diff options
Diffstat (limited to 'usr.sbin/httpd')
271 files changed, 25922 insertions, 11260 deletions
diff --git a/usr.sbin/httpd/conf/highperformance.conf-dist b/usr.sbin/httpd/conf/highperformance.conf-dist index fb7c72563ba..d5a931359ec 100644 --- a/usr.sbin/httpd/conf/highperformance.conf-dist +++ b/usr.sbin/httpd/conf/highperformance.conf-dist @@ -18,7 +18,8 @@ MaxClients 150 StartServers 5 MinSpareServers 5 MaxSpareServers 10 -MaxRequestsPerChild 10000000 +# Assume no memory leaks at all +MaxRequestsPerChild 0 # this is a True Config File # see http://www.apache.org/info/three-config-files.html diff --git a/usr.sbin/httpd/conf/httpd.conf b/usr.sbin/httpd/conf/httpd.conf index 52f743c4e9c..bb2f1449a7a 100644 --- a/usr.sbin/httpd/conf/httpd.conf +++ b/usr.sbin/httpd/conf/httpd.conf @@ -339,9 +339,11 @@ UserDir disabled # # Control access to UserDir directories. The following is an example -# for a site where these directories are restricted to read-only. +# for a site where these directories are restricted to read-only and +# are located under /home/<username>public_html +# You will need to change this to match your site's home directories. # -#<Directory /*/public_html> +#<Directory /home/*/public_html> # AllowOverride FileInfo AuthConfig Limit # Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec # <Limit GET POST OPTIONS PROPFIND> @@ -900,6 +902,7 @@ SSLRandomSeed connect builtin #SSLRandomSeed startup file:/dev/urandom 512 #SSLRandomSeed connect file:/dev/random 512 #SSLRandomSeed connect file:/dev/urandom 512 +SSLRandomSeed startup file:/dev/arandom 512 # Logging: # The home of the dedicated SSL protocol logfile. Errors are diff --git a/usr.sbin/httpd/conf/httpd.conf-dist b/usr.sbin/httpd/conf/httpd.conf-dist index 53590892b9b..d3dfe858013 100644 --- a/usr.sbin/httpd/conf/httpd.conf-dist +++ b/usr.sbin/httpd/conf/httpd.conf-dist @@ -86,7 +86,7 @@ PidFile logs/httpd.pid ScoreBoardFile logs/apache_runtime_status # -# In the standard configuration, the server will process httpd.conf, +# In the standard configuration, the server will process this file, # srm.conf, and access.conf in that order. The latter two files are # now distributed empty, as it is recommended that all directives # be kept in a single file for simplicity. The commented-out values @@ -132,8 +132,7 @@ KeepAliveTimeout 15 # It does this by periodically checking how many servers are waiting # for a request. If there are fewer than MinSpareServers, it creates # a new spare. If there are more than MaxSpareServers, some of the -# spares die off. The default values in httpd.conf-dist are probably OK -# for most sites. +# spares die off. The default values are probably OK for most sites. # MinSpareServers 5 MaxSpareServers 10 @@ -159,9 +158,15 @@ MaxClients 150 # as to avoid problems after prolonged use when Apache (and maybe the # libraries it uses) leak memory or other resources. On most systems, this # isn't really needed, but a few (such as Solaris) do have notable leaks -# in the libraries. +# in the libraries. For these platforms, set to something like 10000 +# or so; a setting of 0 means unlimited. # -MaxRequestsPerChild 30 +# NOTE: This value does not include keepalive requests after the initial +# request per connection. For example, if a child process handles +# an initial request and 10 subsequent "keptalive" requests, it +# would only count as 1 request towards this limit. +# +MaxRequestsPerChild 0 # # Listen: Allows you to bind Apache to specific IP addresses and/or @@ -340,7 +345,7 @@ UserDir public_html # Control access to UserDir directories. The following is an example # for a site where these directories are restricted to read-only. # -#<Directory /*/public_html> +#<Directory /home/*/public_html> # AllowOverride FileInfo AuthConfig Limit # Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec # <Limit GET POST OPTIONS PROPFIND> @@ -373,7 +378,10 @@ AccessFileName .htaccess # .htaccess files. If you change the AccessFileName directive above, # be sure to make the corresponding changes here. # -<Files .htaccess> +# Also, folks tend to use names such as .htpasswd for password +# files, so this will protect those as well. +# +<Files ~ "^\.ht"> Order allow,deny Deny from all </Files> @@ -625,7 +633,7 @@ IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t # to do with the FancyIndexing customization directives above. # AddEncoding x-compress Z -AddEncoding x-gzip gz +AddEncoding x-gzip gz tgz # # AddLanguage allows you to specify the language of a document. You can @@ -653,12 +661,14 @@ LanguagePriority en fr de # AddType allows you to tweak mime.types without actually editing it, or to # make certain files to be certain types. # -# For example, the PHP3 module (not part of the Apache distribution) -# will typically use: +# For example, the PHP3 module (not part of the Apache distribution - see +# http://www.php.net) will typically use: # -#AddType application/x-httpd-php3 .phtml +#AddType application/x-httpd-php3 .php3 #AddType application/x-httpd-php3-source .phps +AddType application/x-tar .tgz + # # AddHandler allows you to map certain file extensions to "handlers", # actions unrelated to filetype. These can be either built into the server @@ -881,6 +891,8 @@ SSLPassPhraseDialog builtin # Configure the SSL Session Cache: First either `none' # or `dbm:/path/to/file' for the mechanism to use and # second the expiring timeout (in seconds). +#SSLSessionCache none +#SSLSessionCache shm:logs/ssl_scache(512000) SSLSessionCache dbm:logs/ssl_scache SSLSessionCacheTimeout 300 @@ -920,7 +932,7 @@ SSLLogLevel info <VirtualHost _default_:443> # General setup for the virtual host -DocumentRoot @@ServerRoot@@/htdocs +DocumentRoot "@@ServerRoot@@/htdocs" ServerName new.host.name ServerAdmin you@your.address ErrorLog logs/error_log @@ -933,7 +945,7 @@ SSLEngine on # SSL Cipher Suite: # List the ciphers that the client is permitted to negotiate. # See the mod_ssl documentation for a complete list. -#SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +#SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL # Server Certificate: # Point SSLCertificateFile at a PEM encoded certificate. If @@ -941,13 +953,22 @@ SSLEngine on # pass phrase. Note that a kill -HUP will prompt again. A test # certificate can be generated with `make certificate' under # built time. -SSLCertificateFile @@ServerRoot@@/conf/ssl.crt/server.crt +SSLCertificateFile @@ServerRoot@@/conf/ssl.crt/server.crt # Server Private Key: # If the key is not combined with the certificate, use this # directive to point at the key file. SSLCertificateKeyFile @@ServerRoot@@/conf/ssl.key/server.key +# Server Certificate Chain: +# Point SSLCertificateChainFile at a file containing the +# concatenation of PEM encoded CA certificates which form the +# certificate chain for the server certificate. Alternatively +# the referenced file can be the same as SSLCertificateFile +# when the CA certificates are directly appended to the server +# certificate for convinience. +#SSLCertificateChainFile @@ServerRoot@@/conf/ssl.crt/ca.crt + # Certificate Authority (CA): # Set the CA certificate verification path where to find CA # certificates for client authentication or alternatively one @@ -955,8 +976,18 @@ SSLCertificateKeyFile @@ServerRoot@@/conf/ssl.key/server.key # Note: Inside SSLCACertificatePath you need hash symlinks # to point to the certificate files. Use the provided # Makefile to update the hash symlinks after changes. -#SSLCACertificatePath @@ServerRoot@@/conf/ssl.crt -#SSLCACertificateFile @@ServerRoot@@/conf/ssl.crt/ca-bundle.crt +#SSLCACertificatePath @@ServerRoot@@/conf/ssl.crt +#SSLCACertificateFile @@ServerRoot@@/conf/ssl.crt/ca-bundle.crt + +# Certificate Revocation Lists (CRL): +# Set the CA revocation path where to find CA CRLs for client +# authentication or alternatively one huge file containing all +# of them (file must be PEM encoded) +# Note: Inside SSLCARevocationPath you need hash symlinks +# to point to the certificate files. Use the provided +# Makefile to update the hash symlinks after changes. +#SSLCARevocationPath @@ServerRoot@@/conf/ssl.crl +#SSLCARevocationFile @@ServerRoot@@/conf/ssl.crl/ca-bundle.crl # Client Authentication (Type): # Client certificate verification type and depth. Types are @@ -999,7 +1030,37 @@ SSLCertificateKeyFile @@ServerRoot@@/conf/ssl.key/server.key # This exports obsolete environment variables for backward compatibility # to Apache-SSL 1.x, mod_ssl 2.0.x, Sioux 1.0 and Stronghold 2.x. Use this # to provide compatibility to existing CGI scripts. -#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +# StrictRequire: +# This denies access when "SSLRequireSSL" or "SSLRequire" applied even +# under a "Satisfy any" situation, i.e. when it applies access is denied +# and no other module can change it. +# OptRenegotiate: +# This enables optimized SSL connection renegotiation handling when SSL +# directives are used in per-directory context. +#SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire + +# SSL Protocol Adjustments: +# The safe and default but still SSL/TLS standard compliant shutdown +# approach is that mod_ssl sends the close notify alert but doesn't wait for +# the close notify alert from client. When you need a different shutdown +# approach you can use one of the following variables: +# ssl-unclean-shutdown: +# This forces an unclean shutdown when the connection is closed, i.e. no +# SSL close notify alert is send or allowed to received. This violates +# the SSL/TLS standard but is needed for some brain-dead browsers. Use +# this when you receive I/O errors because of the standard approach where +# mod_ssl sends the close notify alert. +# ssl-accurate-shutdown: +# This forces an accurate shutdown when the connection is closed, i.e. a +# SSL close notify alert is send and mod_ssl waits for the close notify +# alert of the client. This is 100% SSL/TLS standard compliant, but in +# practice often causes hanging connections with brain-dead browsers. Use +# this only for browsers where you know that their SSL implementation +# works correctly. +# Notice: Most problems of broken clients are also related to the HTTP +# keep-alive facility, so you usually additionally want to disable +# keep-alive for those clients, too. Use variable "nokeepalive" for this. +SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown # Per-Server Logging: # The home of a custom SSL log file. Use this when you want a diff --git a/usr.sbin/httpd/conf/httpd.conf-dist-win b/usr.sbin/httpd/conf/httpd.conf-dist-win index dad2bc424ec..f5b6a4c7f10 100644 --- a/usr.sbin/httpd/conf/httpd.conf-dist-win +++ b/usr.sbin/httpd/conf/httpd.conf-dist-win @@ -89,13 +89,6 @@ ScoreBoardFile logs/apache_status #AccessConfig conf/access.conf # -# ExtendedStatus controls whether Apache will generate "full" status -# information (ExtendedStatus On) or just basic information (ExtendedStatus -# Off) when the "server-status" handler is called. The default is Off. -# -#ExtendedStatus On - -# # Timeout: The number of seconds before receives and sends time out. # Timeout 300 @@ -187,6 +180,13 @@ ThreadsPerChild 50 #LoadModule usertrack_module modules/ApacheModuleUserTrack.dll #LoadModule ssl_module modules/ApacheModuleSSL.dll +# +# ExtendedStatus controls whether Apache will generate "full" status +# information (ExtendedStatus On) or just basic information (ExtendedStatus +# Off) when the "server-status" handler is called. The default is Off. +# +#ExtendedStatus On + ### Section 2: 'Main' server configuration # # The directives in this section set up the values used by the 'main' @@ -560,7 +560,7 @@ IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t # to do with the FancyIndexing customisation directives above. # AddEncoding x-compress Z -AddEncoding x-gzip gz +AddEncoding x-gzip gz tgz # # AddLanguage allows you to specify the language of a document. You can @@ -594,6 +594,8 @@ LanguagePriority en fr de #AddType application/x-httpd-php3 .phtml #AddType application/x-httpd-php3-source .phps +AddType application/x-tar .tgz + # # AddHandler allows you to map certain file extensions to "handlers", # actions unrelated to filetype. These can be either built into the server diff --git a/usr.sbin/httpd/conf/mime.types b/usr.sbin/httpd/conf/mime.types index d8e3b94a66c..d53db0f4e88 100644 --- a/usr.sbin/httpd/conf/mime.types +++ b/usr.sbin/httpd/conf/mime.types @@ -117,7 +117,7 @@ application/vnd.minisoft-hp3000-save application/vnd.mitsubishi.misty-guard.trustweb application/vnd.ms-artgalry application/vnd.ms-asf -application/vnd.ms-excel +application/vnd.ms-excel xls application/vnd.ms-powerpoint ppt application/vnd.ms-project application/vnd.ms-tnef @@ -197,6 +197,7 @@ audio/x-pn-realaudio-plugin rpm audio/x-realaudio ra audio/x-wav wav chemical/x-pdb pdb xyz +image/bmp bmp image/cgm image/g3fax image/gif gif diff --git a/usr.sbin/httpd/htdocs/index.html b/usr.sbin/httpd/htdocs/index.html index d2d5b5f6990..a51d79ad6f0 100644 --- a/usr.sbin/httpd/htdocs/index.html +++ b/usr.sbin/httpd/htdocs/index.html @@ -1,7 +1,17 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> - <TITLE>Default Page for Apache Installation on OpenBSD</TITLE> + <TITLE>Test Page for the SSL-aware Apache Installation on Web Site</TITLE> + <STYLE TYPE="text/css"> + H1 { + font-weight: bold; + font-size: 18pt; + line-height: 18pt; + font-family: arial,helvetica; + font-variant: normal; + font-style: normal; + } + </STYLE> </HEAD> <!-- Background white, links blue (unvisited), navy (visited), red (active) --> <BODY @@ -11,6 +21,8 @@ VLINK="#000080" ALINK="#FF0000" > + <BLOCKQUOTE> + <H1 ALIGN="CENTER"> Welcome to <A HREF="http://www.apache.org/">Apache</A> on <A HREF="http://www.openbsd.org/">OpenBSD</A> @@ -22,15 +34,20 @@ OpenBSD System</A>. They now have to add content to this directory and replace this placeholder page, or else point the server at their real content. - </P> <HR> <P> The Apache <A HREF="manual/index.html" >documentation</A> - has been included with this distribution. + has been included with this distribution.<BR> + Especially read the + <A + HREF="manual/mod/mod_ssl/" + >SSL documentation</A> + carefully. </P> + You may use the images below on any <A HREF="http://www.OpenBSD.org/">OpenBSD</A>-powered Web server. @@ -44,8 +61,6 @@ <IMG SRC="logo24.jpg" ALT="This Site OpenBSD 2.4 Powered!"><BR> <IMG SRC="smalltitle.gif" ALT="OpenBSD"><BR> </DIV> + </BLOCKQUOTE> </BODY> </HTML> - - - diff --git a/usr.sbin/httpd/htdocs/manual/content-negotiation.html b/usr.sbin/httpd/htdocs/manual/content-negotiation.html index 044e196f587..b5b6913f378 100644 --- a/usr.sbin/httpd/htdocs/manual/content-negotiation.html +++ b/usr.sbin/httpd/htdocs/manual/content-negotiation.html @@ -74,14 +74,23 @@ allowing any other media type as a last resort: Apache 1.2 supports 'server driven' content negotiation, as defined in the HTTP/1.1 specification. It fully supports the Accept, Accept-Language, Accept-Charset and Accept-Encoding request headers. +Apache 1.3.4 also supports 'transparent' content negotiation, which is +an experimental negotiation protocol defined in RFC 2295 and RFC 2296. +It does not offer support for 'feature negotiation' as defined in +these RFCs. <P> -The terms used in content negotiation are: a <STRONG>resource</STRONG> is an -item which can be requested of a server, which might be selected as -the result of a content negotiation algorithm. If a resource is -available in several formats, these are called <STRONG>representations</STRONG> -or <STRONG>variants</STRONG>. The ways in which the variants for a particular -resource vary are called the <STRONG>dimensions</STRONG> of negotiation. +A <STRONG>resource</STRONG> is a conceptual entity identified by a URI +(RFC 2396). An HTTP server like Apache provides access to +<STRONG>representations</STRONG> of the resource(s) within its namespace, +with each representation in the form of a sequence of bytes with a +defined media type, character set, encoding, etc. Each resource may be +associated with zero, one, or more than one representation +at any given time. If multiple representations are available, +the resource is referred to as <STRONG>negotiable</STRONG> and each of its +representations is termed a <STRONG>variant</STRONG>. The ways in which the +variants for a negotiable resource vary are called the +<STRONG>dimensions</STRONG> of negotiation. <H2>Negotiation in Apache</H2> @@ -92,9 +101,9 @@ ways: <UL> <LI> Using a type map (<EM>i.e.</EM>, a <CODE>*.var</CODE> file) which - names the files containing the variants explicitly - <LI> Or using a 'MultiViews' search, where the server does an implicit - filename pattern match, and chooses from among the results. + names the files containing the variants explicitly, or + <LI> Using a 'MultiViews' search, where the server does an implicit + filename pattern match and chooses from among the results. </UL> <H3>Using a type-map file</H3> @@ -104,25 +113,25 @@ A type map is a document which is associated with the handler named <CODE>type-map</CODE> (or, for backwards-compatibility with older Apache configurations, the mime type <CODE>application/x-type-map</CODE>). Note that to use this feature, -you've got to have a <CODE>SetHandler</CODE> some place which defines a +you must have a handler set in the configuration that defines a file suffix as <CODE>type-map</CODE>; this is best done with a -<PRE> +<PRE> AddHandler type-map var - </PRE> -in <CODE>srm.conf</CODE>. See comments in the sample config files for -details. <P> + +in the server configuration file. See the comments in the sample config +file for more details. <P> Type map files have an entry for each available variant; these entries -consist of contiguous RFC822-format header lines. Entries for +consist of contiguous HTTP-format header lines. Entries for different variants are separated by blank lines. Blank lines are illegal within an entry. It is conventional to begin a map file with an entry for the combined entity as a whole (although this is not required, and if present will be ignored). An example map file is: -<PRE> +<PRE> URI: foo URI: foo.en.html @@ -130,13 +139,14 @@ map file is: Content-language: en URI: foo.fr.de.html - Content-type: text/html; charset=iso-8859-2 + Content-type: text/html;charset=iso-8859-2 Content-language: fr, de </PRE> If the variants have different source qualities, that may be indicated by the "qs" parameter to the media type, as in this picture (available as jpeg, gif, or ASCII-art): + <PRE> URI: foo @@ -148,14 +158,22 @@ as jpeg, gif, or ASCII-art): URI: foo.txt Content-type: text/plain; qs=0.01 - </PRE> <P> -qs values can vary between 0.000 and 1.000. Note that any variant with +qs values can vary in the range 0.000 to 1.000. Note that any variant with a qs value of 0.000 will never be chosen. Variants with no 'qs' -parameter value are given a qs factor of 1.0. <P> +parameter value are given a qs factor of 1.0. The qs parameter indicates +the relative 'quality' of this variant compared to the other available +variants, independent of the client's capabilities. For example, a jpeg +file is usually of higher source quality than an ascii file if it is +attempting to represent a photograph. However, if the resource being +represented is an original ascii art, then an ascii representation would +have a higher source quality than a jpeg representation. A qs value +is therefore specific to a given variant depending on the nature of +the resource it represents. +<P> The full list of headers recognized is: <DL> @@ -166,42 +184,46 @@ The full list of headers recognized is: the same server (!), and they must refer to files to which the client would be granted access if they were to be requested directly. - <DT> <CODE>Content-type:</CODE> + <DT> <CODE>Content-Type:</CODE> <DD> media type --- charset, level and "qs" parameters may be given. These are often referred to as MIME types; typical media types are <CODE>image/gif</CODE>, <CODE>text/plain</CODE>, or <CODE>text/html; level=3</CODE>. - <DT> <CODE>Content-language:</CODE> + <DT> <CODE>Content-Language:</CODE> <DD> The languages of the variant, specified as an Internet standard - language code (<EM>e.g.</EM>, <CODE>en</CODE> for English, + language tag from RFC 1766 (<EM>e.g.</EM>, <CODE>en</CODE> for English, <CODE>kr</CODE> for Korean, <EM>etc.</EM>). - <DT> <CODE>Content-encoding:</CODE> + <DT> <CODE>Content-Encoding:</CODE> <DD> If the file is compressed, or otherwise encoded, rather than containing the actual raw data, this says how that was done. - For compressed files (the only case where this generally comes - up), content encoding should be - <CODE>x-compress</CODE>, or <CODE>x-gzip</CODE>, as appropriate. - <DT> <CODE>Content-length:</CODE> - <DD> The size of the file. Clients can ask to receive a given media - type only if the variant isn't too big; specifying a content - length in the map allows the server to compare against these - thresholds without checking the actual file. + Apache only recognizes encodings that are defined by an + <A HREF="mod/mod_mime.html#addencoding">AddEncoding</A> directive. + This normally includes the encodings <CODE>x-compress</CODE> + for compress'd files, and <CODE>x-gzip</CODE> for gzip'd files. + The <CODE>x-</CODE> prefix is ignored for encoding comparisons. + <DT> <CODE>Content-Length:</CODE> + <DD> The size of the file. Specifying content + lengths in the type-map allows the server to compare file sizes + without checking the actual files. + <DT> <CODE>Description:</CODE> + <DD> A human-readable textual description of the variant. If Apache cannot + find any appropriate variant to return, it will return an error + response which lists all available variants instead. Such a variant + list will include the human-readable variant descriptions. </DL> <H3>Multiviews</H3> <P> -This is a per-directory option, meaning it can be set with an -<CODE>Options</CODE> directive within a <CODE><Directory></CODE>, +<CODE>MultiViews</CODE> is a per-directory option, meaning it can be set with +an <CODE>Options</CODE> directive within a <CODE><Directory></CODE>, <CODE><Location></CODE> or <CODE><Files></CODE> section in <CODE>access.conf</CODE>, or (if <CODE>AllowOverride</CODE> is properly set) in <CODE>.htaccess</CODE> files. Note that <CODE>Options All</CODE> does not set <CODE>MultiViews</CODE>; you -have to ask for it by name. (Fixing this is a one-line change to -<CODE>http_core.h</CODE>). +have to ask for it by name. <P> - The effect of <CODE>MultiViews</CODE> is as follows: if the server receives a request for <CODE>/some/dir/foo</CODE>, if <CODE>/some/dir</CODE> has <CODE>MultiViews</CODE> enabled, and @@ -210,23 +232,22 @@ directory looking for files named foo.*, and effectively fakes up a type map which names all those files, assigning them the same media types and content-encodings it would have if the client had asked for one of them by name. It then chooses the best match to the client's -requirements, and forwards them along. +requirements. <P> - -This applies to searches for the file named by the +<CODE>MultiViews</CODE> may also apply to searches for the file named by the <CODE>DirectoryIndex</CODE> directive, if the server is trying to -index a directory; if the configuration files specify -<PRE> +index a directory. If the configuration files specify +<PRE> DirectoryIndex index +</PRE> -</PRE> then the server will arbitrate between <CODE>index.html</CODE> +then the server will arbitrate between <CODE>index.html</CODE> and <CODE>index.html3</CODE> if both are present. If neither are present, and <CODE>index.cgi</CODE> is there, the server will run it. <P> - If one of the files found when reading the directive is a CGI script, it's not obvious what should happen. The code gives that case special treatment --- if the request was a POST, or a GET with @@ -235,78 +256,109 @@ rating, and generally invoked; otherwise it is given an extremely low quality rating, which generally causes one of the other views (if any) to be retrieved. -<H2>The Negotiation Algorithm</H2> +<H2>The Negotiation Methods</H2> After Apache has obtained a list of the variants for a given resource, either from a type-map file or from the filenames in the directory, it -applies a algorithm to decide on the 'best' variant to return, if -any. To do this it calculates a quality value for each variant in each -of the dimensions of variance. It is not necessary to know any of the -details of how negotiation actually takes place in order to use Apache's -content negotiation features. However the rest of this document -explains in detail the algorithm used for those interested. <P> +invokes one of two methods to decide on the 'best' variant to +return, if any. It is not necessary to know any of the details of how +negotiation actually takes place in order to use Apache's content +negotiation features. However the rest of this document explains the +methods used for those interested. +<P> + +There are two negotiation methods: + +<OL> + +<LI><STRONG>Server driven negotiation with the Apache +algorithm</STRONG> is used in the normal case. The Apache algorithm is +explained in more detail below. When this algorithm is used, Apache +can sometimes 'fiddle' the quality factor of a particular dimension to +achieve a better result. The ways Apache can fiddle quality factors is +explained in more detail below. + +<LI><STRONG>Transparent content negotiation</STRONG> is used when the +browser specifically requests this through the mechanism defined in RFC +2295. This negotiation method gives the browser full control over +deciding on the 'best' variant, the result is therefore dependent on +the specific algorithms used by the browser. As part of the +transparent negotiation process, the browser can ask Apache to run the +'remote variant selection algorithm' defined in RFC 2296. </UL> -In some circumstances, Apache can 'fiddle' the quality factor of a -particular dimension to achieve a better result. The ways Apache can -fiddle quality factors is explained in more detail below. <H3>Dimensions of Negotiation</H3> <TABLE> -<TR><TH>Dimension +<TR valign="top"> +<TH>Dimension <TH>Notes -<TR><TD>Media Type -<TD>Browser indicates preferences on Accept: header. Each item +<TR valign="top"> +<TD>Media Type +<TD>Browser indicates preferences with the Accept header field. Each item can have an associated quality factor. Variant description can also -have a quality factor. -<TR><TD>Language -<TD>Browser indicates preferences on Accept-Language: header. Each -item -can have a quality factor. Variants can be associated with none, one -or more languages. -<TR><TD>Encoding -<TD>Browser indicates preference with Accept-Encoding: header. -<TR><TD>Charset -<TD>Browser indicates preference with Accept-Charset: header. Variants -can indicate a charset as a parameter of the media type. +have a quality factor (the "qs" parameter). +<TR valign="top"> +<TD>Language +<TD>Browser indicates preferences with the Accept-Language header field. +Each item can have a quality factor. Variants can be associated with none, one +or more than one language. +<TR valign="top"> +<TD>Encoding +<TD>Browser indicates preference with the Accept-Encoding header field. +Each item can have a quality factor. +<TR valign="top"> +<TD>Charset +<TD>Browser indicates preference with the Accept-Charset header field. +Each item can have a quality factor. +Variants can indicate a charset as a parameter of the media type. </TABLE> <H3>Apache Negotiation Algorithm</H3> <P> -Apache uses an algorithm to select the 'best' variant (if any) to -return to the browser. This algorithm is not configurable. It operates -like this: +Apache can use the following algorithm to select the 'best' variant +(if any) to return to the browser. This algorithm is not +further configurable. It operates as follows: <OL> -<LI> -Firstly, for each dimension of the negotiation, the appropriate -Accept header is checked and a quality assigned to this each -variant. If the Accept header for any dimension means that this +<LI>First, for each dimension of the negotiation, check the appropriate +<EM>Accept*</EM> header field and assign a quality to each +variant. If the <EM>Accept*</EM> header for any dimension implies that this variant is not acceptable, eliminate it. If no variants remain, go to step 4. -<LI>Select the 'best' variant by a process of elimination. Each of -the following tests is applied in order. Any variants not selected at -each stage are eliminated. After each test, if only one variant -remains, it is selected as the best match. If more than one variant -remains, move onto the next test. +<LI>Select the 'best' variant by a process of elimination. Each of the +following tests is applied in order. Any variants not selected at each +test are eliminated. After each test, if only one variant remains, +select it as the best match and proceed to step 3. If more than one +variant remains, move on to the next test. <OL> <LI>Multiply the quality factor from the Accept header with the quality-of-source factor for this variant's media type, and select - the variants with the highest value + the variants with the highest value. -<LI>Select the variants with the highest language quality factor +<LI>Select the variants with the highest language quality factor. <LI>Select the variants with the best language match, using either the - order of languages on the <CODE>LanguagePriority</CODE> directive (if - present), - else the order of languages on the Accept-Language header. + order of languages in the Accept-Language header (if present), or else + else the order of languages in the <CODE>LanguagePriority</CODE> + directive (if present). <LI>Select the variants with the highest 'level' media parameter (used to give the version of text/html media types). +<LI>Select variants with the best charset media parameters, + as given on the Accept-Charset header line. Charset ISO-8859-1 + is acceptable unless explicitly excluded. Variants with a + <CODE>text/*</CODE> media type but not explicitly associated + with a particular charset are assumed to be in ISO-8859-1. + +<LI>Select those variants which have associated + charset media parameters that are <EM>not</EM> ISO-8859-1. + If there are no such variants, select all variants instead. + <LI>Select the variants with the best encoding. If there are variants with an encoding that is acceptable to the user-agent, select only these variants. Otherwise if there is a mix of encoded @@ -314,16 +366,12 @@ remains, move onto the next test. If either all variants are encoded or all variants are not encoded, select all variants. -<LI>Select only variants with acceptable charset media parameters, - as given on the Accept-Charset header line. Charset ISO-8859-1 - is always acceptable. Variants not associated with a particular - charset are assumed to be in ISO-8859-1. - -<LI>Select the variants with the smallest content length +<LI>Select the variants with the smallest content length. -<LI>Select the first variant of those remaining (this will be either the -first listed in the type-map file, or the first read from the directory) -and go to stage 3. +<LI>Select the first variant of those remaining. This will be either the + first listed in the type-map file, or when variants are read from + the directory, the one whose file name comes first when sorted using + ASCII code order. </OL> @@ -332,7 +380,7 @@ and go to stage 3. dimensions of negotiation (browsers and caches can use this information when caching the resource). End. -<LI>To get here means no variant was selected (because non are acceptable +<LI>To get here means no variant was selected (because none are acceptable to the browser). Return a 406 status (meaning "No acceptable representation") with a response body consisting of an HTML document listing the available variants. Also set the HTTP Vary header to indicate the @@ -342,15 +390,15 @@ and go to stage 3. <H2><A NAME="better">Fiddling with Quality Values</A></H2> -<P> +<P> Apache sometimes changes the quality values from what would be -expected by a strict interpretation of the algorithm above. This is to -get a better result from the algorithm for browsers which do not send -full or accurate information. Some of the most popular browsers send -Accept header information which would otherwise result in the -selection of the wrong variant in many cases. If a browser -sends full and correct information these fiddles will not -be applied. +expected by a strict interpretation of the Apache negotiation +algorithm above. This is to get a better result from the algorithm for +browsers which do not send full or accurate information. Some of the +most popular browsers send Accept header information which would +otherwise result in the selection of the wrong variant in many +cases. If a browser sends full and correct information these fiddles +will not be applied. <P> <H3>Media Types and Wildcards</H3> @@ -423,6 +471,18 @@ header includes either en or fr (or both) one of foo.en.html or foo.fr.html will be returned. If the browser does not list either en or fr as acceptable, foo.html will be returned instead. +<H2>Extensions to Transparent Content Negotiation</H2> + +Apache extends the transparent content negotiation protocol (RFC 2295) +as follows. A new <CODE> {encoding ..}</CODE> element is used in +variant lists to label variants which are available with a specific +content-encoding only. The implementation of the +RVSA/1.0 algorithm (RFC 2296) is extended to recognize encoded +variants in the list, and to use them as candidate variants whenever +their encodings are acceptable according to the Accept-Encoding +request header. The RVSA/1.0 implementation does not round computed +quality factors to 5 decimal places before choosing the best variant. + <H2>Note on hyperlinks and naming conventions</H2> <P> @@ -514,12 +574,11 @@ if there is one) must be on the right hand side of the MIME-type extension <H2>Note on Caching</H2> <P> -When a cache stores a document, it associates it with the request URL. +When a cache stores a representation, it associates it with the request URL. The next time that URL is requested, the cache can use the stored -document, provided it is still within date. But if the resource is -subject to content negotiation at the server, this would result in -only the first requested variant being cached, and subsequent cache -hits could return the wrong response. To prevent this, +representation. But, if the resource is negotiable at the server, +this might result in only the first requested variant being cached and +subsequent cache hits might return the wrong response. To prevent this, Apache normally marks all responses that are returned after content negotiation as non-cacheable by HTTP/1.0 clients. Apache also supports the HTTP/1.1 protocol features to allow caching of negotiated responses. <P> @@ -528,8 +587,7 @@ For requests which come from a HTTP/1.0 compliant client (either a browser or a cache), the directive <TT>CacheNegotiatedDocs</TT> can be used to allow caching of responses which were subject to negotiation. This directive can be given in the server config or virtual host, and -takes no arguments. It has no effect on requests from HTTP/1.1 -clients. +takes no arguments. It has no effect on requests from HTTP/1.1 clients. <HR> <H3 ALIGN="CENTER"> diff --git a/usr.sbin/httpd/htdocs/manual/dso.html b/usr.sbin/httpd/htdocs/manual/dso.html index 4c48262512b..f8377af9d5b 100644 --- a/usr.sbin/httpd/htdocs/manual/dso.html +++ b/usr.sbin/httpd/htdocs/manual/dso.html @@ -172,7 +172,7 @@ code which automatically makes sure the Unix loader is able to load and start <P>Apache's <CODE>src/Configure</CODE> script currently has only limited but adequate built-in knowledge on how to compile DSO files, because as already mentioned this is heavily platform-dependent. Nevertheless all major Unix -platforms are supported. The definitive current state (May 1998) is this: +platforms are supported. The definitive current state (May 1999) is this: <P> <UL> @@ -180,21 +180,25 @@ platforms are supported. The definitive current state (May 1998) is this: (actually tested versions in parenthesis) <PRE> -o FreeBSD (2.1.5, 2.2.5, 2.2.6) +o FreeBSD (2.1.5, 2.2.x, 3.x, 4.x) o OpenBSD (2.x) o NetBSD (1.3.1) -o BSDI (4.0) +o BSDI (3.x, 4.x) o Linux (Debian/1.3.1, RedHat/4.2) -o Solaris (2.4, 2.5.1, 2.6) +o Solaris (2.4, 2.5, 2.6, 2.7) o SunOS (4.1.3) o Digital UNIX (4.0) -o IRIX (6.2) +o IRIX (5.3, 6.2) o HP/UX (10.20) o UnixWare (2.01, 2.1.2) o SCO (5.0.4) o AIX (3.2, 4.1.5, 4.2, 4.3) o ReliantUNIX/SINIX (5.43) o SVR4 (-) +o Mac OS X Server (1.0) +o Mac OS (10.0 preview 1) +o OpenStep/Mach (4.2) +o DGUX (??) </PRE> <P> diff --git a/usr.sbin/httpd/htdocs/manual/env.html b/usr.sbin/httpd/htdocs/manual/env.html index 5052befcafc..2f0971d877c 100644 --- a/usr.sbin/httpd/htdocs/manual/env.html +++ b/usr.sbin/httpd/htdocs/manual/env.html @@ -15,37 +15,60 @@ <DIV ALIGN="CENTER"> <IMG SRC="images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<h1 ALIGN="CENTER">Special Purpose Environment Variables</h1> -<P>Interoperability problems have led to the introduction of +<H1 ALIGN="CENTER">Special Purpose Environment Variables</H1> +<P> +Interoperability problems have led to the introduction of mechanisms to modify the way Apache behaves when talking to particular clients. To make these mechanisms as flexible as possible, they -are invoked by defining environment variables, typically with -<A HREF="mod/mod_browser.html#browsermatch">BrowserMatch</A>, though -<A HREF="mod/mod_env.html#setenv">SetEnv</A> and +are invoked by defining environment variables, typically with +<A HREF="mod/mod_browser.html#browsermatch">BrowserMatch</A>, though +<A HREF="mod/mod_env.html#setenv">SetEnv</A> and <A HREF="mod/mod_env.html#passenv">PassEnv</A> could also be used, for -example.</P> +example. +</P> + +<H2>downgrade-1.0</H2> +<P> +This forces the request to be treated as a HTTP/1.0 request even if it +was in a later dialect. +</P> + +<H2>force-no-vary</H2> +<P> +This causes any <CODE>Vary</CODE> fields to be removed from the response +header before it is sent back to the client. Some clients don't +interpret this field correctly (see the +<A HREF="misc/known_client_problems.html">known client problems</A> +page); setting this variable can work around this problem. Setting +this variable also implies <STRONG>force-response-1.0</STRONG>. +</P> -<H2>nokeepalive</H2> -This disables <A HREF="mod/core.html#keepalive">KeepAlive</A> when set. Because -of problems with Netscape 2.x and KeepAlive, we recommend the following -directive be used: -<BLOCKQUOTE><CODE> -BrowserMatch Mozilla/2 nokeepalive -</CODE></BLOCKQUOTE> <H2>force-response-1.0</H2> +<P> This forces an HTTP/1.0 response when set. It was originally implemented as a -result of a problem with AOL's proxies. Some clients may not behave correctly +result of a problem with AOL's proxies. Some clients may not behave correctly when given an HTTP/1.1 response, and this can be used to interoperate with them. +</P> + +<H2>nokeepalive</H2> +<P> +This disables <A HREF="mod/core.html#keepalive">KeepAlive</A> when set. Because +of problems with Netscape 2.x and KeepAlive, we recommend the following +directive be used: +</P> +<PRE> + BrowserMatch Mozilla/2 nokeepalive +</PRE> <HR> -<H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 -</H3> + <H3 ALIGN="CENTER"> + Apache HTTP Server Version 1.3 + </H3> <A HREF="./"><IMG SRC="images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/handler.html b/usr.sbin/httpd/htdocs/manual/handler.html index 597ea8cd9e4..fb09a7df489 100644 --- a/usr.sbin/httpd/htdocs/manual/handler.html +++ b/usr.sbin/httpd/htdocs/manual/handler.html @@ -35,7 +35,7 @@ explicitly. Either based on filename extensions or on location, these handlers are unrelated to file type. This is advantageous both because it is a more elegant solution, but it also allows for both a type <STRONG>and</STRONG> a handler to be associated with a file (See also -<A HREF="mod/mod_mime#multipleext">Files with Multiple Extensions</A>) +<A HREF="mod/mod_mime.html#multipleext">Files with Multiple Extensions</A>) </P> diff --git a/usr.sbin/httpd/htdocs/manual/images/ssleay.gif b/usr.sbin/httpd/htdocs/manual/images/ssleay.gif Binary files differdeleted file mode 100644 index c59cdf5b3a8..00000000000 --- a/usr.sbin/httpd/htdocs/manual/images/ssleay.gif +++ /dev/null diff --git a/usr.sbin/httpd/htdocs/manual/index.html b/usr.sbin/httpd/htdocs/manual/index.html index ff46a78f9a0..79eacd5e6be 100644 --- a/usr.sbin/httpd/htdocs/manual/index.html +++ b/usr.sbin/httpd/htdocs/manual/index.html @@ -33,7 +33,7 @@ <H3><A NAME="ref">Apache Reference Manual</A></H3> <UL> -<LI><A HREF="http://www.apache.org/manual-index.cgi/docs"> +<LI><A HREF="http://www.apache.org/search.html"> <STRONG>Search</STRONG></A> for key words <LI><A HREF="install.html">Compiling and Installing</A> <LI><A HREF="invoking.html">Starting</A> diff --git a/usr.sbin/httpd/htdocs/manual/install-tpf.html b/usr.sbin/httpd/htdocs/manual/install-tpf.html index a55636e5bec..6a357452aeb 100644 --- a/usr.sbin/httpd/htdocs/manual/install-tpf.html +++ b/usr.sbin/httpd/htdocs/manual/install-tpf.html @@ -53,8 +53,6 @@ are in /src. If you are using a product such as WinZip on your PC, verify that the <EM>"TAR File Smart CR/LF Conversion"</EM> option is NOT checked. You can find this in WinZip under Options, Configuration. -Since you had to tar and unzip the file to read this document, -you need to re-tar and -unzip if the CR/LF option was checked. This will save you lots of headaches later on. </P> <P> @@ -126,6 +124,9 @@ are case sensitive, and must be made from the "src" directory. DO NOT modify the <TT>TPF=YES</TT> export variable. If this is changed, the "Configure" script will not recognize TPF. <BR><BR> +<LI>Remove the src/lib/expat-lite directory: + <TT><STRONG>rm -r lib/expat-lite</STRONG></TT> + <BR><BR> <LI>Run the "Configure" script: <TT><STRONG>Configure</STRONG></TT> <BR> @@ -212,8 +213,7 @@ HREF="http://www.apache.org/dist/contrib/modules/">http://www.apache.org/dist/co Apache requires a configuration file to initialize itself during activation. (Previously three configuration files were used.) Copy the distribution version, /conf/httpd.conf-dist, to /conf/httpd.conf and then - edit the /conf/httpd.conf copy with your site specific information. This first release - of Apache for TPF only runs under the "inetd" model so you + edit the /conf/httpd.conf copy with your site specific information. If your system is pre-PUT09 you <font color=red><STRONG>must</STRONG></FONT> change <TT>ServerType</TT> from <TT>standalone</TT> to <TT>inetd</TT>. <BR><BR> @@ -226,7 +226,8 @@ HREF="http://www.apache.org/dist/contrib/modules/">http://www.apache.org/dist/co <BR><BR> <PRE> ZINET ADD S-TFTP PGM-CTFT PORT-69 PROTOCOL-UDP MODEL-NOWAIT - ZINET ADD S-APACHE PGM-<EM>pppp</EM> PORT-80 PROTOCOL-TCP MODEL-NOWAIT</PRE> + ZINET ADD S-APACHE PGM-<EM>pppp</EM> PROTOCOL-TCP MODEL-NOWAIT PORT-80 (if inetd mode) + ZINET ADD S-APACHE PGM-<EM>pppp</EM> PROTOCOL-TCP MODEL-NOLISTEN (if standalone mode)</PRE> Please refer to <EM>IBM Transaction Processing Facility Transmission Control Protocol/Internet Protocol Version 4 Release 1</EM> for more information on ZCLAW, INETD, and TFTP. diff --git a/usr.sbin/httpd/htdocs/manual/install.html b/usr.sbin/httpd/htdocs/manual/install.html index 73ab0d9a73f..2abeea575df 100644 --- a/usr.sbin/httpd/htdocs/manual/install.html +++ b/usr.sbin/httpd/htdocs/manual/install.html @@ -104,7 +104,7 @@ directory of the Apache distribution. Change into this directory. </BLOCKQUOTE> (*: Depending on Configuration and your system, Configure - make not print these lines. That's OK).<P> + might not print these lines. That's OK).<P> This generates a Makefile for use in stage 3. It also creates a Makefile in the support directory, for compilation of the optional diff --git a/usr.sbin/httpd/htdocs/manual/invoking.html b/usr.sbin/httpd/htdocs/manual/invoking.html index 22f3dc07bad..aca5908c3bb 100644 --- a/usr.sbin/httpd/htdocs/manual/invoking.html +++ b/usr.sbin/httpd/htdocs/manual/invoking.html @@ -123,7 +123,17 @@ server. (Up to Apache 1.3.3, this option also started the server). <DD>Test the configuration file syntax (<EM>i.e.</EM>, read all configuration files and interpret them) but do not start the server. If the configuration contains errors, display an error message and exit with a non-zero exit status, -otherwise display "Syntax OK" and terminate with a zero exit status. +otherwise display "Syntax OK" and terminate with a zero exit status. This +command checks to see if all DocumentRoot entries exist and are directories. +For sites with many vhosts, this is expensive; consider the <CODE>-T</CODE> +command instead. + +<DT><CODE>-T</CODE> +<DD>Test the configuration file syntax (<EM>i.e.</EM>, read all configuration files +and interpret them) but do not start the server. If the configuration contains +errors, display an error message and exit with a non-zero exit status, +otherwise display "Syntax OK" and terminate with a zero exit status. This +command does not perform any checking of the DocumentRoot entries. <DT><CODE>-k</CODE> <EM>option</EM> <DD>Windows only: signal Apache to restart or shutdown. <EM>option</EM> @@ -194,7 +204,7 @@ kill the children httpd processes. The server will log error messages to a log file, by default <CODE>logs/error_log</CODE> on Unix or <CODE>logs/error.log</CODE> on -OS/2. The filename can be set using the <A +Windows and OS/2. The filename can be set using the <A HREF="mod/core.html#errorlog">ErrorLog</A> directive; different error logs can be set for different <A HREF="mod/core.html#virtualhost">virtual hosts</A>. @@ -203,9 +213,10 @@ HREF="mod/core.html#virtualhost">virtual hosts</A>. The server will typically log each request to a transfer file, by default <CODE>logs/access_log</CODE> on Unix or -<CODE>logs/access.log</CODE> on OS/2. The filename can be set using a -<A HREF="mod/mod_log_config.html#transferlog">TransferLog</A> -directive or additional log files created with the <A +<CODE>logs/access.log</CODE> on Windows and OS/2. The filename can be +set using a <A +HREF="mod/mod_log_config.html#transferlog">TransferLog</A> directive +or additional log files created with the <A HREF="mod/mod_log_config.html#customlog">CustomLog</A> directive; different transfer logs can be set for different <A HREF="mod/core.html#virtualhost">virtual hosts</A>. diff --git a/usr.sbin/httpd/htdocs/manual/misc/API.html b/usr.sbin/httpd/htdocs/manual/misc/API.html index 1ad15723ed3..8b46bcd390c 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/API.html +++ b/usr.sbin/httpd/htdocs/manual/misc/API.html @@ -1,7 +1,7 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html><head> -<title>Apache API notes</title> -</head> +<HTML><HEAD> +<TITLE>Apache API notes</TITLE> +</HEAD> <!-- Background white, links blue (unvisited), navy (visited), red (active) --> <BODY BGCOLOR="#FFFFFF" @@ -13,20 +13,20 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<h1 ALIGN="CENTER">Apache API notes</h1> +<H1 ALIGN="CENTER">Apache API notes</H1> These are some notes on the Apache API and the data structures you -have to deal with, etc. They are not yet nearly complete, but +have to deal with, <EM>etc.</EM> They are not yet nearly complete, but hopefully, they will help you get your bearings. Keep in mind that the API is still subject to change as we gain experience with it. -(See the TODO file for what <em>might</em> be coming). However, +(See the TODO file for what <EM>might</EM> be coming). However, it will be easy to adapt modules to any changes that are made. (We have more modules to adapt than you do). -<p> +<P> A few notes on general pedagogical style here. In the interest of conciseness, all structure declarations here are incomplete --- the @@ -34,77 +34,80 @@ real ones have more slots that I'm not telling you about. For the most part, these are reserved to one component of the server core or another, and should be altered by modules with caution. However, in some cases, they really are things I just haven't gotten around to -yet. Welcome to the bleeding edge.<p> +yet. Welcome to the bleeding edge.<P> Finally, here's an outline, to give you some bare idea of what's coming up, and in what order: -<ul> -<li> <a href="#basics">Basic concepts.</a> -<menu> - <li> <a href="#HMR">Handlers, Modules, and Requests</a> - <li> <a href="#moduletour">A brief tour of a module</a> -</menu> -<li> <a href="#handlers">How handlers work</a> -<menu> - <li> <a href="#req_tour">A brief tour of the <code>request_rec</code></a> - <li> <a href="#req_orig">Where request_rec structures come from</a> - <li> <a href="#req_return">Handling requests, declining, and returning error codes</a> - <li> <a href="#resp_handlers">Special considerations for response handlers</a> - <li> <a href="#auth_handlers">Special considerations for authentication handlers</a> - <li> <a href="#log_handlers">Special considerations for logging handlers</a> -</menu> -<li> <a href="#pools">Resource allocation and resource pools</a> -<li> <a href="#config">Configuration, commands and the like</a> -<menu> - <li> <a href="#per-dir">Per-directory configuration structures</a> - <li> <a href="#commands">Command handling</a> - <li> <a href="#servconf">Side notes --- per-server configuration, virtual servers, etc.</a> -</menu> -</ul> - -<h2><a name="basics">Basic concepts.</a></h2> - -We begin with an overview of the basic concepts behind the +<UL> +<LI> <A HREF="#basics">Basic concepts.</A> +<MENU> + <LI> <A HREF="#HMR">Handlers, Modules, and Requests</A> + <LI> <A HREF="#moduletour">A brief tour of a module</A> +</MENU> +<LI> <A HREF="#handlers">How handlers work</A> +<MENU> + <LI> <A HREF="#req_tour">A brief tour of the <CODE>request_rec</CODE></A> + <LI> <A HREF="#req_orig">Where request_rec structures come from</A> + <LI> <A HREF="#req_return">Handling requests, declining, and returning error + codes</A> + <LI> <A HREF="#resp_handlers">Special considerations for response handlers</A> + <LI> <A HREF="#auth_handlers">Special considerations for authentication + handlers</A> + <LI> <A HREF="#log_handlers">Special considerations for logging handlers</A> +</MENU> +<LI> <A HREF="#pools">Resource allocation and resource pools</A> +<LI> <A HREF="#config">Configuration, commands and the like</A> +<MENU> + <LI> <A HREF="#per-dir">Per-directory configuration structures</A> + <LI> <A HREF="#commands">Command handling</A> + <LI> <A HREF="#servconf">Side notes --- per-server configuration, + virtual servers, <EM>etc</EM>.</A> +</MENU> +</UL> + +<H2><A NAME="basics">Basic concepts.</A></H2> + +We begin with an overview of the basic concepts behind the API, and how they are manifested in the code. -<h3><a name="HMR">Handlers, Modules, and Requests</a></h3> +<H3><A NAME="HMR">Handlers, Modules, and Requests</A></H3> Apache breaks down request handling into a series of steps, more or less the same way the Netscape server API does (although this API has a few more stages than NetSite does, as hooks for stuff I thought might be useful in the future). These are: -<ul> - <li> URI -> Filename translation - <li> Auth ID checking [is the user who they say they are?] - <li> Auth access checking [is the user authorized <em>here</em>?] - <li> Access checking other than auth - <li> Determining MIME type of the object requested - <li> `Fixups' --- there aren't any of these yet, but the phase is +<UL> + <LI> URI -> Filename translation + <LI> Auth ID checking [is the user who they say they are?] + <LI> Auth access checking [is the user authorized <EM>here</EM>?] + <LI> Access checking other than auth + <LI> Determining MIME type of the object requested + <LI> `Fixups' --- there aren't any of these yet, but the phase is intended as a hook for possible extensions like - <code>SetEnv</code>, which don't really fit well elsewhere. - <li> Actually sending a response back to the client. - <li> Logging the request -</ul> + <CODE>SetEnv</CODE>, which don't really fit well elsewhere. + <LI> Actually sending a response back to the client. + <LI> Logging the request +</UL> These phases are handled by looking at each of a succession of -<em>modules</em>, looking to see if each of them has a handler for the +<EM>modules</EM>, looking to see if each of them has a handler for the phase, and attempting invoking it if so. The handler can typically do one of three things: -<ul> - <li> <em>Handle</em> the request, and indicate that it has done so - by returning the magic constant <code>OK</code>. - <li> <em>Decline</em> to handle the request, by returning the magic - integer constant <code>DECLINED</code>. In this case, the +<UL> + <LI> <EM>Handle</EM> the request, and indicate that it has done so + by returning the magic constant <CODE>OK</CODE>. + <LI> <EM>Decline</EM> to handle the request, by returning the magic + integer constant <CODE>DECLINED</CODE>. In this case, the server behaves in all respects as if the handler simply hadn't been there. - <li> Signal an error, by returning one of the HTTP error codes. + <LI> Signal an error, by returning one of the HTTP error codes. This terminates normal handling of the request, although an ErrorDocument may be invoked to try to mop up, and it will be logged in any case. -</ul> +</UL> Most phases are terminated by the first module that handles them; however, for logging, `fixups', and non-access authentication @@ -112,62 +115,62 @@ checking, all handlers always run (barring an error). Also, the response phase is unique in that modules may declare multiple handlers for it, via a dispatch table keyed on the MIME type of the requested object. Modules may declare a response-phase handler which can handle -<em>any</em> request, by giving it the key <code>*/*</code> (i.e., a +<EM>any</EM> request, by giving it the key <CODE>*/*</CODE> (<EM>i.e.</EM>, a wildcard MIME type specification). However, wildcard handlers are only invoked if the server has already tried and failed to find a more specific response handler for the MIME type of the requested object -(either none existed, or they all declined).<p> +(either none existed, or they all declined).<P> The handlers themselves are functions of one argument (a -<code>request_rec</code> structure. vide infra), which returns an -integer, as above.<p> +<CODE>request_rec</CODE> structure. vide infra), which returns an +integer, as above.<P> -<h3><a name="moduletour">A brief tour of a module</a></h3> +<H3><A NAME="moduletour">A brief tour of a module</A></H3> At this point, we need to explain the structure of a module. Our candidate will be one of the messier ones, the CGI module --- this -handles both CGI scripts and the <code>ScriptAlias</code> config file +handles both CGI scripts and the <CODE>ScriptAlias</CODE> config file command. It's actually a great deal more complicated than most modules, but if we're going to have only one example, it might as well -be the one with its fingers in every place.<p> +be the one with its fingers in every place.<P> Let's begin with handlers. In order to handle the CGI scripts, the module declares a response handler for them. Because of -<code>ScriptAlias</code>, it also has handlers for the name -translation phase (to recognize <code>ScriptAlias</code>ed URIs), the -type-checking phase (any <code>ScriptAlias</code>ed request is typed -as a CGI script).<p> +<CODE>ScriptAlias</CODE>, it also has handlers for the name +translation phase (to recognize <CODE>ScriptAlias</CODE>ed URIs), the +type-checking phase (any <CODE>ScriptAlias</CODE>ed request is typed +as a CGI script).<P> The module needs to maintain some per (virtual) -server information, namely, the <code>ScriptAlias</code>es in effect; +server information, namely, the <CODE>ScriptAlias</CODE>es in effect; the module structure therefore contains pointers to a functions which builds these structures, and to another which combines two of them (in case the main server and a virtual server both have -<code>ScriptAlias</code>es declared).<p> +<CODE>ScriptAlias</CODE>es declared).<P> Finally, this module contains code to handle the -<code>ScriptAlias</code> command itself. This particular module only +<CODE>ScriptAlias</CODE> command itself. This particular module only declares one command, but there could be more, so modules have -<em>command tables</em> which declare their commands, and describe -where they are permitted, and how they are to be invoked. <p> +<EM>command tables</EM> which declare their commands, and describe +where they are permitted, and how they are to be invoked. <P> A final note on the declared types of the arguments of some of these -commands: a <code>pool</code> is a pointer to a <em>resource pool</em> +commands: a <CODE>pool</CODE> is a pointer to a <EM>resource pool</EM> structure; these are used by the server to keep track of the memory -which has been allocated, files opened, etc., either to service a +which has been allocated, files opened, <EM>etc.</EM>, either to service a particular request, or to handle the process of configuring itself. That way, when the request is over (or, for the configuration pool, when the server is restarting), the memory can be freed, and the files -closed, <i>en masse</i>, without anyone having to write explicit code to +closed, <EM>en masse</EM>, without anyone having to write explicit code to track them all down and dispose of them. Also, a -<code>cmd_parms</code> structure contains various information about +<CODE>cmd_parms</CODE> structure contains various information about the config file being read, and other status information, which is sometimes of use to the function which processes a config-file command -(such as <code>ScriptAlias</code>). +(such as <CODE>ScriptAlias</CODE>). With no further ado, the module itself: - -<pre> + +<PRE> /* Declarations of handlers. */ int translate_scriptalias (request_rec *); @@ -219,37 +222,37 @@ module cgi_module = { NULL, /* logger */ NULL /* header parser */ }; -</pre> +</PRE> -<h2><a name="handlers">How handlers work</a></h2> +<H2><A NAME="handlers">How handlers work</A></H2> -The sole argument to handlers is a <code>request_rec</code> structure. +The sole argument to handlers is a <CODE>request_rec</CODE> structure. This structure describes a particular request which has been made to the server, on behalf of a client. In most cases, each connection to -the client generates only one <code>request_rec</code> structure.<p> +the client generates only one <CODE>request_rec</CODE> structure.<P> -<h3><a name="req_tour">A brief tour of the <code>request_rec</code></a></h3> +<H3><A NAME="req_tour">A brief tour of the <CODE>request_rec</CODE></A></H3> -The <code>request_rec</code> contains pointers to a resource pool +The <CODE>request_rec</CODE> contains pointers to a resource pool which will be cleared when the server is finished handling the request; to structures containing per-server and per-connection -information, and most importantly, information on the request itself.<p> +information, and most importantly, information on the request itself.<P> The most important such information is a small set of character strings describing attributes of the object being requested, including its URI, filename, content-type and content-encoding (these being filled in by the translation and type-check handlers which handle the -request, respectively). <p> +request, respectively). <P> Other commonly used data items are tables giving the MIME headers on the client's original request, MIME headers to be sent back with the response (which modules can add to at will), and environment variables for any subprocesses which are spawned off in the course of servicing the request. These tables are manipulated using the -<code>table_get</code> and <code>table_set</code> routines. <p> +<CODE>ap_table_get</CODE> and <CODE>ap_table_set</CODE> routines. <P> <BLOCKQUOTE> Note that the <SAMP>Content-type</SAMP> header value <EM>cannot</EM> be - set by module content-handlers using the <SAMP>table_*()</SAMP> + set by module content-handlers using the <SAMP>ap_table_*()</SAMP> routines. Rather, it is set by pointing the <SAMP>content_type</SAMP> field in the <SAMP>request_rec</SAMP> structure to an appropriate string. <EM>E.g.</EM>, @@ -261,17 +264,17 @@ Finally, there are pointers to two data structures which, in turn, point to per-module configuration structures. Specifically, these hold pointers to the data structures which the module has built to describe the way it has been configured to operate in a given -directory (via <code>.htaccess</code> files or -<code><Directory></code> sections), for private data it has +directory (via <CODE>.htaccess</CODE> files or +<CODE><Directory></CODE> sections), for private data it has built in the course of servicing the request (so modules' handlers for one phase can pass `notes' to their handlers for other phases). There -is another such configuration vector in the <code>server_rec</code> -data structure pointed to by the <code>request_rec</code>, which -contains per (virtual) server configuration data.<p> +is another such configuration vector in the <CODE>server_rec</CODE> +data structure pointed to by the <CODE>request_rec</CODE>, which +contains per (virtual) server configuration data.<P> -Here is an abridged declaration, giving the fields most commonly used:<p> +Here is an abridged declaration, giving the fields most commonly used:<P> -<pre> +<PRE> struct request_rec { pool *pool; @@ -279,17 +282,17 @@ struct request_rec { server_rec *server; /* What object is being requested */ - + char *uri; char *filename; char *path_info; char *args; /* QUERY_ARGS, if any */ struct stat finfo; /* Set by server core; * st_mode set to zero if no such file */ - + char *content_type; char *content_encoding; - + /* MIME header environments, in and out. Also, an array containing * environment variables to be passed to subprocesses, so people can * write modules to add to that environment. @@ -299,18 +302,18 @@ struct request_rec { * redirects (so the headers printed for ErrorDocument handlers will * have them). */ - + table *headers_in; table *headers_out; table *err_headers_out; table *subprocess_env; /* Info about the request itself... */ - + int header_only; /* HEAD request, as opposed to GET */ char *protocol; /* Protocol, as given to us, or HTTP/0.9 */ - char *method; /* GET, HEAD, POST, etc. */ - int method_number; /* M_GET, M_POST, etc. */ + char *method; /* GET, HEAD, POST, <EM>etc.</EM> */ + int method_number; /* M_GET, M_POST, <EM>etc.</EM> */ /* Info for logging */ @@ -327,119 +330,122 @@ struct request_rec { * These are config vectors, with one void* pointer for each module * (the thing pointed to being the module's business). */ - - void *per_dir_config; /* Options set in config files, etc. */ + + void *per_dir_config; /* Options set in config files, <EM>etc.</EM> */ void *request_config; /* Notes on *this* request */ - + }; -</pre> +</PRE> -<h3><a name="req_orig">Where request_rec structures come from</a></h3> +<H3><A NAME="req_orig">Where request_rec structures come from</A></H3> -Most <code>request_rec</code> structures are built by reading an HTTP +Most <CODE>request_rec</CODE> structures are built by reading an HTTP request from a client, and filling in the fields. However, there are a few exceptions: -<ul> - <li> If the request is to an imagemap, a type map (i.e., a - <code>*.var</code> file), or a CGI script which returned a +<UL> + <LI> If the request is to an imagemap, a type map (<EM>i.e.</EM>, a + <CODE>*.var</CODE> file), or a CGI script which returned a local `Location:', then the resource which the user requested is going to be ultimately located by some URI other than what the client originally supplied. In this case, the server does - an <em>internal redirect</em>, constructing a new - <code>request_rec</code> for the new URI, and processing it + an <EM>internal redirect</EM>, constructing a new + <CODE>request_rec</CODE> for the new URI, and processing it almost exactly as if the client had requested the new URI - directly. <p> + directly. <P> - <li> If some handler signaled an error, and an - <code>ErrorDocument</code> is in scope, the same internal - redirect machinery comes into play.<p> + <LI> If some handler signaled an error, and an + <CODE>ErrorDocument</CODE> is in scope, the same internal + redirect machinery comes into play.<P> - <li> Finally, a handler occasionally needs to investigate `what + <LI> Finally, a handler occasionally needs to investigate `what would happen if' some other request were run. For instance, the directory indexing module needs to know what MIME type would be assigned to a request for each directory entry, in - order to figure out what icon to use.<p> + order to figure out what icon to use.<P> - Such handlers can construct a <em>sub-request</em>, using the - functions <code>sub_req_lookup_file</code> and - <code>sub_req_lookup_uri</code>; this constructs a new - <code>request_rec</code> structure and processes it as you + Such handlers can construct a <EM>sub-request</EM>, using the + functions <CODE>ap_sub_req_lookup_file</CODE>, + <CODE>ap_sub_req_lookup_uri</CODE>, and + <CODE>ap_sub_req_method_uri</CODE>; these construct a new + <CODE>request_rec</CODE> structure and processes it as you would expect, up to but not including the point of actually sending a response. (These functions skip over the access checks if the sub-request is for a file in the same directory - as the original request).<p> + as the original request).<P> (Server-side includes work by building sub-requests and then actually invoking the response handler for them, via the - function <code>run_sub_request</code>). -</ul> + function <CODE>ap_run_sub_req</CODE>). +</UL> -<h3><a name="req_return">Handling requests, declining, and returning error codes</a></h3> +<H3><A NAME="req_return">Handling requests, declining, and returning error + codes</A></H3> As discussed above, each handler, when invoked to handle a particular -<code>request_rec</code>, has to return an <code>int</code> to +<CODE>request_rec</CODE>, has to return an <CODE>int</CODE> to indicate what happened. That can either be -<ul> - <li> OK --- the request was handled successfully. This may or may +<UL> + <LI> OK --- the request was handled successfully. This may or may not terminate the phase. - <li> DECLINED --- no erroneous condition exists, but the module + <LI> DECLINED --- no erroneous condition exists, but the module declines to handle the phase; the server tries to find another. - <li> an HTTP error code, which aborts handling of the request. -</ul> + <LI> an HTTP error code, which aborts handling of the request. +</UL> -Note that if the error code returned is <code>REDIRECT</code>, then -the module should put a <code>Location</code> in the request's -<code>headers_out</code>, to indicate where the client should be -redirected <em>to</em>. <p> +Note that if the error code returned is <CODE>REDIRECT</CODE>, then +the module should put a <CODE>Location</CODE> in the request's +<CODE>headers_out</CODE>, to indicate where the client should be +redirected <EM>to</EM>. <P> -<h3><a name="resp_handlers">Special considerations for response handlers</a></h3> +<H3><A NAME="resp_handlers">Special considerations for response + handlers</A></H3> Handlers for most phases do their work by simply setting a few fields -in the <code>request_rec</code> structure (or, in the case of access +in the <CODE>request_rec</CODE> structure (or, in the case of access checkers, simply by returning the correct error code). However, -response handlers have to actually send a request back to the client. <p> +response handlers have to actually send a request back to the client. <P> They should begin by sending an HTTP response header, using the -function <code>send_http_header</code>. (You don't have to do +function <CODE>ap_send_http_header</CODE>. (You don't have to do anything special to skip sending the header for HTTP/0.9 requests; the function figures out on its own that it shouldn't do anything). If -the request is marked <code>header_only</code>, that's all they should +the request is marked <CODE>header_only</CODE>, that's all they should do; they should return after that, without attempting any further -output. <p> +output. <P> Otherwise, they should produce a request body which responds to the -client as appropriate. The primitives for this are <code>rputc</code> -and <code>rprintf</code>, for internally generated output, and -<code>send_fd</code>, to copy the contents of some <code>FILE *</code> -straight to the client. <p> +client as appropriate. The primitives for this are <CODE>ap_rputc</CODE> +and <CODE>ap_rprintf</CODE>, for internally generated output, and +<CODE>ap_send_fd</CODE>, to copy the contents of some <CODE>FILE *</CODE> +straight to the client. <P> At this point, you should more or less understand the following piece -of code, which is the handler which handles <code>GET</code> requests +of code, which is the handler which handles <CODE>GET</CODE> requests which have no more specific handler; it also shows how conditional -<code>GET</code>s can be handled, if it's desirable to do so in a -particular response handler --- <code>set_last_modified</code> checks -against the <code>If-modified-since</code> value supplied by the +<CODE>GET</CODE>s can be handled, if it's desirable to do so in a +particular response handler --- <CODE>ap_set_last_modified</CODE> checks +against the <CODE>If-modified-since</CODE> value supplied by the client, if any, and returns an appropriate code (which will, if nonzero, be USE_LOCAL_COPY). No similar considerations apply for -<code>set_content_length</code>, but it returns an error code for -symmetry.<p> +<CODE>ap_set_content_length</CODE>, but it returns an error code for +symmetry.<P> -<pre> +<PRE> int default_handler (request_rec *r) { int errstatus; FILE *f; - + if (r->method_number != M_GET) return DECLINED; if (r->finfo.st_mode == 0) return NOT_FOUND; - if ((errstatus = set_content_length (r, r->finfo.st_size)) - || (errstatus = set_last_modified (r, r->finfo.st_mtime))) + if ((errstatus = ap_set_content_length (r, r->finfo.st_size)) + || (errstatus = ap_set_last_modified (r, r->finfo.st_mtime))) return errstatus; - + f = fopen (r->filename, "r"); if (f == NULL) { @@ -447,252 +453,394 @@ int default_handler (request_rec *r) r->filename, r); return FORBIDDEN; } - + register_timeout ("send", r); - send_http_header (r); + ap_send_http_header (r); if (!r->header_only) send_fd (f, r); - pfclose (r->pool, f); + ap_pfclose (r->pool, f); return OK; } -</pre> +</PRE> Finally, if all of this is too much of a challenge, there are a few ways out of it. First off, as shown above, a response handler which has not yet produced any output can simply return an error code, in which case the server will automatically produce an error response. Secondly, it can punt to some other handler by invoking -<code>internal_redirect</code>, which is how the internal redirection +<CODE>ap_internal_redirect</CODE>, which is how the internal redirection machinery discussed above is invoked. A response handler which has -internally redirected should always return <code>OK</code>. <p> +internally redirected should always return <CODE>OK</CODE>. <P> -(Invoking <code>internal_redirect</code> from handlers which are -<em>not</em> response handlers will lead to serious confusion). +(Invoking <CODE>ap_internal_redirect</CODE> from handlers which are +<EM>not</EM> response handlers will lead to serious confusion). -<h3><a name="auth_handlers">Special considerations for authentication handlers</a></h3> +<H3><A NAME="auth_handlers">Special considerations for authentication + handlers</A></H3> Stuff that should be discussed here in detail: -<ul> - <li> Authentication-phase handlers not invoked unless auth is +<UL> + <LI> Authentication-phase handlers not invoked unless auth is configured for the directory. - <li> Common auth configuration stored in the core per-dir - configuration; it has accessors <code>auth_type</code>, - <code>auth_name</code>, and <code>requires</code>. - <li> Common routines, to handle the protocol end of things, at least - for HTTP basic authentication (<code>get_basic_auth_pw</code>, - which sets the <code>connection->user</code> structure field - automatically, and <code>note_basic_auth_failure</code>, which - arranges for the proper <code>WWW-Authenticate:</code> header + <LI> Common auth configuration stored in the core per-dir + configuration; it has accessors <CODE>ap_auth_type</CODE>, + <CODE>ap_auth_name</CODE>, and <CODE>ap_requires</CODE>. + <LI> Common routines, to handle the protocol end of things, at least + for HTTP basic authentication (<CODE>ap_get_basic_auth_pw</CODE>, + which sets the <CODE>connection->user</CODE> structure field + automatically, and <CODE>ap_note_basic_auth_failure</CODE>, which + arranges for the proper <CODE>WWW-Authenticate:</CODE> header to be sent back). -</ul> +</UL> -<h3><a name="log_handlers">Special considerations for logging handlers</a></h3> +<H3><A NAME="log_handlers">Special considerations for logging handlers</A></H3> When a request has internally redirected, there is the question of what to log. Apache handles this by bundling the entire chain of -redirects into a list of <code>request_rec</code> structures which are -threaded through the <code>r->prev</code> and <code>r->next</code> -pointers. The <code>request_rec</code> which is passed to the logging +redirects into a list of <CODE>request_rec</CODE> structures which are +threaded through the <CODE>r->prev</CODE> and <CODE>r->next</CODE> +pointers. The <CODE>request_rec</CODE> which is passed to the logging handlers in such cases is the one which was originally built for the initial request from the client; note that the bytes_sent field will only be correct in the last request in the chain (the one for which a -response was actually sent). - -<h2><a name="pools">Resource allocation and resource pools</a></h2> +response was actually sent). +<H2><A NAME="pools">Resource allocation and resource pools</A></H2> +<P> One of the problems of writing and designing a server-pool server is that of preventing leakage, that is, allocating resources (memory, -open files, etc.), without subsequently releasing them. The resource +open files, <EM>etc.</EM>), without subsequently releasing them. The resource pool machinery is designed to make it easy to prevent this from happening, by allowing resource to be allocated in such a way that -they are <em>automatically</em> released when the server is done with -them. <p> - +they are <EM>automatically</EM> released when the server is done with +them. +</P> +<P> The way this works is as follows: the memory which is allocated, file -opened, etc., to deal with a particular request are tied to a -<em>resource pool</em> which is allocated for the request. The pool -is a data structure which itself tracks the resources in question. <p> - -When the request has been processed, the pool is <em>cleared</em>. At +opened, <EM>etc.</EM>, to deal with a particular request are tied to a +<EM>resource pool</EM> which is allocated for the request. The pool +is a data structure which itself tracks the resources in question. +</P> +<P> +When the request has been processed, the pool is <EM>cleared</EM>. At that point, all the memory associated with it is released for reuse, all files associated with it are closed, and any other clean-up functions which are associated with the pool are run. When this is over, we can be confident that all the resource tied to the pool have -been released, and that none of them have leaked. <p> - +been released, and that none of them have leaked. +</P> +<P> Server restarts, and allocation of memory and resources for per-server configuration, are handled in a similar way. There is a -<em>configuration pool</em>, which keeps track of resources which were +<EM>configuration pool</EM>, which keeps track of resources which were allocated while reading the server configuration files, and handling the commands therein (for instance, the memory that was allocated for per-server module configuration, log files and other files that were opened, and so forth). When the server restarts, and has to reread the configuration files, the configuration pool is cleared, and so the memory and file descriptors which were taken up by reading them the -last time are made available for reuse. <p> - +last time are made available for reuse. +</P> +<P> It should be noted that use of the pool machinery isn't generally obligatory, except for situations like logging handlers, where you really need to register cleanups to make sure that the log file gets closed when the server restarts (this is most easily done by using the -function <code><a href="#pool-files">pfopen</a></code>, which also +function <CODE><A HREF="#pool-files">ap_pfopen</A></CODE>, which also arranges for the underlying file descriptor to be closed before any -child processes, such as for CGI scripts, are <code>exec</code>ed), or +child processes, such as for CGI scripts, are <CODE>exec</CODE>ed), or in case you are using the timeout machinery (which isn't yet even documented here). However, there are two benefits to using it: resources allocated to a pool never leak (even if you allocate a scratch string, and just forget about it); also, for memory -allocation, <code>palloc</code> is generally faster than -<code>malloc</code>.<p> - +allocation, <CODE>ap_palloc</CODE> is generally faster than +<CODE>malloc</CODE>. +</P> +<P> We begin here by describing how memory is allocated to pools, and then discuss how other resources are tracked by the resource pool machinery. - -<h3>Allocation of memory in pools</h3> - +</P> +<H3>Allocation of memory in pools</H3> +<P> Memory is allocated to pools by calling the function -<code>palloc</code>, which takes two arguments, one being a pointer to +<CODE>ap_palloc</CODE>, which takes two arguments, one being a pointer to a resource pool structure, and the other being the amount of memory to -allocate (in <code>char</code>s). Within handlers for handling +allocate (in <CODE>char</CODE>s). Within handlers for handling requests, the most common way of getting a resource pool structure is -by looking at the <code>pool</code> slot of the relevant -<code>request_rec</code>; hence the repeated appearance of the +by looking at the <CODE>pool</CODE> slot of the relevant +<CODE>request_rec</CODE>; hence the repeated appearance of the following idiom in module code: - -<pre> +</P> +<PRE> int my_handler(request_rec *r) { struct my_structure *foo; ... - foo = (foo *)palloc (r->pool, sizeof(my_structure)); + foo = (foo *)ap_palloc (r->pool, sizeof(my_structure)); } -</pre> - -Note that <em>there is no <code>pfree</code></em> --- -<code>palloc</code>ed memory is freed only when the associated -resource pool is cleared. This means that <code>palloc</code> does not -have to do as much accounting as <code>malloc()</code>; all it does in +</PRE> +<P> +Note that <EM>there is no <CODE>ap_pfree</CODE></EM> --- +<CODE>ap_palloc</CODE>ed memory is freed only when the associated +resource pool is cleared. This means that <CODE>ap_palloc</CODE> does not +have to do as much accounting as <CODE>malloc()</CODE>; all it does in the typical case is to round up the size, bump a pointer, and do a -range check.<p> - -(It also raises the possibility that heavy use of <code>palloc</code> +range check. +</P> +<P> +(It also raises the possibility that heavy use of <CODE>ap_palloc</CODE> could cause a server process to grow excessively large. There are two ways to deal with this, which are dealt with below; briefly, you -can use <code>malloc</code>, and try to be sure that all of the memory -gets explicitly <code>free</code>d, or you can allocate a sub-pool of +can use <CODE>malloc</CODE>, and try to be sure that all of the memory +gets explicitly <CODE>free</CODE>d, or you can allocate a sub-pool of the main pool, allocate your memory in the sub-pool, and clear it out periodically. The latter technique is discussed in the section on sub-pools below, and is used in the directory-indexing code, in order to avoid excessive storage allocation when listing directories with thousands of files). - -<h3>Allocating initialized memory</h3> - +</P> +<H3>Allocating initialized memory</H3> +<P> There are functions which allocate initialized memory, and are -frequently useful. The function <code>pcalloc</code> has the same -interface as <code>palloc</code>, but clears out the memory it -allocates before it returns it. The function <code>pstrdup</code> -takes a resource pool and a <code>char *</code> as arguments, and +frequently useful. The function <CODE>ap_pcalloc</CODE> has the same +interface as <CODE>ap_palloc</CODE>, but clears out the memory it +allocates before it returns it. The function <CODE>ap_pstrdup</CODE> +takes a resource pool and a <CODE>char *</CODE> as arguments, and allocates memory for a copy of the string the pointer points to, -returning a pointer to the copy. Finally <code>pstrcat</code> is a +returning a pointer to the copy. Finally <CODE>ap_pstrcat</CODE> is a varargs-style function, which takes a pointer to a resource pool, and -at least two <code>char *</code> arguments, the last of which must be -<code>NULL</code>. It allocates enough memory to fit copies of each +at least two <CODE>char *</CODE> arguments, the last of which must be +<CODE>NULL</CODE>. It allocates enough memory to fit copies of each of the strings, as a unit; for instance: - -<pre> - pstrcat (r->pool, "foo", "/", "bar", NULL); -</pre> - +</P> +<PRE> + ap_pstrcat (r->pool, "foo", "/", "bar", NULL); +</PRE> +<P> returns a pointer to 8 bytes worth of memory, initialized to -<code>"foo/bar"</code>. - -<h3><a name="pool-files">Tracking open files, etc.</a></h3> - +<CODE>"foo/bar"</CODE>. +</P> +<H3><A NAME="pools-used">Commonly-used pools in the Apache Web server</A></H3> +<P> +A pool is really defined by its lifetime more than anything else. There +are some static pools in http_main which are passed to various +non-http_main functions as arguments at opportune times. Here they are: +</P> +<DL COMPACT> + <DT>permanent_pool + </DT> + <DD> + <UL> + <LI>never passed to anything else, this is the ancestor of all pools + </LI> + </UL> + </DD> + <DT>pconf + </DT> + <DD> + <UL> + <LI>subpool of permanent_pool + </LI> + <LI>created at the beginning of a config "cycle"; exists until the + server is terminated or restarts; passed to all config-time + routines, either via cmd->pool, or as the "pool *p" argument on + those which don't take pools + </LI> + <LI>passed to the module init() functions + </LI> + </UL> + </DD> + <DT>ptemp + </DT> + <DD> + <UL> + <LI>sorry I lie, this pool isn't called this currently in 1.3, I + renamed it this in my pthreads development. I'm referring to + the use of ptrans in the parent... contrast this with the later + definition of ptrans in the child. + </LI> + <LI>subpool of permanent_pool + </LI> + <LI>created at the beginning of a config "cycle"; exists until the + end of config parsing; passed to config-time routines <EM>via</EM> + cmd->temp_pool. Somewhat of a "bastard child" because it isn't + available everywhere. Used for temporary scratch space which + may be needed by some config routines but which is deleted at + the end of config. + </LI> + </UL> + </DD> + <DT>pchild + </DT> + <DD> + <UL> + <LI>subpool of permanent_pool + </LI> + <LI>created when a child is spawned (or a thread is created); lives + until that child (thread) is destroyed + </LI> + <LI>passed to the module child_init functions + </LI> + <LI>destruction happens right after the child_exit functions are + called... (which may explain why I think child_exit is redundant + and unneeded) + </LI> + </UL> + </DD> + <DT>ptrans + <DT> + <DD> + <UL> + <LI>should be a subpool of pchild, but currently is a subpool of + permanent_pool, see above + </LI> + <LI>cleared by the child before going into the accept() loop to receive + a connection + </LI> + <LI>used as connection->pool + </LI> + </UL> + </DD> + <DT>r->pool + </DT> + <DD> + <UL> + <LI>for the main request this is a subpool of connection->pool; for + subrequests it is a subpool of the parent request's pool. + </LI> + <LI>exists until the end of the request (<EM>i.e.</EM>, + ap_destroy_sub_req, or + in child_main after process_request has finished) + </LI> + <LI>note that r itself is allocated from r->pool; <EM>i.e.</EM>, + r->pool is + first created and then r is the first thing palloc()d from it + </LI> + </UL> + </DD> +</DL> +<P> +For almost everything folks do, r->pool is the pool to use. But you +can see how other lifetimes, such as pchild, are useful to some +modules... such as modules that need to open a database connection once +per child, and wish to clean it up when the child dies. +</P> +<P> +You can also see how some bugs have manifested themself, such as setting +connection->user to a value from r->pool -- in this case +connection exists +for the lifetime of ptrans, which is longer than r->pool (especially if +r->pool is a subrequest!). So the correct thing to do is to allocate +from connection->pool. +</P> +<P> +And there was another interesting bug in mod_include/mod_cgi. You'll see +in those that they do this test to decide if they should use r->pool +or r->main->pool. In this case the resource that they are registering +for cleanup is a child process. If it were registered in r->pool, +then the code would wait() for the child when the subrequest finishes. +With mod_include this could be any old #include, and the delay can be up +to 3 seconds... and happened quite frequently. Instead the subprocess +is registered in r->main->pool which causes it to be cleaned up when +the entire request is done -- <EM>i.e.</EM>, after the output has been sent to +the client and logging has happened. +</P> +<H3><A NAME="pool-files">Tracking open files, etc.</A></H3> +<P> As indicated above, resource pools are also used to track other sorts of resources besides memory. The most common are open files. The -routine which is typically used for this is <code>pfopen</code>, which +routine which is typically used for this is <CODE>ap_pfopen</CODE>, which takes a resource pool and two strings as arguments; the strings are -the same as the typical arguments to <code>fopen</code>, e.g., - -<pre> +the same as the typical arguments to <CODE>fopen</CODE>, <EM>e.g.</EM>, +</P> +<PRE> ... - FILE *f = pfopen (r->pool, r->filename, "r"); + FILE *f = ap_pfopen (r->pool, r->filename, "r"); if (f == NULL) { ... } else { ... } -</pre> - -There is also a <code>popenf</code> routine, which parallels the -lower-level <code>open</code> system call. Both of these routines +</PRE> +<P> +There is also a <CODE>ap_popenf</CODE> routine, which parallels the +lower-level <CODE>open</CODE> system call. Both of these routines arrange for the file to be closed when the resource pool in question -is cleared. <p> - -Unlike the case for memory, there <em>are</em> functions to close -files allocated with <code>pfopen</code>, and <code>popenf</code>, -namely <code>pfclose</code> and <code>pclosef</code>. (This is +is cleared. +</P> +<P> +Unlike the case for memory, there <EM>are</EM> functions to close +files allocated with <CODE>ap_pfopen</CODE>, and <CODE>ap_popenf</CODE>, +namely <CODE>ap_pfclose</CODE> and <CODE>ap_pclosef</CODE>. (This is because, on many systems, the number of files which a single process can have open is quite limited). It is important to use these -functions to close files allocated with <code>pfopen</code> and -<code>popenf</code>, since to do otherwise could cause fatal errors on +functions to close files allocated with <CODE>ap_pfopen</CODE> and +<CODE>ap_popenf</CODE>, since to do otherwise could cause fatal errors on systems such as Linux, which react badly if the same -<code>FILE*</code> is closed more than once. <p> - -(Using the <code>close</code> functions is not mandatory, since the +<CODE>FILE*</CODE> is closed more than once. +</P> +<P> +(Using the <CODE>close</CODE> functions is not mandatory, since the file will eventually be closed regardless, but you should consider it in cases where your module is opening, or could open, a lot of files). - -<h3>Other sorts of resources --- cleanup functions</h3> - +</P> +<H3>Other sorts of resources --- cleanup functions</H3> +<BLOCKQUOTE> More text goes here. Describe the the cleanup primitives in terms of -which the file stuff is implemented; also, <code>spawn_process</code>. - -<h3>Fine control --- creating and dealing with sub-pools, with a note -on sub-requests</h3> - -On rare occasions, too-free use of <code>palloc()</code> and the +which the file stuff is implemented; also, <CODE>spawn_process</CODE>. +</BLOCKQUOTE> +<P> +Pool cleanups live until clear_pool() is called: clear_pool(a) recursively +calls destroy_pool() on all subpools of a; then calls all the cleanups for a; +then releases all the memory for a. destroy_pool(a) calls clear_pool(a) +and then releases the pool structure itself. <EM>i.e.</EM>, clear_pool(a) doesn't +delete a, it just frees up all the resources and you can start using it +again immediately. +</P> +<H3>Fine control --- creating and dealing with sub-pools, with a note +on sub-requests</H3> + +On rare occasions, too-free use of <CODE>ap_palloc()</CODE> and the associated primitives may result in undesirably profligate resource allocation. You can deal with such a case by creating a -<em>sub-pool</em>, allocating within the sub-pool rather than the main +<EM>sub-pool</EM>, allocating within the sub-pool rather than the main pool, and clearing or destroying the sub-pool, which releases the -resources which were associated with it. (This really <em>is</em> a +resources which were associated with it. (This really <EM>is</EM> a rare situation; the only case in which it comes up in the standard module set is in case of listing directories, and then only with -<em>very</em> large directories. Unnecessary use of the primitives +<EM>very</EM> large directories. Unnecessary use of the primitives discussed here can hair up your code quite a bit, with very little -gain). <p> +gain). <P> -The primitive for creating a sub-pool is <code>make_sub_pool</code>, +The primitive for creating a sub-pool is <CODE>ap_make_sub_pool</CODE>, which takes another pool (the parent pool) as an argument. When the main pool is cleared, the sub-pool will be destroyed. The sub-pool may also be cleared or destroyed at any time, by calling the functions -<code>clear_pool</code> and <code>destroy_pool</code>, respectively. -(The difference is that <code>clear_pool</code> frees resources -associated with the pool, while <code>destroy_pool</code> also +<CODE>ap_clear_pool</CODE> and <CODE>ap_destroy_pool</CODE>, respectively. +(The difference is that <CODE>ap_clear_pool</CODE> frees resources +associated with the pool, while <CODE>ap_destroy_pool</CODE> also deallocates the pool itself. In the former case, you can allocate new resources within the pool, and clear it again, and so forth; in the -latter case, it is simply gone). <p> +latter case, it is simply gone). <P> One final note --- sub-requests have their own resource pools, which are sub-pools of the resource pool for the main request. The polite way to reclaim the resources associated with a sub request which you -have allocated (using the <code>sub_req_lookup_...</code> functions) -is <code>destroy_sub_request</code>, which frees the resource pool. +have allocated (using the <CODE>ap_sub_req_...</CODE> functions) +is <CODE>ap_destroy_sub_req</CODE>, which frees the resource pool. Before calling this function, be sure to copy anything that you care about which might be allocated in the sub-request's resource pool into someplace a little less volatile (for instance, the filename in its -<code>request_rec</code> structure). <p> +<CODE>request_rec</CODE> structure). <P> (Again, under most circumstances, you shouldn't feel obliged to call this function; only 2K of memory or so are allocated for a typical sub request, and it will be freed anyway when the main request pool is cleared. It is only when you are allocating many, many sub-requests for a single main request that you should seriously consider the -<code>destroy...</code> functions). +<CODE>ap_destroy_...</CODE> functions). -<h2><a name="config">Configuration, commands and the like</a></h2> +<H2><A NAME="config">Configuration, commands and the like</A></H2> One of the design goals for this server was to maintain external compatibility with the NCSA 1.3 server --- that is, to read the same @@ -702,7 +850,7 @@ hand, another design goal was to move as much of the server's functionality into modules which have as little as possible to do with the monolithic server core. The only way to reconcile these goals is to move the handling of most commands from the central server into the -modules. <p> +modules. <P> However, just giving the modules command tables is not enough to divorce them completely from the server core. The server has to @@ -711,96 +859,96 @@ maintaining data which is private to the modules, and which can be either per-server, or per-directory. Most things are per-directory, including in particular access control and authorization information, but also information on how to determine file types from suffixes, -which can be modified by <code>AddType</code> and -<code>DefaultType</code> directives, and so forth. In general, the -governing philosophy is that anything which <em>can</em> be made +which can be modified by <CODE>AddType</CODE> and +<CODE>DefaultType</CODE> directives, and so forth. In general, the +governing philosophy is that anything which <EM>can</EM> be made configurable by directory should be; per-server information is generally used in the standard set of modules for information like -<code>Alias</code>es and <code>Redirect</code>s which come into play +<CODE>Alias</CODE>es and <CODE>Redirect</CODE>s which come into play before the request is tied to a particular place in the underlying -file system. <p> +file system. <P> Another requirement for emulating the NCSA server is being able to handle the per-directory configuration files, generally called -<code>.htaccess</code> files, though even in the NCSA server they can +<CODE>.htaccess</CODE> files, though even in the NCSA server they can contain directives which have nothing at all to do with access control. Accordingly, after URI -> filename translation, but before performing any other phase, the server walks down the directory hierarchy of the underlying filesystem, following the translated -pathname, to read any <code>.htaccess</code> files which might be +pathname, to read any <CODE>.htaccess</CODE> files which might be present. The information which is read in then has to be -<em>merged</em> with the applicable information from the server's own -config files (either from the <code><Directory></code> sections -in <code>access.conf</code>, or from defaults in -<code>srm.conf</code>, which actually behaves for most purposes almost -exactly like <code><Directory /></code>).<p> +<EM>merged</EM> with the applicable information from the server's own +config files (either from the <CODE><Directory></CODE> sections +in <CODE>access.conf</CODE>, or from defaults in +<CODE>srm.conf</CODE>, which actually behaves for most purposes almost +exactly like <CODE><Directory /></CODE>).<P> Finally, after having served a request which involved reading -<code>.htaccess</code> files, we need to discard the storage allocated +<CODE>.htaccess</CODE> files, we need to discard the storage allocated for handling them. That is solved the same way it is solved wherever else similar problems come up, by tying those structures to the -per-transaction resource pool. <p> +per-transaction resource pool. <P> -<h3><a name="per-dir">Per-directory configuration structures</a></h3> +<H3><A NAME="per-dir">Per-directory configuration structures</A></H3> -Let's look out how all of this plays out in <code>mod_mime.c</code>, +Let's look out how all of this plays out in <CODE>mod_mime.c</CODE>, which defines the file typing handler which emulates the NCSA server's behavior of determining file types from suffixes. What we'll be looking at, here, is the code which implements the -<code>AddType</code> and <code>AddEncoding</code> commands. These -commands can appear in <code>.htaccess</code> files, so they must be +<CODE>AddType</CODE> and <CODE>AddEncoding</CODE> commands. These +commands can appear in <CODE>.htaccess</CODE> files, so they must be handled in the module's private per-directory data, which in fact, -consists of two separate <code>table</code>s for MIME types and +consists of two separate <CODE>table</CODE>s for MIME types and encoding information, and is declared as follows: -<pre> +<PRE> typedef struct { table *forced_types; /* Additional AddTyped stuff */ table *encoding_types; /* Added with AddEncoding... */ } mime_dir_config; -</pre> +</PRE> When the server is reading a configuration file, or -<code><Directory></code> section, which includes one of the MIME -module's commands, it needs to create a <code>mime_dir_config</code> +<CODE><Directory></CODE> section, which includes one of the MIME +module's commands, it needs to create a <CODE>mime_dir_config</CODE> structure, so those commands have something to act on. It does this by invoking the function it finds in the module's `create per-dir config slot', with two arguments: the name of the directory to which -this configuration information applies (or <code>NULL</code> for -<code>srm.conf</code>), and a pointer to a resource pool in which the -allocation should happen. <p> +this configuration information applies (or <CODE>NULL</CODE> for +<CODE>srm.conf</CODE>), and a pointer to a resource pool in which the +allocation should happen. <P> -(If we are reading a <code>.htaccess</code> file, that resource pool +(If we are reading a <CODE>.htaccess</CODE> file, that resource pool is the per-request resource pool for the request; otherwise it is a resource pool which is used for configuration data, and cleared on restarts. Either way, it is important for the structure being created to vanish when the pool is cleared, by registering a cleanup on the -pool if necessary). <p> +pool if necessary). <P> For the MIME module, the per-dir config creation function just -<code>palloc</code>s the structure above, and a creates a couple of -<code>table</code>s to fill it. That looks like this: +<CODE>ap_palloc</CODE>s the structure above, and a creates a couple of +<CODE>table</CODE>s to fill it. That looks like this: -<pre> +<PRE> void *create_mime_dir_config (pool *p, char *dummy) { mime_dir_config *new = - (mime_dir_config *) palloc (p, sizeof(mime_dir_config)); + (mime_dir_config *) ap_palloc (p, sizeof(mime_dir_config)); + + new->forced_types = ap_make_table (p, 4); + new->encoding_types = ap_make_table (p, 4); - new->forced_types = make_table (p, 4); - new->encoding_types = make_table (p, 4); - return new; } -</pre> +</PRE> -Now, suppose we've just read in a <code>.htaccess</code> file. We +Now, suppose we've just read in a <CODE>.htaccess</CODE> file. We already have the per-directory configuration structure for the next -directory up in the hierarchy. If the <code>.htaccess</code> file we -just read in didn't have any <code>AddType</code> or -<code>AddEncoding</code> commands, its per-directory config structure +directory up in the hierarchy. If the <CODE>.htaccess</CODE> file we +just read in didn't have any <CODE>AddType</CODE> or +<CODE>AddEncoding</CODE> commands, its per-directory config structure for the MIME module is still valid, and we can just use it. -Otherwise, we need to merge the two structures somehow. <p> +Otherwise, we need to merge the two structures somehow. <P> To do that, the server invokes the module's per-directory config merge function, if one is present. That function takes three arguments: @@ -809,171 +957,172 @@ allocate the result. For the MIME module, all that needs to be done is overlay the tables from the new per-directory config structure with those from the parent: -<pre> +<PRE> void *merge_mime_dir_configs (pool *p, void *parent_dirv, void *subdirv) { mime_dir_config *parent_dir = (mime_dir_config *)parent_dirv; mime_dir_config *subdir = (mime_dir_config *)subdirv; mime_dir_config *new = - (mime_dir_config *)palloc (p, sizeof(mime_dir_config)); + (mime_dir_config *)ap_palloc (p, sizeof(mime_dir_config)); - new->forced_types = overlay_tables (p, subdir->forced_types, + new->forced_types = ap_overlay_tables (p, subdir->forced_types, parent_dir->forced_types); - new->encoding_types = overlay_tables (p, subdir->encoding_types, + new->encoding_types = ap_overlay_tables (p, subdir->encoding_types, parent_dir->encoding_types); return new; } -</pre> +</PRE> As a note --- if there is no per-directory merge function present, the server will just use the subdirectory's configuration info, and ignore -the parent's. For some modules, that works just fine (e.g., for the +the parent's. For some modules, that works just fine (<EM>e.g.</EM>, for the includes module, whose per-directory configuration information -consists solely of the state of the <code>XBITHACK</code>), and for +consists solely of the state of the <CODE>XBITHACK</CODE>), and for those modules, you can just not declare one, and leave the -corresponding structure slot in the module itself <code>NULL</code>.<p> +corresponding structure slot in the module itself <CODE>NULL</CODE>.<P> -<h3><a name="commands">Command handling</a></h3> +<H3><A NAME="commands">Command handling</A></H3> Now that we have these structures, we need to be able to figure out how to fill them. That involves processing the actual -<code>AddType</code> and <code>AddEncoding</code> commands. To find -commands, the server looks in the module's <code>command table</code>. +<CODE>AddType</CODE> and <CODE>AddEncoding</CODE> commands. To find +commands, the server looks in the module's <CODE>command table</CODE>. That table contains information on how many arguments the commands take, and in what formats, where it is permitted, and so forth. That information is sufficient to allow the server to invoke most command-handling functions with pre-parsed arguments. Without further -ado, let's look at the <code>AddType</code> command handler, which -looks like this (the <code>AddEncoding</code> command looks basically +ado, let's look at the <CODE>AddType</CODE> command handler, which +looks like this (the <CODE>AddEncoding</CODE> command looks basically the same, and won't be shown here): -<pre> +<PRE> char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct, char *ext) { if (*ext == '.') ++ext; - table_set (m->forced_types, ext, ct); + ap_table_set (m->forced_types, ext, ct); return NULL; } -</pre> +</PRE> This command handler is unusually simple. As you can see, it takes four arguments, two of which are pre-parsed arguments, the third being the per-directory configuration structure for the module in question, -and the fourth being a pointer to a <code>cmd_parms</code> structure. +and the fourth being a pointer to a <CODE>cmd_parms</CODE> structure. That structure contains a bunch of arguments which are frequently of use to some, but not all, commands, including a resource pool (from which memory can be allocated, and to which cleanups should be tied), and the (virtual) server being configured, from which the module's -per-server configuration data can be obtained if required.<p> +per-server configuration data can be obtained if required.<P> Another way in which this particular command handler is unusually simple is that there are no error conditions which it can encounter. If there were, it could return an error message instead of -<code>NULL</code>; this causes an error to be printed out on the -server's <code>stderr</code>, followed by a quick exit, if it is in -the main config files; for a <code>.htaccess</code> file, the syntax +<CODE>NULL</CODE>; this causes an error to be printed out on the +server's <CODE>stderr</CODE>, followed by a quick exit, if it is in +the main config files; for a <CODE>.htaccess</CODE> file, the syntax error is logged in the server error log (along with an indication of where it came from), and the request is bounced with a server error -response (HTTP error status, code 500). <p> +response (HTTP error status, code 500). <P> The MIME module's command table has entries for these commands, which look like this: -<pre> +<PRE> command_rec mime_cmds[] = { -{ "AddType", add_type, NULL, OR_FILEINFO, TAKE2, +{ "AddType", add_type, NULL, OR_FILEINFO, TAKE2, "a mime type followed by a file extension" }, -{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, TAKE2, - "an encoding (e.g., gzip), followed by a file extension" }, +{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, TAKE2, + "an encoding (<EM>e.g.</EM>, gzip), followed by a file extension" }, { NULL } }; -</pre> +</PRE> The entries in these tables are: -<ul> - <li> The name of the command - <li> The function which handles it - <li> a <code>(void *)</code> pointer, which is passed in the - <code>cmd_parms</code> structure to the command handler --- +<UL> + <LI> The name of the command + <LI> The function which handles it + <LI> a <CODE>(void *)</CODE> pointer, which is passed in the + <CODE>cmd_parms</CODE> structure to the command handler --- this is useful in case many similar commands are handled by the same function. - <li> A bit mask indicating where the command may appear. There are - mask bits corresponding to each <code>AllowOverride</code> - option, and an additional mask bit, <code>RSRC_CONF</code>, + <LI> A bit mask indicating where the command may appear. There are + mask bits corresponding to each <CODE>AllowOverride</CODE> + option, and an additional mask bit, <CODE>RSRC_CONF</CODE>, indicating that the command may appear in the server's own - config files, but <em>not</em> in any <code>.htaccess</code> + config files, but <EM>not</EM> in any <CODE>.htaccess</CODE> file. - <li> A flag indicating how many arguments the command handler wants + <LI> A flag indicating how many arguments the command handler wants pre-parsed, and how they should be passed in. - <code>TAKE2</code> indicates two pre-parsed arguments. Other - options are <code>TAKE1</code>, which indicates one pre-parsed - argument, <code>FLAG</code>, which indicates that the argument - should be <code>On</code> or <code>Off</code>, and is passed in - as a boolean flag, <code>RAW_ARGS</code>, which causes the + <CODE>TAKE2</CODE> indicates two pre-parsed arguments. Other + options are <CODE>TAKE1</CODE>, which indicates one pre-parsed + argument, <CODE>FLAG</CODE>, which indicates that the argument + should be <CODE>On</CODE> or <CODE>Off</CODE>, and is passed in + as a boolean flag, <CODE>RAW_ARGS</CODE>, which causes the server to give the command the raw, unparsed arguments (everything but the command name itself). There is also - <code>ITERATE</code>, which means that the handler looks the - same as <code>TAKE1</code>, but that if multiple arguments are + <CODE>ITERATE</CODE>, which means that the handler looks the + same as <CODE>TAKE1</CODE>, but that if multiple arguments are present, it should be called multiple times, and finally - <code>ITERATE2</code>, which indicates that the command handler - looks like a <code>TAKE2</code>, but if more arguments are + <CODE>ITERATE2</CODE>, which indicates that the command handler + looks like a <CODE>TAKE2</CODE>, but if more arguments are present, then it should be called multiple times, holding the first argument constant. - <li> Finally, we have a string which describes the arguments that + <LI> Finally, we have a string which describes the arguments that should be present. If the arguments in the actual config file are not as required, this string will be used to help give a more specific error message. (You can safely leave this - <code>NULL</code>). -</ul> + <CODE>NULL</CODE>). +</UL> Finally, having set this all up, we have to use it. This is ultimately done in the module's handlers, specifically for its file-typing handler, which looks more or less like this; note that the per-directory configuration structure is extracted from the -<code>request_rec</code>'s per-directory configuration vector by using -the <code>get_module_config</code> function. +<CODE>request_rec</CODE>'s per-directory configuration vector by using +the <CODE>ap_get_module_config</CODE> function. -<pre> +<PRE> int find_ct(request_rec *r) { int i; - char *fn = pstrdup (r->pool, r->filename); + char *fn = ap_pstrdup (r->pool, r->filename); mime_dir_config *conf = (mime_dir_config *) - get_module_config(r->per_dir_config, &mime_module); + ap_get_module_config(r->per_dir_config, &mime_module); char *type; - if (S_ISDIR(r->finfo.st_mode)) { - r->content_type = DIR_MAGIC_TYPE; + if (S_ISDIR(r->finfo.st_mode)) { + r->content_type = DIR_MAGIC_TYPE; return OK; } - - if((i=rind(fn,'.')) < 0) return DECLINED; + + if((i=ap_rind(fn,'.')) < 0) return DECLINED; ++i; - if ((type = table_get (conf->encoding_types, &fn[i]))) + if ((type = ap_table_get (conf->encoding_types, &fn[i]))) { - r->content_encoding = type; + r->content_encoding = type; /* go back to previous extension to try to use it as a type */ fn[i-1] = '\0'; - if((i=rind(fn,'.')) < 0) return OK; + if((i=ap_rind(fn,'.')) < 0) return OK; ++i; } - if ((type = table_get (conf->forced_types, &fn[i]))) + if ((type = ap_table_get (conf->forced_types, &fn[i]))) { - r->content_type = type; + r->content_type = type; } - + return OK; } -</pre> +</PRE> -<h3><a name="servconf">Side notes --- per-server configuration, virtual servers, etc.</a></h3> +<H3><A NAME="servconf">Side notes --- per-server configuration, virtual + servers, <EM>etc</EM>.</A></H3> The basic ideas behind per-server module configuration are basically the same as those for per-directory configuration; there is a creation @@ -982,36 +1131,37 @@ virtual server has partially overridden the base server configuration, and a combined structure must be computed. (As with per-directory configuration, the default if no merge function is specified, and a module is configured in some virtual server, is that the base -configuration is simply ignored). <p> +configuration is simply ignored). <P> The only substantial difference is that when a command needs to configure the per-server private module data, it needs to go to the -<code>cmd_parms</code> data to get at it. Here's an example, from the +<CODE>cmd_parms</CODE> data to get at it. Here's an example, from the alias module, which also indicates how a syntax error can be returned (note that the per-directory configuration argument to the command handler is declared as a dummy, since the module doesn't actually have per-directory config data): -<pre> +<PRE> char *add_redirect(cmd_parms *cmd, void *dummy, char *f, char *url) { - server_rec *s = cmd->server; + server_rec *s = cmd->server; alias_server_conf *conf = (alias_server_conf *) - get_module_config(s->module_config,&alias_module); - alias_entry *new = push_array (conf->redirects); + ap_get_module_config(s->module_config,&alias_module); + alias_entry *new = ap_push_array (conf->redirects); + + if (!ap_is_url (url)) return "Redirect to non-URL"; - if (!is_url (url)) return "Redirect to non-URL"; - new->fake = f; new->real = url; return NULL; } -</pre> +</PRE> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> <A HREF="../"><IMG SRC="../images/home.gif" ALT="Home"></A> -</body></html> +</BODY></HTML> diff --git a/usr.sbin/httpd/htdocs/manual/misc/FAQ.html b/usr.sbin/httpd/htdocs/manual/misc/FAQ.html index d7d335f7810..04475577e93 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/FAQ.html +++ b/usr.sbin/httpd/htdocs/manual/misc/FAQ.html @@ -2,6 +2,7 @@ <HTML> <HEAD> <TITLE>Apache Server Frequently Asked Questions</TITLE> + </HEAD> <!-- Background white, links blue (unvisited), navy (visited), red (active) --> <BODY @@ -20,7 +21,7 @@ <H1 ALIGN="CENTER">Apache Server Frequently Asked Questions</H1> <P> - $Revision: 1.3 $ ($Date: 1999/03/01 01:05:09 $) + $Revision: 1.4 $ ($Date: 1999/09/29 06:29:00 $) </P> <P> The latest version of this FAQ is always available from the main @@ -85,11 +86,20 @@ <!-- (A: you can't but "satisfy any; allow from all" can be close --> <!-- - '400 malformed request' on Win32 might mean stale proxy; see --> <!-- PR #2300. --> -<!-- - "expected </Directory> saw </Directory" due to buggy AIX --> -<!-- compiler. --> -<UL> - <LI><STRONG>Background</STRONG> - <OL START=1> +<!-- - how do I tell what version of Apache I am running? --> +<OL TYPE="A"> + + + + + + + + + + + <LI VALUE="1"><STRONG>Background</STRONG> + <OL> <LI><A HREF="#what">What is Apache?</A> </LI> <LI><A HREF="#why">Why was Apache created?</A> @@ -113,55 +123,163 @@ </LI> </OL> </LI> - <LI><STRONG>Technical Questions</STRONG> - <OL START=11> + + + + + + + + + + + + + + + + <LI value="2"><STRONG>General Technical Questions</STRONG> + <OL> <LI><A HREF="#what2do">"Why can't I ...? Why won't ... work?" What to do in case of problems</A> </LI> <LI><A HREF="#compatible">How compatible is Apache with my existing NCSA 1.3 setup?</A> </LI> - <LI><A HREF="#CGIoutsideScriptAlias">How do I enable CGI execution - in directories other than the ScriptAlias?</A> + <LI><A HREF="#year2000">Is Apache Year 2000 compliant?</A> </LI> - <LI><A HREF="#premature-script-headers">What does it mean when my - CGIs fail with "<SAMP>Premature end of script - headers</SAMP>"?</A> + <LI><A HREF="#submit_patch">How do I submit a patch to the Apache Group?</A> </LI> - <LI><A HREF="#ssi-part-i">How do I enable SSI (parsed HTML)?</A> + <LI><A HREF="#domination">Why has Apache stolen my favourite site's + Internet address?</A> </LI> - <LI><A HREF="#ssi-part-ii">Why don't my parsed files get cached?</A> + <LI><A HREF="#apspam">Why am I getting spam mail from the Apache site?</A> </LI> - <LI><A HREF="#ssi-part-iii">How can I have my script output parsed?</A> + <LI><A HREF="#redist">May I include the Apache software on a CD or other + package I'm distributing?</A> </LI> - <LI><A HREF="#ssi-part-iv">SSIs don't work for VirtualHosts and/or - user home directories</A> + <LI><A HREF="#zoom">What's the best hardware/operating system/... How do + I get the most out of my Apache Web server?</A> </LI> - <LI><A HREF="#proxy">Does or will Apache act as a Proxy server?</A> + <LI><A HREF="#regex">What are "regular expressions"?</A> </LI> - <LI><A HREF="#multiviews">What are "multiviews"?</A> + </OL> + </LI> + + + + + + + + + + + + + + + + <LI VALUE="3"><STRONG>Building Apache</STRONG> + <OL> + <LI><A HREF="#bind8.1">Why do I get an error about an undefined + reference to "<SAMP>__inet_ntoa</SAMP>" or other + <SAMP>__inet_*</SAMP> symbols?</A> + </LI> + <LI><A HREF="#cantbuild">Why won't Apache compile with my + system's <SAMP>cc</SAMP>?</A> + </LI> + <LI><A HREF="#linuxiovec">Why do I get complaints about redefinition + of "<CODE>struct iovec</CODE>" when compiling under Linux?</A> </LI> + <LI><A HREF="#broken-gcc">I'm using gcc and I get some compilation errors, + what is wrong?</A> + </LI> + <LI><A HREF="#glibc-crypt">I'm using RedHat Linux 5.0, or some other + <SAMP>glibc</SAMP>-based Linux system, and I get errors with the + <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</A> + </LI> + </OL> + </LI> + + + + + + + + + + + + + + + + <LI VALUE="4"><STRONG>Error Log Messages and Problems Starting Apache</STRONG> + <OL> + <LI><A HREF="#setgid">Why do I get "<SAMP>setgid: Invalid + argument</SAMP>" at startup?</A> + </LI> + <LI><A HREF="#nodelay">Why am I getting "<SAMP>httpd: could not + set socket option TCP_NODELAY</SAMP>" in my error log?</A> + </LI> + <LI><A HREF="#peerreset">Why am I getting "<SAMP>connection + reset by peer</SAMP>" in my error log?</A> + </LI> + <LI><A HREF="#wheres-the-dump">The errorlog says Apache dumped core, + but where's the dump file?</A> + </LI> + <LI><A HREF="#linux-shmget">When I run it under Linux I get "shmget: + function not found", what should I do?</A> + </LI> + <LI><A HREF="#nfslocking">Server hangs, or fails to start, and/or error log + fills with "<SAMP>fcntl: F_SETLKW: No record locks + available</SAMP>" or similar messages</A> + </LI> + <LI><A HREF="#aixccbug">Why am I getting "<SAMP>Expected </Directory> + but saw </Directory></SAMP>" when I try to start Apache?</A> + </LI> + <LI><A HREF="#redhat">I'm using RedHat Linux and I have problems with httpd + dying randomly or not restarting properly</A> + </LI> + <LI><A HREF="#stopping">I upgraded from an Apache version earlier + than 1.2.0 and suddenly I have problems with Apache dying randomly + or not restarting properly</A> + </LI> + <LI><A HREF="#setservername">When I try to start Apache from a DOS + window, I get a message like "<samp>Cannot determine host name. + Use ServerName directive to set it manually.</samp>" What does + this mean?</A> + </LI> + </OL> + </LI> + + + + + + + + + + + + + + + + <LI VALUE="5"><STRONG>Configuration Questions</STRONG> + <OL> <LI><A HREF="#fdlim">Why can't I run more than <<EM>n</EM>> virtual hosts?</A> </LI> <LI><A HREF="#freebsd-setsize">Can I increase <SAMP>FD_SETSIZE</SAMP> on FreeBSD?</A> </LI> - <LI><A HREF="#POSTnotallowed">Why do I keep getting "Method Not - Allowed" for form POST requests?</A> - </LI> - <LI><A HREF="#passwdauth">Can I use my <SAMP>/etc/passwd</SAMP> file - for Web page authentication?</A> - </LI> <LI><A HREF="#errordoc401">Why doesn't my <CODE>ErrorDocument 401</CODE> work?</A> </LI> - <LI><A HREF="#errordocssi">How can I use <CODE>ErrorDocument</CODE> - and SSI to simplify customized error messages?</A> - </LI> - <LI><A HREF="#setgid">Why do I get "<SAMP>setgid: Invalid - argument</SAMP>" at startup?</A> - </LI> <LI><A HREF="#cookies1">Why does Apache send a cookie on every response?</A> </LI> <LI><A HREF="#cookies2">Why don't my cookies work, I even compiled in @@ -170,66 +288,114 @@ <LI><A HREF="#jdk1-and-http1.1">Why do my Java app[let]s give me plain text when I request an URL from an Apache server?</A> </LI> - <LI><A HREF="#putsupport">Why can't I publish to my Apache server - using PUT on Netscape Gold and other programs?</A> + <LI><A HREF="#midi">How do I get Apache to send a MIDI file so the + browser can play it?</A> </LI> - <LI><A HREF="#fastcgi">Why isn't FastCGI included with Apache any - more?</A> + <LI><A HREF="#addlog">How do I add browsers and referrers to my logs?</A> </LI> - <LI><A HREF="#nodelay">Why am I getting "<SAMP>httpd: could not - set socket option TCP_NODELAY</SAMP>" in my error log?</A> + <LI><A HREF="#set-servername">Why does accessing directories only work + when I include the trailing "/" + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) but + not when I omit it + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</A> </LI> - <LI><A HREF="#peerreset">Why am I getting "<SAMP>connection - reset by peer</SAMP>" in my error log?</A> + <LI><A HREF="#no-info-directives">Why doesn't mod_info list any + directives?</A> + </LI> + <LI><A HREF="#namevhost">I upgraded to Apache 1.3 and now my + virtual hosts don't work!</A> + </LI> + <LI><A HREF="#redhat-htm">I'm using RedHat Linux and my .htm files are + showing up as HTML source rather than being formatted!</A> + </LI> + <LI><A HREF="#htaccess-work">My <CODE>.htaccess</CODE> files are being + ignored.</A> + </LI> + <LI><A HREF="#forbidden">Why do I get a + "<SAMP>Forbidden</SAMP>" message whenever I try to + access a particular directory?</A> + </OL> + </LI> + + + + + + + + + + + + + + + + <LI VALUE="6"><STRONG>Dynamic Content (CGI and SSI)</STRONG> + <OL> + <LI><A HREF="#CGIoutsideScriptAlias">How do I enable CGI execution + in directories other than the ScriptAlias?</A> + </LI> + <LI><A HREF="#premature-script-headers">What does it mean when my + CGIs fail with "<SAMP>Premature end of script + headers</SAMP>"?</A> + </LI> + <LI><A HREF="#POSTnotallowed">Why do I keep getting "Method Not + Allowed" for form POST requests?</A> </LI> <LI><A HREF="#nph-scripts">How can I get my script's output without Apache buffering it? Why doesn't my server push work?</A> </LI> - <LI><A HREF="#linuxiovec">Why do I get complaints about redefinition - of "<CODE>struct iovec</CODE>" when compiling under Linux?</A> + <LI><A HREF="#cgi-spec">Where can I find the "CGI + specification"?</A> </LI> - <LI><A HREF="#wheres-the-dump">The errorlog says Apache dumped core, - but where's the dump file?</A> + <LI><A HREF="#fastcgi">Why isn't FastCGI included with Apache any + more?</A> </LI> - <LI><A HREF="#dnsauth">Why isn't restricting access by host or domain name - working correctly?</A> + <LI><A HREF="#ssi-part-i">How do I enable SSI (parsed HTML)?</A> </LI> - <LI><A HREF="#SSL-i">Why doesn't Apache include SSL?</A> + <LI><A HREF="#ssi-part-ii">Why don't my parsed files get cached?</A> </LI> - <LI><A HREF="#midi">How do I get Apache to send a MIDI file so the - browser can play it?</A> + <LI><A HREF="#ssi-part-iii">How can I have my script output parsed?</A> </LI> - <LI><A HREF="#cantbuild">Why won't Apache compile with my - system's <SAMP>cc</SAMP>?</A> + <LI><A HREF="#ssi-part-iv">SSIs don't work for VirtualHosts and/or + user home directories</A> </LI> - <LI><A HREF="#addlog">How do I add browsers and referrers to my logs?</A> + <LI><A HREF="#errordocssi">How can I use <CODE>ErrorDocument</CODE> + and SSI to simplify customized error messages?</A> </LI> - <LI><A HREF="#bind8.1">Why do I get an error about an undefined - reference to "<SAMP>__inet_ntoa</SAMP>" or other - <SAMP>__inet_*</SAMP> symbols?</A> + <LI><A HREF="#remote-user-var">Why is the environment variable + <SAMP>REMOTE_USER</SAMP> not set?</A> </LI> - <LI><A HREF="#set-servername">Why does accessing directories only work - when I include the trailing "/" - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) but - not when I omit it - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</A> + </OL> + </LI> + + + + + + + + + + + + + + + + <LI VALUE="7"><STRONG>Authentication and Access Restrictions</STRONG> + <OL> + <LI><A HREF="#dnsauth">Why isn't restricting access by host or domain name + working correctly?</A> </LI> <LI><A HREF="#user-authentication">How do I set up Apache to require a username and password to access certain documents?</A> </LI> - <LI><A HREF="#remote-user-var">Why is the environment variable - <SAMP>REMOTE_USER</SAMP> not set?</A> - </LI> <LI><A HREF="#remote-auth-only">How do I set up Apache to allow access to certain documents only if a site is either a local site <EM>or</EM> the user supplies a password and username?</A> </LI> - <LI><A HREF="#no-info-directives">Why doesn't mod_info list any - directives?</A> - </LI> - <LI><A HREF="#linux-shmget">When I run it under Linux I get "shmget: - function not found", what should I do?</A> - </LI> <LI><A HREF="#authauthoritative">Why does my authentication give me a server error?</A> </LI> @@ -238,6 +404,28 @@ </LI> <LI><A HREF="#msql-slow">Why is my mSQL authentication terribly slow?</A> </LI> + <LI><A HREF="#passwdauth">Can I use my <SAMP>/etc/passwd</SAMP> file + for Web page authentication?</A> + </LI> + </OL> + </LI> + + + + + + + + + + + + + + + + <LI VALUE="8"><STRONG>URL Rewriting</STRONG> + <OL> <LI><A HREF="#rewrite-more-config">Where can I find mod_rewrite rulesets which already solve particular URL-related problems?</A> </LI> @@ -262,64 +450,65 @@ <LI><A HREF="#rewrite-envwhitespace">How can I use strings with whitespaces in RewriteRule's ENV flag?</A> </LI> - <LI><A HREF="#cgi-spec">Where can I find the "CGI - specification"?</A> - </LI> - <LI><A HREF="#year2000">Is Apache Year 2000 compliant?</A> - </LI> - <LI><A HREF="#namevhost">I upgraded to Apache 1.3 and now my - virtual hosts don't work!</A> - </LI> - <LI><A HREF="#redhat">I'm using RedHat Linux and I have problems with httpd - dying randomly or not restarting properly</A> - </LI> - <LI><A HREF="#stopping">I upgraded from an Apache version earlier - than 1.2.0 and suddenly I have problems with Apache dying randomly - or not restarting properly</A> - </LI> - <LI><A HREF="#redhat-htm">I'm using RedHat Linux and my .htm files are - showing up as HTML source rather than being formatted!</A> - </LI> - <LI><A HREF="#glibc-crypt">I'm using RedHat Linux 5.0, or some other - <SAMP>glibc</SAMP>-based Linux system, and I get errors with the - <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</A> - </LI> - <LI><A HREF="#nfslocking">Server hangs, or fails to start, and/or error log - fills with "<SAMP>fcntl: F_SETLKW: No record locks - available</SAMP>" or similar messages</A> - </LI> - <LI><A HREF="#zoom">What's the best hardware/operating system/... How do - I get the most out of my Apache Web server?</A> - </LI> - <LI><A HREF="#regex">What are "regular expressions"?</A> - </LI> - <LI><A HREF="#broken-gcc">I'm using gcc and I get some compilation errors, - what is wrong?</A> + </OL> + </LI> + + + + + + + + + + + + + + + + <LI VALUE="9"><STRONG>Features</STRONG> + <OL> + <LI><A HREF="#proxy">Does or will Apache act as a Proxy server?</A> </LI> - <LI><A HREF="#htaccess-work">My <CODE>.htaccess</CODE> files are being - ignored.</A> + <LI><A HREF="#multiviews">What are "multiviews"?</A> </LI> - <LI><A HREF="#submit_patch">How do I submit a patch to the Apache Group?</A> + <LI><A HREF="#putsupport">Why can't I publish to my Apache server + using PUT on Netscape Gold and other programs?</A> </LI> - <LI><A HREF="#aixccbug">Why am I getting "<SAMP>Expected </Directory> - but saw </Directory></SAMP>" when I try to start Apache?</A> + <LI><A HREF="#SSL-i">Why doesn't Apache include SSL?</A> </LI> - <LI><A HREF="#domination">Why has Apache stolen my favourite site's - Internet address?</A> + <LI><A HREF="#footer">How can I attach a footer to my documents + without using SSI?</A> </LI> - <LI><A HREF="#apspam">Why am I getting spam mail from the Apache site?</A> + <LI><A HREF="#search">Does Apache include a search engine?</A> </LI> </OL> </LI> -</UL> + + + + + +</OL> <HR> <H2>The Answers</H2> - <H3> - Background - </H3> -<OL START=1> + + + + + + + + + + + + + <H3>A. Background</H3> +<OL> <LI><A NAME="what"> <STRONG>What is Apache?</STRONG> </A> @@ -400,7 +589,7 @@ <STRONG>How thoroughly tested is Apache?</STRONG> </A> <P> - Apache is run on over 1.2 million Internet servers (as of July 1998). It has + Apache is run on over 3 million Internet servers (as of June 1999). It has been tested thoroughly by both developers and users. The Apache Group maintains rigorous standards before releasing new versions of their server, and our server runs without a hitch on over one half of all @@ -487,8 +676,25 @@ <HR> </LI> </OL> - <H3>Technical Questions</H3> -<OL START=11> + + + + + + + + + + + + + + + + + <H3>B. General Technical Questions</H3> +<OL> + <LI><A NAME="what2do"> <STRONG>"Why can't I ...? Why won't ... work?" What to do in case of problems</STRONG> @@ -533,7 +739,8 @@ </P> </LI> <LI><STRONG>Ask in the <SAMP>comp.infosystems.www.servers.unix</SAMP> - USENET newsgroup</STRONG> + or <SAMP>comp.infosystems.www.servers.ms-windows</SAMP> USENET + newsgroup (as appropriate for the platform you use).</STRONG> <P> A lot of common problems never make it to the bug database because there's already high Q&A traffic about them in the @@ -600,298 +807,619 @@ <HR> </LI> - <LI><A NAME="CGIoutsideScriptAlias"> - <STRONG>How do I enable CGI execution in directories other than - the ScriptAlias?</STRONG> + <LI><A NAME="year2000"> + <STRONG>Is Apache Year 2000 compliant?</STRONG> </A> <P> - Apache recognizes all files in a directory named as a - <A HREF="../mod/mod_alias.html#scriptalias"><SAMP>ScriptAlias</SAMP></A> - as being eligible for execution rather than processing as normal - documents. This applies regardless of the file name, so scripts in a - ScriptAlias directory don't need to be named - "<SAMP>*.cgi</SAMP>" or "<SAMP>*.pl</SAMP>" or - whatever. In other words, <EM>all</EM> files in a ScriptAlias - directory are scripts, as far as Apache is concerned. + Yes, Apache is Year 2000 compliant. </P> <P> - To persuade Apache to execute scripts in other locations, such as in - directories where normal documents may also live, you must tell it how - to recognize them - and also that it's okay to execute them. For - this, you need to use something like the - <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> - directive. + Apache internally never stores years as two digits. + On the HTTP protocol level RFC1123-style addresses are generated + which is the only format a HTTP/1.1-compliant server should + generate. To be compatible with older applications Apache + recognizes ANSI C's <CODE>asctime()</CODE> and + RFC850-/RFC1036-style date formats, too. + The <CODE>asctime()</CODE> format uses four-digit years, + but the RFC850 and RFC1036 date formats only define a two-digit year. + If Apache sees such a date with a value less than 70 it assumes that + the century is <SAMP>20</SAMP> rather than <SAMP>19</SAMP>. </P> <P> - <OL> - <LI>In an appropriate section of your server configuration files, add - a line such as - <P> - <DL> - <DD><CODE>AddHandler cgi-script .cgi</CODE> - </DD> - </DL> - <P></P> - <P> - The server will then recognize that all files in that location (and - its logical descendants) that end in "<SAMP>.cgi</SAMP>" - are script files, not documents. - </P> - </LI> - <LI>Make sure that the directory location is covered by an - <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> - declaration that includes the <SAMP>ExecCGI</SAMP> option. - </LI> - </OL> - <P></P> + Although Apache is Year 2000 compliant, you may still get problems + if the underlying OS has problems with dates past year 2000 + (<EM>e.g.</EM>, OS calls which accept or return year numbers). + Most (UNIX) systems store dates internally as signed 32-bit integers + which contain the number of seconds since 1<SUP>st</SUP> January 1970, so + the magic boundary to worry about is the year 2038 and not 2000. + But modern operating systems shouldn't cause any trouble + at all. + </P> <P> - In some situations, you might not want to actually - allow all files named "<SAMP>*.cgi</SAMP>" to be executable. - Perhaps all you want is to enable a particular file in a normal directory to - be executable. This can be alternatively accomplished - <EM>via</EM> <A HREF="../mod/mod_rewrite.html"><SAMP>mod_rewrite</SAMP></A> - and the following steps: + Users of Apache 1.2.x should upgrade to a current version of Apache 1.3 + (see <A HREF="../new_features_1_3.html#misc">year-2000 improvements in + Apache 1.3</A> for details). </P> + <HR> + </LI> + + <LI><A NAME="submit_patch"> + <STRONG>How do I submit a patch to the Apache Group?</STRONG></A> + <P> + The Apache Group encourages patches from outside developers. There + are 2 main "types" of patches: small bugfixes and general + improvements. Bugfixes should be submitting using the Apache <A + HREF="http://www.apache.org/bug_report.html">bug report page</A>. + Improvements, modifications, and additions should follow the + instructions below. + </P> + <P> + In general, the first course of action is to be a member of the + <SAMP>new-httpd@apache.org</SAMP> mailing list. This indicates to + the Group that you are closely following the latest Apache + developments. Your patch file should be generated using either + '<CODE>diff -c</CODE>' or '<CODE>diff -u</CODE>' against + the latest CVS tree. To submit your patch, send email to + <SAMP>new-httpd@apache.org</SAMP> with a <SAMP>Subject:</SAMP> line + that starts with <SAMP>[PATCH]</SAMP> and includes a general + description of the patch. In the body of the message, the patch + should be clearly described and then included at the end of the + message. If the patch-file is long, you can note a URL to the file + instead of the file itself. Use of MIME enclosures/attachments + should be avoided. + </P> + <P> + Be prepared to respond to any questions about your patches and + possibly defend your code. If your patch results in a lot of + discussion, you may be asked to submit an updated patch that + incorporate all changes and suggestions. + </P> + <HR> + </LI> + + <LI><A NAME="domination"><STRONG>Why has Apache stolen my favourite site's + Internet address?</STRONG></A> + <P> + The simple answer is: "It hasn't." This misconception is usually + caused by the site in question having migrated to the Apache Web + server software, but not having migrated the site's content yet. When + Apache is installed, the default page that gets installed tells the + Webmaster the installation was successful. The expectation is that + this default page will be replaced with the site's real content. + If it doesn't, complain to the Webmaster, not to the Apache project -- + we just make the software and aren't responsible for what people + do (or don't do) with it. + </P> + <HR> + </LI> + + <LI><A NAME="apspam"><STRONG>Why am I getting spam mail from the + Apache site?</STRONG></A> + <P> + The short answer is: "You aren't." Usually when someone thinks the + Apache site is originating spam, it's because they've traced the + spam to a Web site, and the Web site says it's using Apache. See the + <A HREF="#domination">previous FAQ entry</A> for more details on this + phenomenon. + </P> + <P> + No marketing spam originates from the Apache site. The only mail + that comes from the site goes only to addresses that have been + <EM>requested</EM> to receive the mail. + </P> + <HR> + </LI> + + <LI><A NAME="redist"><STRONG>May I include the Apache software on a + CD or other package I'm distributing?</STRONG></A> + <P> + The detailed answer to this question can be found in the + Apache license, which is included in the Apache distribution in + the file <CODE>LICENSE</CODE>. You can also find it on the Web at + <SAMP><<A HREF="http://www.apache.org/LICENSE.txt" + >http://www.apache.org/LICENSE.txt</A>></SAMP>. + </P> + <HR> + </LI> + + <LI><A NAME="zoom"> + <STRONG>What's the best hardware/operating system/... How do + I get the most out of my Apache Web server?</STRONG> + </A> <P> - <OL> - <LI>Locally add to the corresponding <SAMP>.htaccess</SAMP> file a ruleset - similar to this one: - <P> - <DL> - <DD><CODE>RewriteEngine on - <BR> - RewriteBase /~foo/bar/ - <BR> - RewriteRule ^quux\.cgi$ - [T=application/x-httpd-cgi]</CODE> - </DD> - </DL> - <P></P> - </LI> - <LI>Make sure that the directory location is covered by an - <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> - declaration that includes the <SAMP>ExecCGI</SAMP> and - <SAMP>FollowSymLinks</SAMP> option. - </LI> - </OL> - <P></P> + Check out Dean Gaudet's + <A HREF="http://www.apache.org/docs/misc/perf-tuning.html" + >performance tuning page</A>. + </P> <HR> </LI> - <LI><A NAME="premature-script-headers"> - <STRONG>What does it mean when my CGIs fail with - "<SAMP>Premature end of script headers</SAMP>"?</STRONG> + <LI><A NAME="regex"> + <STRONG>What are "regular expressions"?</STRONG></A> + <P> + Regular expressions are a way of describing a pattern - for example, "all + the words that begin with the letter A" or "every 10-digit phone number" + or even "Every sentence with two commas in it, and no capital letter Q". + Regular expressions (aka "regexp"s) are useful in Apache because they + let you apply certain attributes against collections of files or resources + in very flexible ways - for example, all .gif and .jpg files under + any "images" directory could be written as /.*\/images\/.*[jpg|gif]/. + </P> + <P> + The best overview around is probably the one which comes with Perl. + We implement a simple subset of Perl's regexp support, but it's + still a good way to learn what they mean. You can start by going + to the <A + HREF="http://www.perl.com/CPAN-local/doc/manual/html/pod/perlre.html#Version_8_Regular_Expresions" + >CPAN page on regular expressions</A>, and branching out from + there. + </P> + <HR> + </LI> +</OL> + + + + + + + + + + + + + + + + + <H3>C. Building Apache</H3> +<OL> + + <LI><A NAME="bind8.1"> + <STRONG>Why do I get an error about an undefined reference to + "<SAMP>__inet_ntoa</SAMP>" or other + <SAMP>__inet_*</SAMP> symbols?</STRONG> </A> <P> - It means just what it says: the server was expecting a complete set of - HTTP headers (one or more followed by a blank line), and didn't get - them. + If you have installed <A HREF="http://www.isc.org/bind.html">BIND-8</A> + then this is normally due to a conflict between your include files + and your libraries. BIND-8 installs its include files and libraries + <CODE>/usr/local/include/</CODE> and <CODE>/usr/local/lib/</CODE>, while + the resolver that comes with your system is probably installed in + <CODE>/usr/include/</CODE> and <CODE>/usr/lib/</CODE>. If + your system uses the header files in <CODE>/usr/local/include/</CODE> + before those in <CODE>/usr/include/</CODE> but you do not use the new + resolver library, then the two versions will conflict. </P> <P> - The most common cause of this problem is the script dying before - sending the complete set of headers, or possibly any at all, to the - server. To see if this is the case, try running the script standalone - from an interactive session, rather than as a script under the server. - If you get error messages, this is almost certainly the cause of the - "premature end of script headers" message. + To resolve this, you can either make sure you use the include files + and libraries that came with your system or make sure to use the + new include files and libraries. Adding <CODE>-lbind</CODE> to the + <CODE>EXTRA_LDFLAGS</CODE> line in your <SAMP>Configuration</SAMP> + file, then re-running <SAMP>Configure</SAMP>, should resolve the + problem. (Apache versions 1.2.* and earlier use + <CODE>EXTRA_LFLAGS</CODE> instead.) </P> <P> - The second most common cause of this (aside from people not - outputting the required headers at all) is a result of an interaction - with Perl's output buffering. To make Perl flush its buffers - after each output statement, insert the following statements around - the <CODE>print</CODE> or <CODE>write</CODE> statements that send your - HTTP headers: + <STRONG>Note:</STRONG>As of BIND 8.1.1, the bind libraries and files are + installed under <SAMP>/usr/local/bind</SAMP> by default, so you + should not run into this problem. Should you want to use the bind + resolvers you'll have to add the following to the respective lines: </P> <P> <DL> - <DD><CODE>{<BR> - local ($oldbar) = $|;<BR> - $cfh = select (STDOUT);<BR> - $| = 1;<BR> - #<BR> - # print your HTTP headers here<BR> - #<BR> - $| = $oldbar;<BR> - select ($cfh);<BR> - }</CODE> + <DD><CODE>EXTRA_CFLAGS=-I/usr/local/bind/include + <BR> + EXTRA_LDFLAGS=-L/usr/local/bind/lib + <BR> + EXTRA_LIBS=-lbind</CODE> </DD> </DL> <P></P> + <HR> + </LI> + + <LI><A NAME="cantbuild"> + <STRONG>Why won't Apache compile with my system's + <SAMP>cc</SAMP>?</STRONG> + </A> <P> - This is generally only necessary when you are calling external - programs from your script that send output to stdout, or if there will - be a long delay between the time the headers are sent and the actual - content starts being emitted. To maximize performance, you should - turn buffer-flushing back <EM>off</EM> (with <CODE>$| = 0</CODE> or the - equivalent) after the statements that send the headers, as displayed - above. - </P> - <P> - If your script isn't written in Perl, do the equivalent thing for - whatever language you <EM>are</EM> using (<EM>e.g.</EM>, for C, call - <CODE>fflush()</CODE> after writing the headers). + If the server won't compile on your system, it is probably due to one + of the following causes: </P> + <UL> + <LI><STRONG>The <SAMP>Configure</SAMP> script doesn't recognize your system + environment.</STRONG> + <BR> + This might be either because it's completely unknown or because + the specific environment (include files, OS version, <EM>et + cetera</EM>) isn't explicitly handled. If this happens, you may + need to port the server to your OS yourself. + </LI> + <LI><STRONG>Your system's C compiler is garbage.</STRONG> + <BR> + Some operating systems include a default C compiler that is either + not ANSI C-compliant or suffers from other deficiencies. The usual + recommendation in cases like this is to acquire, install, and use + <SAMP>gcc</SAMP>. + </LI> + <LI><STRONG>Your <SAMP>include</SAMP> files may be confused.</STRONG> + <BR> + In some cases, we have found that a compiler installation or system + upgrade has left the C header files in an inconsistent state. Make + sure that your include directory tree is in sync with the compiler and + the operating system. + </LI> + <LI><STRONG>Your operating system or compiler may be out of + revision.</STRONG> + <BR> + Software vendors (including those that develop operating systems) + issue new releases for a reason; sometimes to add functionality, but + more often to fix bugs that have been discovered. Try upgrading + your compiler and/or your operating system. + </LI> + </UL> <P> - Another cause for the "premature end of script headers" - message are the RLimitCPU and RLimitMEM directives. You may - get the message if the CGI script was killed due to a - resource limit. + The Apache Group tests the ability to build the server on many + different platforms. Unfortunately, we can't test all of the OS + platforms there are. If you have verified that none of the above + issues is the cause of your problem, and it hasn't been reported + before, please submit a + <A HREF="http://www.apache.org/bug_report.html">problem report</A>. + Be sure to include <EM>complete</EM> details, such as the compiler + & OS versions and exact error messages. </P> <HR> </LI> - <LI><A NAME="ssi-part-i"> - <STRONG>How do I enable SSI (parsed HTML)?</STRONG> + <LI><A NAME="linuxiovec"> + <STRONG>Why do I get complaints about redefinition + of "<CODE>struct iovec</CODE>" when + compiling under Linux?</STRONG> </A> <P> - SSI (an acronym for Server-Side Include) directives allow static HTML - documents to be enhanced at run-time (<EM>e.g.</EM>, when delivered to - a client by Apache). The format of SSI directives is covered - in the <A HREF="../mod/mod_include.html">mod_include manual</A>; - suffice it to say that Apache supports not only SSI but - xSSI (eXtended SSI) directives. - </P> - <P> - Processing a document at run-time is called <EM>parsing</EM> it; hence - the term "parsed HTML" sometimes used for documents that - contain SSI instructions. Parsing tends to be <EM>extremely</EM> - resource-consumptive, and is not enabled by default. It can also - interfere with the cachability of your documents, which can put a - further load on your server. (see the - <A HREF="#ssi-part-ii">next question</A> for more information about this.) + This is a conflict between your C library includes and your kernel + includes. You need to make sure that the versions of both are matched + properly. There are two workarounds, either one will solve the problem: </P> <P> - To enable SSI processing, you need to - </P> <UL> - <LI>Build your server with the - <A HREF="../mod/mod_include.html"><SAMP>mod_include</SAMP></A> - module. This is normally compiled in by default. + <LI>Remove the definition of <CODE>struct iovec</CODE> from your C + library includes. It is located in <CODE>/usr/include/sys/uio.h</CODE>. + <STRONG>Or,</STRONG> </LI> - <LI>Make sure your server configuration files have an - <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> - directive which permits <SAMP>Includes</SAMP>. + <LI>Add <CODE>-DNO_WRITEV</CODE> to the <CODE>EXTRA_CFLAGS</CODE> + line in your <SAMP>Configuration</SAMP> and reconfigure/rebuild. + This hurts performance and should only be used as a last resort. </LI> - <LI>Make sure that the directory where you want the SSI documents to - live is covered by the "server-parsed" content handler, - either explicitly or in some ancestral location. That can be done - with the following - <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> - directive: + </UL> + <P></P> + <HR> + </LI> + + <LI><A NAME="broken-gcc"><STRONG>I'm using gcc and I get some + compilation errors, what is wrong?</STRONG></A> <P> - <DL> - <DD><CODE>AddHandler server-parsed .shtml</CODE> - </DD> - </DL> - <P></P> + GCC parses your system header files and produces a modified subset which + it uses for compiling. This behaviour ties GCC tightly to the version + of your operating system. So, for example, if you were running IRIX 5.3 + when you built GCC and then upgrade to IRIX 6.2 later, you will have to + rebuild GCC. Similarly for Solaris 2.4, 2.5, or 2.5.1 when you upgrade + to 2.6. Sometimes you can type "gcc -v" and it will tell you the version + of the operating system it was built against. + </P> <P> - This indicates that all files ending in ".shtml" in that - location (or its descendants) should be parsed. Note that using - ".html" will cause all normal HTML files to be parsed, - which may put an inordinate load on your server. + If you fail to do this, then it is very likely that Apache will fail + to build. One of the most common errors is with <CODE>readv</CODE>, + <CODE>writev</CODE>, or <CODE>uio.h</CODE>. This is <STRONG>not</STRONG> a + bug with Apache. You will need to re-install GCC. </P> - </LI> - </UL> + <HR> + </LI> + + <LI><A NAME="glibc-crypt"> + <STRONG>I'm using RedHat Linux 5.0, or some other + <SAMP>glibc</SAMP>-based Linux system, and I get errors with the + <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</STRONG> + </A> + <P> - For additional information, see the <CITE>Apache Week</CITE> article on - <A HREF="http://www.apacheweek.com/features/ssi" REL="Help" - ><CITE>Using Server Side Includes</CITE></A>. + <SAMP>glibc</SAMP> puts the <CODE>crypt</CODE> function into a separate + library. Edit your <CODE>src/Configuration</CODE> file and set this: + </P> + <DL> + <DD><CODE>EXTRA_LIBS=-lcrypt</CODE> + </DD> + </DL> + <P> + Then re-run <SAMP>src/Configure</SAMP> and re-execute the make. </P> <HR> </LI> - <LI><A NAME="ssi-part-ii"> - <STRONG>Why don't my parsed files get cached?</STRONG> +</OL> + + + + + + + + + + + + + + + + + <H3>D. Error Log Messages and Problems Starting Apache</H3> +<OL> + + <LI><A NAME="setgid"> + <STRONG>Why do I get "<SAMP>setgid: Invalid + argument</SAMP>" at startup?</STRONG> </A> <P> - Since the server is performing run-time processing of your SSI - directives, which may change the content shipped to the client, it - can't know at the time it starts parsing what the final size of the - result will be, or whether the parsed result will always be the same. - This means that it can't generate <SAMP>Content-Length</SAMP> or - <SAMP>Last-Modified</SAMP> headers. Caches commonly work by comparing - the <SAMP>Last-Modified</SAMP> of what's in the cache with that being - delivered by the server. Since the server isn't sending that header - for a parsed document, whatever's doing the caching can't tell whether - the document has changed or not - and so fetches it again to be on the - safe side. + Your + <A HREF="../mod/core.html#group"><SAMP>Group</SAMP></A> + directive (probably in <SAMP>conf/httpd.conf</SAMP>) needs to name a + group that actually exists in the <SAMP>/etc/group</SAMP> file (or + your system's equivalent). This problem is also frequently seen when + a negative number is used in the <CODE>Group</CODE> directive + (<EM>e.g.</EM>, "<CODE>Group #-1</CODE>"). Using a group name + -- not group number -- found in your system's group database should + solve this problem in all cases. </P> + <HR> + </LI> + + <LI><A NAME="nodelay"> + <STRONG>Why am I getting "<SAMP>httpd: could not set socket + option TCP_NODELAY</SAMP>" in my error log?</STRONG> + </A> <P> - You can work around this in some cases by causing an - <SAMP>Expires</SAMP> header to be generated. (See the - <A HREF="../mod/mod_expires.html" REL="Help"><SAMP>mod_expires</SAMP></A> - documentation for more details.) Another possibility is to use the - <A HREF="../mod/mod_include.html#xbithack" REL="Help" - ><SAMP>XBitHack Full</SAMP></A> - mechanism, which tells Apache to send (under certain circumstances - detailed in the XBitHack directive description) a - <SAMP>Last-Modified</SAMP> header based upon the last modification - time of the file being parsed. Note that this may actually be lying - to the client if the parsed file doesn't change but the SSI-inserted - content does; if the included content changes often, this can result - in stale copies being cached. + This message almost always indicates that the client disconnected + before Apache reached the point of calling <CODE>setsockopt()</CODE> + for the connection. It shouldn't occur for more than about 1% of the + requests your server handles, and it's advisory only in any case. </P> <HR> </LI> - <LI><A NAME="ssi-part-iii"> - <STRONG>How can I have my script output parsed?</STRONG> + <LI><A NAME="peerreset"> + <STRONG>Why am I getting "<SAMP>connection reset by + peer</SAMP>" in my error log?</STRONG> </A> <P> - So you want to include SSI directives in the output from your CGI - script, but can't figure out how to do it? - The short answer is "you can't." This is potentially - a security liability and, more importantly, it can not be cleanly - implemented under the current server API. The best workaround - is for your script itself to do what the SSIs would be doing. - After all, it's generating the rest of the content. + This is a normal message and nothing about which to be alarmed. It simply + means that the client canceled the connection before it had been + completely set up - such as by the end-user pressing the "Stop" + button. People's patience being what it is, sites with response-time + problems or slow network links may experiences this more than + high-capacity ones or those with large pipes to the network. </P> + <HR> + </LI> + + <LI><A NAME="wheres-the-dump"> + <STRONG>The errorlog says Apache dumped core, but where's the dump + file?</STRONG> + </A> <P> - This is a feature The Apache Group hopes to add in the next major - release after 1.3. + In Apache version 1.2, the error log message + about dumped core includes the directory where the dump file should be + located. However, many Unixes do not allow a process that has + called <CODE>setuid()</CODE> to dump core for security reasons; + the typical Apache setup has the server started as root to bind to + port 80, after which it changes UIDs to a non-privileged user to + serve requests. + </P> + <P> + Dealing with this is extremely operating system-specific, and may + require rebuilding your system kernel. Consult your operating system + documentation or vendor for more information about whether your system + does this and how to bypass it. If there <EM>is</EM> a documented way + of bypassing it, it is recommended that you bypass it only for the + <SAMP>httpd</SAMP> server process if possible. + </P> + <P> + The canonical location for Apache's core-dump files is the + <A HREF="../mod/core.html#serverroot">ServerRoot</A> + directory. As of Apache version 1.3, the location can be set <EM>via</EM> + the + <A HREF="../mod/core.html#coredumpdirectory" + ><SAMP>CoreDumpDirectory</SAMP></A> + directive to a different directory. Make sure that this directory is + writable by the user the server runs as (as opposed to the user the server + is <EM>started</EM> as). </P> <HR> </LI> - <LI><A NAME="ssi-part-iv"> - <STRONG>SSIs don't work for VirtualHosts and/or - user home directories.</STRONG> + <LI><A NAME="linux-shmget"> + <STRONG>When I run it under Linux I get "shmget: + function not found", what should I do?</STRONG> </A> <P> - This is almost always due to having some setting in your config file that - sets "Options Includes" or some other setting for your DocumentRoot - but not for other directories. If you set it inside a Directory - section, then that setting will only apply to that directory. + Your kernel has been built without SysV IPC support. You will have + to rebuild the kernel with that support enabled (it's under the + "General Setup" submenu). Documentation for kernel + building is beyond the scope of this FAQ; you should consult the <A + HREF="http://www.linuxhq.com/HOWTO/Kernel-HOWTO.html" >Kernel + HOWTO</A>, or the documentation provided with your distribution, or + a <A HREF="http://www.linuxhq.com/HOWTO/META-FAQ.html" >Linux + newsgroup/mailing list</A>. As a last-resort workaround, you can + comment out the <CODE>#define USE_SHMGET_SCOREBOARD</CODE> + definition in the <SAMP>LINUX</SAMP> section of + <SAMP>src/conf.h</SAMP> and rebuild the server (prior to 1.3b4, + simply removing <CODE>#define HAVE_SHMGET</CODE> would have + sufficed). This will produce a server which is slower and less + reliable. </P> + <HR> </LI> - <LI><A NAME="proxy"> - <STRONG>Does or will Apache act as a Proxy server?</STRONG> + <LI><A NAME="nfslocking"> + <STRONG>Server hangs, or fails to start, and/or error log + fills with "<SAMP>fcntl: F_SETLKW: No record locks + available</SAMP>" or similar messages</STRONG> </A> + <P> - Apache version 1.1 and above comes with a - <A HREF="../mod/mod_proxy.html">proxy module</A>. - If compiled in, this will make Apache act as a caching-proxy server. + These are symptoms of a fine locking problem, which usually means that + the server is trying to use a synchronization file on an NFS filesystem. + </P> + <P> + Because of its parallel-operation model, the Apache Web server needs to + provide some form of synchronization when accessing certain resources. + One of these synchronization methods involves taking out locks on a file, + which means that the filesystem whereon the lockfile resides must support + locking. In many cases this means it <EM>can't</EM> be kept on an + NFS-mounted filesystem. + </P> + <P> + To cause the Web server to work around the NFS locking limitations, include + a line such as the following in your server configuration files: + </P> + <DL> + <DD><CODE>LockFile /var/run/apache-lock</CODE> + </DD> + </DL> + <P> + The directory should not be generally writable (<EM>e.g.</EM>, don't use + <SAMP>/var/tmp</SAMP>). + See the <A HREF="../mod/core.html#lockfile"><SAMP>LockFile</SAMP></A> + documentation for more information. </P> <HR> </LI> - <LI><A NAME="multiviews"> - <STRONG>What are "multiviews"?</STRONG> + <LI><A NAME="aixccbug"><STRONG>Why am I getting "<SAMP>Expected + </Directory> but saw </Directory></SAMP>" when + I try to start Apache?</STRONG></A> + <P> + This is a known problem with certain versions of the AIX C compiler. + IBM are working on a solution, and the issue is being tracked by + <A HREF="http://bugs.apache.org/index/full/2312">problem report #2312</A>. + </P> + <HR> + </LI> + + <LI><A NAME="redhat"> + <STRONG>I'm using RedHat Linux and I have problems with httpd + dying randomly or not restarting properly</STRONG> </A> + <P> - "Multiviews" is the general name given to the Apache - server's ability to provide language-specific document variants in - response to a request. This is documented quite thoroughly in the - <A HREF="../content-negotiation.html" REL="Help">content negotiation</A> - description page. In addition, <CITE>Apache Week</CITE> carried an - article on this subject entitled - "<A HREF="http://www.apacheweek.com/features/negotiation" REL="Help" - ><CITE>Content Negotiation Explained</CITE></A>". + RedHat Linux versions 4.x (and possibly earlier) RPMs contain + various nasty scripts which do not stop or restart Apache properly. + These can affect you even if you're not running the RedHat supplied + RPMs. + </P> + <P> + If you're using the default install then you're probably running + Apache 1.1.3, which is outdated. From RedHat's ftp site you can + pick up a more recent RPM for Apache 1.2.x. This will solve one of + the problems. + </P> + <P> + If you're using a custom built Apache rather than the RedHat RPMs + then you should <CODE>rpm -e apache</CODE>. In particular you want + the mildly broken <CODE>/etc/logrotate.d/apache</CODE> script to be + removed, and you want the broken <CODE>/etc/rc.d/init.d/httpd</CODE> + (or <CODE>httpd.init</CODE>) script to be removed. The latter is + actually fixed by the apache-1.2.5 RPMs but if you're building your + own Apache then you probably don't want the RedHat files. + </P> + <P> + We can't stress enough how important it is for folks, <EM>especially + vendors</EM> to follow the <A HREF="../stopping.html">stopping Apache + directions</A> given in our documentation. In RedHat's defense, + the broken scripts were necessary with Apache 1.1.x because the + Linux support in 1.1.x was very poor, and there were various race + conditions on all platforms. None of this should be necessary with + Apache 1.2 and later. </P> <HR> </LI> + <LI><A NAME="stopping"> + <STRONG>I upgraded from an Apache version earlier + than 1.2.0 and suddenly I have problems with Apache dying randomly + or not restarting properly</STRONG> + </A> + + <P> + You should read <A HREF="#redhat">the previous note</A> about + problems with RedHat installations. It is entirely likely that your + installation has start/stop/restart scripts which were built for + an earlier version of Apache. Versions earlier than 1.2.0 had + various race conditions that made it necessary to use + <CODE>kill -9</CODE> at times to take out all the httpd servers. + But that should not be necessary any longer. You should follow + the <A HREF="../stopping.html">directions on how to stop + and restart Apache</A>. + </P> + <P>As of Apache 1.3 there is a script + <CODE>src/support/apachectl</CODE> which, after a bit of + customization, is suitable for starting, stopping, and restarting + your server. + </P> + <HR> + </LI> + + <LI><A name="setservername"> + <b>When I try to start Apache from a DOS + window, I get a message like "<samp>Cannot determine host name. + Use ServerName directive to set it manually.</samp>" What does + this mean?</b></A> + + <p> + It means what it says; the Apache software can't determine the + hostname of your system. Edit your <samp>conf\httpd.conf</samp> + file, look for the string "ServerName", and make sure there's an + uncommented directive such as + </p> + <dl> + <dd><code>ServerName localhost</code></dd> + </dl> + <p> + or + </p> + <dl> + <dd><code>ServerName www.foo.com</code></dd> + </dl> + <p> + in the file. Correct it if there one there with wrong information, or + add one if you don't already have one. Then try to start the server + again. + </p> + <hr> + </LI> + +</OL> + + + + + + + + + + + + + + + + + <H3>E. Configuration Questions</H3> +<OL> + <LI><A NAME="fdlim"> <STRONG>Why can't I run more than <<EM>n</EM>> virtual hosts?</STRONG> @@ -1024,76 +1552,6 @@ <HR> </LI> - <LI><A NAME="POSTnotallowed"> - <STRONG>Why do I keep getting "Method Not Allowed" for - form POST requests?</STRONG> - </A> - <P> - This is almost always due to Apache not being configured to treat the - file you are trying to POST to as a CGI script. You can not POST - to a normal HTML file; the operation has no meaning. See the FAQ - entry on <A HREF="#CGIoutsideScriptAlias">CGIs outside ScriptAliased - directories</A> for details on how to configure Apache to treat the - file in question as a CGI. - </P> - <HR> - </LI> - - <LI><A NAME="passwdauth"> - <STRONG>Can I use my <SAMP>/etc/passwd</SAMP> file - for Web page authentication?</STRONG> - </A> - <P> - Yes, you can - but it's a <STRONG>very bad idea</STRONG>. Here are - some of the reasons: - </P> - <UL> - <LI>The Web technology provides no governors on how often or how - rapidly password (authentication failure) retries can be made. That - means that someone can hammer away at your system's - <SAMP>root</SAMP> password using the Web, using a dictionary or - similar mass attack, just as fast as the wire and your server can - handle the requests. Most operating systems these days include - attack detection (such as <EM>n</EM> failed passwords for the same - account within <EM>m</EM> seconds) and evasion (breaking the - connection, disabling the account under attack, disabling - <EM>all</EM> logins from that source, <EM>et cetera</EM>), but the - Web does not. - </LI> - <LI>An account under attack isn't notified (unless the server is - heavily modified); there's no "You have 19483 login - failures" message when the legitimate owner logs in. - </LI> - <LI>Without an exhaustive and error-prone examination of the server - logs, you can't tell whether an account has been compromised. - Detecting that an attack has occurred, or is in progress, is fairly - obvious, though - <EM>if</EM> you look at the logs. - </LI> - <LI>Web authentication passwords (at least for Basic authentication) - generally fly across the wire, and through intermediate proxy - systems, in what amounts to plain text. "O'er the net we - go/Caching all the way;/O what fun it is to surf/Giving my password - away!" - </LI> - <LI>Since HTTP is stateless, information about the authentication is - transmitted <EM>each and every time</EM> a request is made to the - server. Essentially, the client caches it after the first - successful access, and transmits it without asking for all - subsequent requests to the same server. - </LI> - <LI>It's relatively trivial for someone on your system to put up a - page that will steal the cached password from a client's cache - without them knowing. Can you say "password grabber"? - </LI> - </UL> - <P> - If you still want to do this in light of the above disadvantages, the - method is left as an exercise for the reader. It'll void your Apache - warranty, though, and you'll lose all accumulated UNIX guru points. - </P> - <HR> - </LI> - <LI><A NAME="errordoc401"> <STRONG>Why doesn't my <CODE>ErrorDocument 401</CODE> work?</STRONG> </A> @@ -1107,39 +1565,11 @@ <HR> </LI> - <LI><A NAME="errordocssi"> - <STRONG>How can I use <CODE>ErrorDocument</CODE> - and SSI to simplify customized error messages?</STRONG> - </A> - <P> - Have a look at <A HREF="custom_errordocs.html">this document</A>. - It shows in example form how you can a combination of XSSI and - negotiation to tailor a set of <CODE>ErrorDocument</CODE>s to your - personal taste, and returning different internationalized error - responses based on the client's native language. - </P> - <HR> - </LI> - - <LI><A NAME="setgid"> - <STRONG>Why do I get "<SAMP>setgid: Invalid - argument</SAMP>" at startup?</STRONG> - </A> - <P> - Your - <A HREF="../mod/core.html#group"><SAMP>Group</SAMP></A> - directive (probably in <SAMP>conf/httpd.conf</SAMP>) needs to name a - group that actually exists in the <SAMP>/etc/group</SAMP> file (or - your system's equivalent). - </P> - <HR> - </LI> - <LI><A NAME="cookies1"> <STRONG>Why does Apache send a cookie on every response?</STRONG> </A> <P> - Apache does <EM>not</EM> send automatically send a cookie on every + Apache does <EM>not</EM> automatically send a cookie on every response, unless you have re-compiled it with the <A HREF="../mod/mod_usertrack.html"><SAMP>mod_usertrack</SAMP></A> module, and specifically enabled it with the @@ -1224,437 +1654,618 @@ <HR> </LI> - <LI><A NAME="putsupport"> - <STRONG>Why can't I publish to my Apache server using PUT on - Netscape Gold and other programs?</STRONG> + <LI><A NAME="midi"> + <STRONG>How do I get Apache to send a MIDI file so the browser can + play it?</STRONG> </A> <P> - Because you need to install and configure a script to handle - the uploaded files. This script is often called a "PUT" handler. - There are several available, but they may have security problems. - Using FTP uploads may be easier and more secure, at least for now. - For more information, see the <CITE>Apache Week</CITE> article - <A HREF="http://www.apacheweek.com/features/put" - ><CITE>Publishing Pages with PUT</CITE></A>. + Even though the registered MIME type for MIDI files is + <SAMP>audio/midi</SAMP>, some browsers are not set up to recognize it + as such; instead, they look for <SAMP>audio/x-midi</SAMP>. There are + two things you can do to address this: </P> + <OL> + <LI>Configure your browser to treat documents of type + <SAMP>audio/midi</SAMP> correctly. This is the type that Apache + sends by default. This may not be workable, however, if you have + many client installations to change, or if some or many of the + clients are not under your control. + </LI> + <LI>Instruct Apache to send a different <SAMP>Content-type</SAMP> + header for these files by adding the following line to your server's + configuration files: + <P> + <DL> + <DD><CODE>AddType audio/x-midi .mid .midi .kar</CODE> + </DD> + </DL> + <P></P> + <P> + Note that this may break browsers that <EM>do</EM> recognize the + <SAMP>audio/midi</SAMP> MIME type unless they're prepared to also + handle <SAMP>audio/x-midi</SAMP> the same way. + </P> + </LI> + </OL> <HR> </LI> - <LI><A NAME="fastcgi"> - <STRONG>Why isn't FastCGI included with Apache any more?</STRONG> + <LI><A NAME="addlog"> + <STRONG>How do I add browsers and referrers to my logs?</STRONG> </A> <P> - The simple answer is that it was becoming too difficult to keep the - version being included with Apache synchronized with the master copy - at the - <A HREF="http://www.fastcgi.com/" - >FastCGI web site</A>. When a new version of Apache was released, the - version of the FastCGI module included with it would soon be out of date. + Apache provides a couple of different ways of doing this. The + recommended method is to compile the + <A HREF="../mod/mod_log_config.html"><SAMP>mod_log_config</SAMP></A> + module into your configuration and use the + <A HREF="../mod/mod_log_config.html#customlog"><SAMP>CustomLog</SAMP></A> + directive. </P> <P> - You can still obtain the FastCGI module for Apache from the master - FastCGI web site. + You can either log the additional information in files other than your + normal transfer log, or you can add them to the records already being + written. For example: + </P> + <P> + <CODE> + CustomLog logs/access_log "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"" + </CODE> + </P> + <P> + This will add the values of the <SAMP>User-agent:</SAMP> and + <SAMP>Referer:</SAMP> headers, which indicate the client and the + referring page, respectively, to the end of each line in the access + log. + </P> + <P> + You may want to check out the <CITE>Apache Week</CITE> article + entitled: + "<A HREF="http://www.apacheweek.com/features/logfiles" REL="Help" + ><CITE>Gathering Visitor Information: Customizing Your + Logfiles</CITE></A>". </P> <HR> </LI> - <LI><A NAME="nodelay"> - <STRONG>Why am I getting "<SAMP>httpd: could not set socket - option TCP_NODELAY</SAMP>" in my error log?</STRONG> + <LI><A NAME="set-servername"> + <STRONG>Why does accessing directories only work when I include + the trailing "/" + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) + but not when I omit it + (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</STRONG> </A> <P> - This message almost always indicates that the client disconnected - before Apache reached the point of calling <CODE>setsockopt()</CODE> - for the connection. It shouldn't occur for more than about 1% of the - requests your server handles, and it's advisory only in any case. + When you access a directory without a trailing "/", Apache needs + to send what is called a redirect to the client to tell it to + add the trailing slash. If it did not do so, relative URLs would + not work properly. When it sends the redirect, it needs to know + the name of the server so that it can include it in the redirect. + There are two ways for Apache to find this out; either it can guess, + or you can tell it. If your DNS is configured correctly, it can + normally guess without any problems. If it is not, however, then + you need to tell it. + </P> + <P> + Add a <A HREF="../mod/core.html#servername">ServerName</A> directive + to the config file to tell it what the domain name of the server is. </P> <HR> </LI> - <LI><A NAME="peerreset"> - <STRONG>Why am I getting "<SAMP>connection reset by - peer</SAMP>" in my error log?</STRONG> + <LI><A NAME="no-info-directives"> + <STRONG>Why doesn't mod_info list any directives?</STRONG> </A> <P> - This is a normal message and nothing about which to be alarmed. It simply - means that the client canceled the connection before it had been - completely set up - such as by the end-user pressing the "Stop" - button. People's patience being what it is, sites with response-time - problems or slow network links may experiences this more than - high-capacity ones or those with large pipes to the network. + The <A HREF="../mod/mod_info.html"><SAMP>mod_info</SAMP></A> + module allows you to use a Web browser to see how your server is + configured. Among the information it displays is the list modules and + their configuration directives. The "current" values for + the directives are not necessarily those of the running server; they + are extracted from the configuration files themselves at the time of + the request. If the files have been changed since the server was last + reloaded, the display will will not match the values actively in use. + If the files and the path to the files are not readable by the user as + which the server is running (see the + <A HREF="../mod/core.html#user"><SAMP>User</SAMP></A> + directive), then <SAMP>mod_info</SAMP> cannot read them in order to + list their values. An entry <EM>will</EM> be made in the error log in + this event, however. </P> <HR> </LI> - <LI><A NAME="nph-scripts"> - <STRONG>How can I get my script's output without Apache buffering - it? Why doesn't my server push work?</STRONG> + <LI><A NAME="namevhost"> + <STRONG>I upgraded to Apache 1.3 and now my virtual hosts don't + work!</STRONG> </A> <P> - As of Apache 1.3, CGI scripts are essentially not buffered. Every time - your script does a "flush" to output data, that data gets relayed on to - the client. Some scripting languages, for example Perl, have their own - buffering for output - this can be disabled by setting the <CODE>$|</CODE> - special variable to 1. Of course this does increase the overall number - of packets being transmitted, which can result in a sense of slowness for - the end user. + In versions of Apache prior to 1.3b2, there was a lot of confusion + regarding address-based virtual hosts and (HTTP/1.1) name-based + virtual hosts, and the rules concerning how the server processed + <SAMP><VirtualHost></SAMP> definitions were very complex and not + well documented. </P> - <P>Prior to 1.3, you needed to use "nph-" scripts to accomplish non-buffering. - Today, the only difference between nph scripts and normal scripts is - that nph scripts require the full HTTP headers to be sent. + <P> + Apache 1.3b2 introduced a new directive, + <A HREF="http://www.apache.org/docs/mod/core.html#namevirtualhost" + ><SAMP>NameVirtualHost</SAMP></A>, + which simplifies the rules quite a bit. However, changing the rules + like this means that your existing name-based + <SAMP><VirtualHost></SAMP> containers probably won't work + correctly immediately following the upgrade. </P> - <HR> - </LI> - - <LI><A NAME="linuxiovec"> - <STRONG>Why do I get complaints about redefinition - of "<CODE>struct iovec</CODE>" when - compiling under Linux?</STRONG> - </A> <P> - This is a conflict between your C library includes and your kernel - includes. You need to make sure that the versions of both are matched - properly. There are two workarounds, either one will solve the problem: + To correct this problem, add the following line to the beginning of + your server configuration file, before defining any virtual hosts: </P> + <DL> + <DD><CODE>NameVirtualHost <EM>n.n.n.n</EM></CODE> + </DD> + </DL> <P> - <UL> - <LI>Remove the definition of <CODE>struct iovec</CODE> from your C - library includes. It is located in <CODE>/usr/include/sys/uio.h</CODE>. - <STRONG>Or,</STRONG> - </LI> - <LI>Add <CODE>-DNO_WRITEV</CODE> to the <CODE>EXTRA_CFLAGS</CODE> - line in your <SAMP>Configuration</SAMP> and reconfigure/rebuild. - This hurts performance and should only be used as a last resort. - </LI> - </UL> - <P></P> + Replace the "<SAMP>n.n.n.n</SAMP>" with the IP address to + which the name-based virtual host names resolve; if you have multiple + name-based hosts on multiple addresses, repeat the directive for each + address. + </P> + <P> + Make sure that your name-based <SAMP><VirtualHost></SAMP> blocks + contain <SAMP>ServerName</SAMP> and possibly <SAMP>ServerAlias</SAMP> + directives so Apache can be sure to tell them apart correctly. + </P> + <P> + Please see the + <A HREF="http://www.apache.org/docs/vhosts/">Apache + Virtual Host documentation</A> for further details about configuration. + </P> <HR> </LI> - <LI><A NAME="wheres-the-dump"> - <STRONG>The errorlog says Apache dumped core, but where's the dump - file?</STRONG> + <LI><A NAME="redhat-htm"> + <STRONG>I'm using RedHat Linux and my .htm files are showing + up as HTML source rather than being formatted!</STRONG> </A> + <P> - In Apache version 1.2, the error log message - about dumped core includes the directory where the dump file should be - located. However, many Unixes do not allow a process that has - called <CODE>setuid()</CODE> to dump core for security reasons; - the typical Apache setup has the server started as root to bind to - port 80, after which it changes UIDs to a non-privileged user to - serve requests. - </P> - <P> - Dealing with this is extremely operating system-specific, and may - require rebuilding your system kernel. Consult your operating system - documentation or vendor for more information about whether your system - does this and how to bypass it. If there <EM>is</EM> a documented way - of bypassing it, it is recommended that you bypass it only for the - <SAMP>httpd</SAMP> server process if possible. + RedHat messed up and forgot to put a content type for <CODE>.htm</CODE> + files into <CODE>/etc/mime.types</CODE>. Edit <CODE>/etc/mime.types</CODE>, + find the line containing <CODE>html</CODE> and add <CODE>htm</CODE> to it. + Then restart your httpd server: </P> + <DL> + <DD><CODE>kill -HUP `cat /var/run/httpd.pid`</CODE> + </DD> + </DL> <P> - The canonical location for Apache's core-dump files is the - <A HREF="../mod/core.html#serverroot">ServerRoot</A> - directory. As of Apache version 1.3, the location can be set <EM>via</EM> - the - <A HREF="../mod/core.html#coredumpdirectory" - ><SAMP>CoreDumpDirectory</SAMP></A> - directive to a different directory. Make sure that this directory is - writable by the user the server runs as (as opposed to the user the server - is <EM>started</EM> as). + Then <STRONG>clear your browsers' caches</STRONG>. (Many browsers won't + re-examine the content type after they've reloaded a page.) </P> <HR> </LI> - <LI><A NAME="dnsauth"> - <STRONG>Why isn't restricting access by host or domain name - working correctly?</STRONG> + <LI><A NAME="htaccess-work"> + <STRONG>My <CODE>.htaccess</CODE> files are being ignored.</STRONG></A> + <P> + This is almost always due to your <A HREF="../mod/core.html#allowoverride"> + AllowOverride</A> directive being set incorrectly for the directory in + question. If it is set to <CODE>None</CODE> then .htaccess files will + not even be looked for. If you do have one that is set, then be certain + it covers the directory you are trying to use the .htaccess file in. + This is normally accomplished by ensuring it is inside the proper + <A HREF="../mod/core.html#directory">Directory</A> container. + </P> + <HR> + </LI> + <LI><A NAME="forbidden"> + <STRONG>Why do I get a "<SAMP>Forbidden</SAMP>" message + whenever I try to access a particular directory?</STRONG></A> + <P> + This message is generally caused because either + </P> + <UL> + <LI>The underlying file system permissions do not allow the + User/Group under which Apache is running to access the necessary + files; or + <LI>The Apache configuration has some access restrictions in + place which forbid access to the files. + </UL> + <P> + You can determine which case applies to your situation by checking the + error log. + </P> + <P> + In the case where file system permission are at fault, remember + that not only must the directory and files in question be readable, + but also all parent directories must be at least searchable by the + web server in order for the content to be accessible. + </P> + <HR> + </LI> +</OL> + + + + + + + + + + + + + + + + + <H3>F. Dynamic Content (CGI and SSI)</H3> +<OL> + + <LI><A NAME="CGIoutsideScriptAlias"> + <STRONG>How do I enable CGI execution in directories other than + the ScriptAlias?</STRONG> </A> <P> - Two of the most common causes of this are: + Apache recognizes all files in a directory named as a + <A HREF="../mod/mod_alias.html#scriptalias"><SAMP>ScriptAlias</SAMP></A> + as being eligible for execution rather than processing as normal + documents. This applies regardless of the file name, so scripts in a + ScriptAlias directory don't need to be named + "<SAMP>*.cgi</SAMP>" or "<SAMP>*.pl</SAMP>" or + whatever. In other words, <EM>all</EM> files in a ScriptAlias + directory are scripts, as far as Apache is concerned. </P> + <P> + To persuade Apache to execute scripts in other locations, such as in + directories where normal documents may also live, you must tell it how + to recognize them - and also that it's okay to execute them. For + this, you need to use something like the + <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> + directive. + </P> + <P> <OL> - <LI><STRONG>An error, inconsistency, or unexpected mapping in the DNS - registration</STRONG> - <BR> - This happens frequently: your configuration restricts access to - <SAMP>Host.FooBar.Com</SAMP>, but you can't get in from that host. - The usual reason for this is that <SAMP>Host.FooBar.Com</SAMP> is - actually an alias for another name, and when Apache performs the - address-to-name lookup it's getting the <EM>real</EM> name, not - <SAMP>Host.FooBar.Com</SAMP>. You can verify this by checking the - reverse lookup yourself. The easiest way to work around it is to - specify the correct host name in your configuration. - </LI> - <LI><STRONG>Inadequate checking and verification in your - configuration of Apache</STRONG> - <BR> - If you intend to perform access checking and restriction based upon - the client's host or domain name, you really need to configure - Apache to double-check the origin information it's supplied. You do - this by adding the <SAMP>-DMAXIMUM_DNS</SAMP> clause to the - <SAMP>EXTRA_CFLAGS</SAMP> definition in your - <SAMP>Configuration</SAMP> file. For example: + <LI>In an appropriate section of your server configuration files, add + a line such as <P> <DL> - <DD><CODE>EXTRA_CFLAGS=-DMAXIMUM_DNS</CODE> + <DD><CODE>AddHandler cgi-script .cgi</CODE> </DD> </DL> <P></P> <P> - This will cause Apache to be very paranoid about making sure a - particular host address is <EM>really</EM> assigned to the name it - claims to be. Note that this <EM>can</EM> incur a significant - performance penalty, however, because of all the name resolution - requests being sent to a nameserver. + The server will then recognize that all files in that location (and + its logical descendants) that end in "<SAMP>.cgi</SAMP>" + are script files, not documents. </P> </LI> + <LI>Make sure that the directory location is covered by an + <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> + declaration that includes the <SAMP>ExecCGI</SAMP> option. + </LI> + </OL> + <P></P> + <P> + In some situations, you might not want to actually + allow all files named "<SAMP>*.cgi</SAMP>" to be executable. + Perhaps all you want is to enable a particular file in a normal directory to + be executable. This can be alternatively accomplished + <EM>via</EM> <A HREF="../mod/mod_rewrite.html"><SAMP>mod_rewrite</SAMP></A> + and the following steps: + </P> + <P> + <OL> + <LI>Locally add to the corresponding <SAMP>.htaccess</SAMP> file a ruleset + similar to this one: + <P> + <DL> + <DD><CODE>RewriteEngine on + <BR> + RewriteBase /~foo/bar/ + <BR> + RewriteRule ^quux\.cgi$ - [T=application/x-httpd-cgi]</CODE> + </DD> + </DL> + <P></P> + </LI> + <LI>Make sure that the directory location is covered by an + <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> + declaration that includes the <SAMP>ExecCGI</SAMP> and + <SAMP>FollowSymLinks</SAMP> option. + </LI> </OL> + <P></P> <HR> </LI> - <LI><A NAME="SSL-i"> - <STRONG>Why doesn't Apache include SSL?</STRONG> + <LI><A NAME="premature-script-headers"> + <STRONG>What does it mean when my CGIs fail with + "<SAMP>Premature end of script headers</SAMP>"?</STRONG> </A> <P> - SSL (Secure Socket Layer) data transport requires encryption, and many - governments have restrictions upon the import, export, and use of - encryption technology. If Apache included SSL in the base package, - its distribution would involve all sorts of legal and bureaucratic - issues, and it would no longer be freely available. Also, some of - the technology required to talk to current clients using SSL is - patented by <A HREF="http://www.rsa.com/">RSA Data Security</A>, - who restricts its use without a license. + It means just what it says: the server was expecting a complete set of + HTTP headers (one or more followed by a blank line), and didn't get + them. </P> <P> - Some SSL implementations of Apache are available, however; see the - "<A HREF="http://www.apache.org/related_projects.html" - >related projects</A>" - page at the main Apache web site. + The most common cause of this problem is the script dying before + sending the complete set of headers, or possibly any at all, to the + server. To see if this is the case, try running the script standalone + from an interactive session, rather than as a script under the server. + If you get error messages, this is almost certainly the cause of the + "premature end of script headers" message. Even if the CGI + runs fine from the command line, remember that the environment and + permissions may be different when running under the web server. The + CGI can only access resources allowed for the <A + HREF="../mod/core.html#user"><CODE>User</CODE></A> and + <A HREF="../mod/core.html#group"><CODE>Group</CODE></A> specified in + your Apache configuration. In addition, the environment will not be + the same as the one provided on the command line, but it can be + adjusted using the directives provided by <A + HREF="../mod/mod_env.html">mod_env</A>. </P> <P> - You can find out more about this topic in the <CITE>Apache Week</CITE> - article about - <A HREF="http://www.apacheweek.com/features/ssl" REL="Help" - ><CITE>Apache and Secure Transactions</CITE></A>. + The second most common cause of this (aside from people not + outputting the required headers at all) is a result of an interaction + with Perl's output buffering. To make Perl flush its buffers + after each output statement, insert the following statements around + the <CODE>print</CODE> or <CODE>write</CODE> statements that send your + HTTP headers: + </P> + <P> + <DL> + <DD><CODE>{<BR> + local ($oldbar) = $|;<BR> + $cfh = select (STDOUT);<BR> + $| = 1;<BR> + #<BR> + # print your HTTP headers here<BR> + #<BR> + $| = $oldbar;<BR> + select ($cfh);<BR> + }</CODE> + </DD> + </DL> + <P></P> + <P> + This is generally only necessary when you are calling external + programs from your script that send output to stdout, or if there will + be a long delay between the time the headers are sent and the actual + content starts being emitted. To maximize performance, you should + turn buffer-flushing back <EM>off</EM> (with <CODE>$| = 0</CODE> or the + equivalent) after the statements that send the headers, as displayed + above. + </P> + <P> + If your script isn't written in Perl, do the equivalent thing for + whatever language you <EM>are</EM> using (<EM>e.g.</EM>, for C, call + <CODE>fflush()</CODE> after writing the headers). + </P> + <P> + Another cause for the "premature end of script headers" + message are the RLimitCPU and RLimitMEM directives. You may + get the message if the CGI script was killed due to a + resource limit. + </P> + <P> + In addition, a configuration problem in <A + HREF="../suexec.html">suEXEC</A>, mod_perl, or another third party + module can often interfere with the execution of your CGI and cause + the "premature end of script headers" message. </P> <HR> </LI> - <LI><A NAME="midi"> - <STRONG>How do I get Apache to send a MIDI file so the browser can - play it?</STRONG> + <LI><A NAME="POSTnotallowed"> + <STRONG>Why do I keep getting "Method Not Allowed" for + form POST requests?</STRONG> </A> <P> - Even though the registered MIME type for MIDI files is - <SAMP>audio/midi</SAMP>, some browsers are not set up to recognize it - as such; instead, they look for <SAMP>audio/x-midi</SAMP>. There are - two things you can do to address this: + This is almost always due to Apache not being configured to treat the + file you are trying to POST to as a CGI script. You can not POST + to a normal HTML file; the operation has no meaning. See the FAQ + entry on <A HREF="#CGIoutsideScriptAlias">CGIs outside ScriptAliased + directories</A> for details on how to configure Apache to treat the + file in question as a CGI. </P> - <OL> - <LI>Configure your browser to treat documents of type - <SAMP>audio/midi</SAMP> correctly. This is the type that Apache - sends by default. This may not be workable, however, if you have - many client installations to change, or if some or many of the - clients are not under your control. - </LI> - <LI>Instruct Apache to send a different <SAMP>Content-type</SAMP> - header for these files by adding the following line to your server's - configuration files: - <P> - <DL> - <DD><CODE>AddType audio/x-midi .mid .midi .kar</CODE> - </DD> - </DL> - <P></P> - <P> - Note that this may break browsers that <EM>do</EM> recognize the - <SAMP>audio/midi</SAMP> MIME type unless they're prepared to also - handle <SAMP>audio/x-midi</SAMP> the same way. - </P> - </LI> - </OL> <HR> </LI> - <LI><A NAME="cantbuild"> - <STRONG>Why won't Apache compile with my system's - <SAMP>cc</SAMP>?</STRONG> + <LI><A NAME="nph-scripts"> + <STRONG>How can I get my script's output without Apache buffering + it? Why doesn't my server push work?</STRONG> </A> <P> - If the server won't compile on your system, it is probably due to one - of the following causes: + As of Apache 1.3, CGI scripts are essentially not buffered. Every time + your script does a "flush" to output data, that data gets relayed on to + the client. Some scripting languages, for example Perl, have their own + buffering for output - this can be disabled by setting the <CODE>$|</CODE> + special variable to 1. Of course this does increase the overall number + of packets being transmitted, which can result in a sense of slowness for + the end user. </P> - <UL> - <LI><STRONG>The <SAMP>Configure</SAMP> script doesn't recognize your system - environment.</STRONG> - <BR> - This might be either because it's completely unknown or because - the specific environment (include files, OS version, <EM>et - cetera</EM>) isn't explicitly handled. If this happens, you may - need to port the server to your OS yourself. - </LI> - <LI><STRONG>Your system's C compiler is garbage.</STRONG> - <BR> - Some operating systems include a default C compiler that is either - not ANSI C-compliant or suffers from other deficiencies. The usual - recommendation in cases like this is to acquire, install, and use - <SAMP>gcc</SAMP>. - </LI> - <LI><STRONG>Your <SAMP>include</SAMP> files may be confused.</STRONG> - <BR> - In some cases, we have found that a compiler installation or system - upgrade has left the C header files in an inconsistent state. Make - sure that your include directory tree is in sync with the compiler and - the operating system. - </LI> - <LI><STRONG>Your operating system or compiler may be out of - revision.</STRONG> - <BR> - Software vendors (including those that develop operating systems) - issue new releases for a reason; sometimes to add functionality, but - more often to fix bugs that have been discovered. Try upgrading - your compiler and/or your operating system. - </LI> - </UL> - <P> - The Apache Group tests the ability to build the server on many - different platforms. Unfortunately, we can't test all of the OS - platforms there are. If you have verified that none of the above - issues is the cause of your problem, and it hasn't been reported - before, please submit a - <A HREF="http://www.apache.org/bug_report.html">problem report</A>. - Be sure to include <EM>complete</EM> details, such as the compiler - & OS versions and exact error messages. + <P>Prior to 1.3, you needed to use "nph-" scripts to accomplish + non-buffering. Today, the only difference between nph scripts and + normal scripts is that nph scripts require the full HTTP headers to + be sent. </P> <HR> </LI> - <LI><A NAME="addlog"> - <STRONG>How do I add browsers and referrers to my logs?</STRONG> + <LI><A NAME="cgi-spec"> + <STRONG>Where can I find the "CGI specification"?</STRONG> </A> <P> - Apache provides a couple of different ways of doing this. The - recommended method is to compile the - <A HREF="../mod/mod_log_config.html"><SAMP>mod_log_config</SAMP></A> - module into your configuration and use the - <A HREF="../mod/mod_log_config.html#customlog"><SAMP>CustomLog</SAMP></A> - directive. - </P> - <P> - You can either log the additional information in files other than your - normal transfer log, or you can add them to the records already being - written. For example: + The Common Gateway Interface (CGI) specification can be found at + the original NCSA site + <<A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html"> + <SAMP>http://hoohoo.ncsa.uiuc.edu/cgi/interface.html</SAMP></A>>. + This version hasn't been updated since 1995, and there have been + some efforts to update it. </P> <P> - <CODE> - CustomLog logs/access_log "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"" - </CODE> + A new draft is being worked on with the intent of making it an informational + RFC; you can find out more about this project at + <<A HREF="http://web.golux.com/coar/cgi/" + ><SAMP>http://web.golux.com/coar/cgi/</SAMP></A>>. </P> + <HR> + </LI> + + <LI><A NAME="fastcgi"> + <STRONG>Why isn't FastCGI included with Apache any more?</STRONG> + </A> <P> - This will add the values of the <SAMP>User-agent:</SAMP> and - <SAMP>Referer:</SAMP> headers, which indicate the client and the - referring page, respectively, to the end of each line in the access - log. + The simple answer is that it was becoming too difficult to keep the + version being included with Apache synchronized with the master copy + at the + <A HREF="http://www.fastcgi.com/" + >FastCGI web site</A>. When a new version of Apache was released, the + version of the FastCGI module included with it would soon be out of date. </P> <P> - You may want to check out the <CITE>Apache Week</CITE> article - entitled: - "<A HREF="http://www.apacheweek.com/features/logfiles" REL="Help" - ><CITE>Gathering Visitor Information: Customising Your - Logfiles</CITE></A>". + You can still obtain the FastCGI module for Apache from the master + FastCGI web site. </P> <HR> </LI> - <LI><A NAME="bind8.1"> - <STRONG>Why do I get an error about an undefined reference to - "<SAMP>__inet_ntoa</SAMP>" or other - <SAMP>__inet_*</SAMP> symbols?</STRONG> + <LI><A NAME="ssi-part-i"> + <STRONG>How do I enable SSI (parsed HTML)?</STRONG> </A> <P> - If you have installed <A HREF="http://www.isc.org/bind.html">BIND-8</A> - then this is normally due to a conflict between your include files - and your libraries. BIND-8 installs its include files and libraries - <CODE>/usr/local/include/</CODE> and <CODE>/usr/local/lib/</CODE>, while - the resolver that comes with your system is probably installed in - <CODE>/usr/include/</CODE> and <CODE>/usr/lib/</CODE>. If - your system uses the header files in <CODE>/usr/local/include/</CODE> - before those in <CODE>/usr/include/</CODE> but you do not use the new - resolver library, then the two versions will conflict. + SSI (an acronym for Server-Side Include) directives allow static HTML + documents to be enhanced at run-time (<EM>e.g.</EM>, when delivered to + a client by Apache). The format of SSI directives is covered + in the <A HREF="../mod/mod_include.html">mod_include manual</A>; + suffice it to say that Apache supports not only SSI but + xSSI (eXtended SSI) directives. </P> <P> - To resolve this, you can either make sure you use the include files - and libraries that came with your system or make sure to use the - new include files and libraries. Adding <CODE>-lbind</CODE> to the - <CODE>EXTRA_LDFLAGS</CODE> line in your <SAMP>Configuration</SAMP> - file, then re-running <SAMP>Configure</SAMP>, should resolve the - problem. (Apache versions 1.2.* and earlier use - <CODE>EXTRA_LFLAGS</CODE> instead.) + Processing a document at run-time is called <EM>parsing</EM> it; hence + the term "parsed HTML" sometimes used for documents that + contain SSI instructions. Parsing tends to be <EM>extremely</EM> + resource-consumptive, and is not enabled by default. It can also + interfere with the cachability of your documents, which can put a + further load on your server. (see the + <A HREF="#ssi-part-ii">next question</A> for more information about this.) </P> <P> - <STRONG>Note:</STRONG>As of BIND 8.1.1, the bind libraries and files are - installed under <SAMP>/usr/local/bind</SAMP> by default, so you - should not run into this problem. Should you want to use the bind - resolvers you'll have to add the following to the respective lines: + To enable SSI processing, you need to </P> + <UL> + <LI>Build your server with the + <A HREF="../mod/mod_include.html"><SAMP>mod_include</SAMP></A> + module. This is normally compiled in by default. + </LI> + <LI>Make sure your server configuration files have an + <A HREF="../mod/core.html#options"><SAMP>Options</SAMP></A> + directive which permits <SAMP>Includes</SAMP>. + </LI> + <LI>Make sure that the directory where you want the SSI documents to + live is covered by the "server-parsed" content handler, + either explicitly or in some ancestral location. That can be done + with the following + <A HREF="../mod/mod_mime.html#addhandler"><SAMP>AddHandler</SAMP></A> + directive: + <P> + <DL> + <DD><CODE>AddHandler server-parsed .shtml</CODE> + </DD> + </DL> + <P></P> + <P> + This indicates that all files ending in ".shtml" in that + location (or its descendants) should be parsed. Note that using + ".html" will cause all normal HTML files to be parsed, + which may put an inordinate load on your server. + </P> + </LI> + </UL> <P> - <DL> - <DD><CODE>EXTRA_CFLAGS=-I/usr/local/bind/include - <BR> - EXTRA_LDFLAGS=-L/usr/local/bind/lib - <BR> - EXTRA_LIBS=-lbind</CODE> - </DD> - </DL> - <P></P> + For additional information, see the <CITE>Apache Week</CITE> article on + <A HREF="http://www.apacheweek.com/features/ssi" REL="Help" + ><CITE>Using Server Side Includes</CITE></A>. + </P> <HR> </LI> - <LI><A NAME="set-servername"> - <STRONG>Why does accessing directories only work when I include - the trailing "/" - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user/</SAMP>) - but not when I omit it - (<EM>e.g.</EM>, <SAMP>http://foo.domain.com/~user</SAMP>)?</STRONG> + <LI><A NAME="ssi-part-ii"> + <STRONG>Why don't my parsed files get cached?</STRONG> </A> <P> - When you access a directory without a trailing "/", Apache needs - to send what is called a redirect to the client to tell it to - add the trailing slash. If it did not do so, relative URLs would - not work properly. When it sends the redirect, it needs to know - the name of the server so that it can include it in the redirect. - There are two ways for Apache to find this out; either it can guess, - or you can tell it. If your DNS is configured correctly, it can - normally guess without any problems. If it is not, however, then - you need to tell it. + Since the server is performing run-time processing of your SSI + directives, which may change the content shipped to the client, it + can't know at the time it starts parsing what the final size of the + result will be, or whether the parsed result will always be the same. + This means that it can't generate <SAMP>Content-Length</SAMP> or + <SAMP>Last-Modified</SAMP> headers. Caches commonly work by comparing + the <SAMP>Last-Modified</SAMP> of what's in the cache with that being + delivered by the server. Since the server isn't sending that header + for a parsed document, whatever's doing the caching can't tell whether + the document has changed or not - and so fetches it again to be on the + safe side. </P> <P> - Add a <A HREF="../mod/core.html#servername">ServerName</A> directive - to the config file to tell it what the domain name of the server is. + You can work around this in some cases by causing an + <SAMP>Expires</SAMP> header to be generated. (See the + <A HREF="../mod/mod_expires.html" REL="Help"><SAMP>mod_expires</SAMP></A> + documentation for more details.) Another possibility is to use the + <A HREF="../mod/mod_include.html#xbithack" REL="Help" + ><SAMP>XBitHack Full</SAMP></A> + mechanism, which tells Apache to send (under certain circumstances + detailed in the XBitHack directive description) a + <SAMP>Last-Modified</SAMP> header based upon the last modification + time of the file being parsed. Note that this may actually be lying + to the client if the parsed file doesn't change but the SSI-inserted + content does; if the included content changes often, this can result + in stale copies being cached. </P> <HR> </LI> - <LI><A NAME="user-authentication"> - <STRONG>How do I set up Apache to require a username and - password to access certain documents?</STRONG> + <LI><A NAME="ssi-part-iii"> + <STRONG>How can I have my script output parsed?</STRONG> </A> <P> - There are several ways to do this; some of the more popular - ones are to use the <A HREF="../mod/mod_auth.html">mod_auth</A>, - <A HREF="../mod/mod_auth_db.html">mod_auth_db</A>, or - <A HREF="../mod/mod_auth_dbm.html">mod_auth_dbm</A> modules. + So you want to include SSI directives in the output from your CGI + script, but can't figure out how to do it? + The short answer is "you can't." This is potentially + a security liability and, more importantly, it can not be cleanly + implemented under the current server API. The best workaround + is for your script itself to do what the SSIs would be doing. + After all, it's generating the rest of the content. </P> <P> - For an explanation on how to implement these restrictions, see - <A HREF="http://www.apacheweek.com/"><CITE>Apache Week</CITE></A>'s - articles on - <A HREF="http://www.apacheweek.com/features/userauth" - ><CITE>Using User Authentication</CITE></A> - or - <A HREF="http://www.apacheweek.com/features/dbmauth" - ><CITE>DBM User Authentication</CITE></A>. + This is a feature The Apache Group hopes to add in the next major + release after 1.3. + </P> + <HR> + </LI> + + <LI><A NAME="ssi-part-iv"> + <STRONG>SSIs don't work for VirtualHosts and/or + user home directories.</STRONG> + </A> + <P> + This is almost always due to having some setting in your config file that + sets "Options Includes" or some other setting for your DocumentRoot + but not for other directories. If you set it inside a Directory + section, then that setting will only apply to that directory. + </P> + <HR> + </LI> + + <LI><A NAME="errordocssi"> + <STRONG>How can I use <CODE>ErrorDocument</CODE> + and SSI to simplify customized error messages?</STRONG> + </A> + <P> + Have a look at <A HREF="custom_errordocs.html">this document</A>. + It shows in example form how you can a combination of XSSI and + negotiation to tailor a set of <CODE>ErrorDocument</CODE>s to your + personal taste, and returning different internationalized error + responses based on the client's native language. </P> <HR> </LI> @@ -1686,6 +2297,95 @@ <HR> </LI> +</OL> + + + + + + + + + + + + + + + + <H3>G. Authentication and Access Restrictions</H3> +<OL> + + <LI><A NAME="dnsauth"> + <STRONG>Why isn't restricting access by host or domain name + working correctly?</STRONG> + </A> + <P> + Two of the most common causes of this are: + </P> + <OL> + <LI><STRONG>An error, inconsistency, or unexpected mapping in the DNS + registration</STRONG> + <BR> + This happens frequently: your configuration restricts access to + <SAMP>Host.FooBar.Com</SAMP>, but you can't get in from that host. + The usual reason for this is that <SAMP>Host.FooBar.Com</SAMP> is + actually an alias for another name, and when Apache performs the + address-to-name lookup it's getting the <EM>real</EM> name, not + <SAMP>Host.FooBar.Com</SAMP>. You can verify this by checking the + reverse lookup yourself. The easiest way to work around it is to + specify the correct host name in your configuration. + </LI> + <LI><STRONG>Inadequate checking and verification in your + configuration of Apache</STRONG> + <BR> + If you intend to perform access checking and restriction based upon + the client's host or domain name, you really need to configure + Apache to double-check the origin information it's supplied. You do + this by adding the <SAMP>-DMAXIMUM_DNS</SAMP> clause to the + <SAMP>EXTRA_CFLAGS</SAMP> definition in your + <SAMP>Configuration</SAMP> file. For example: + <P> + <DL> + <DD><CODE>EXTRA_CFLAGS=-DMAXIMUM_DNS</CODE> + </DD> + </DL> + <P></P> + <P> + This will cause Apache to be very paranoid about making sure a + particular host address is <EM>really</EM> assigned to the name it + claims to be. Note that this <EM>can</EM> incur a significant + performance penalty, however, because of all the name resolution + requests being sent to a nameserver. + </P> + </LI> + </OL> + <HR> + </LI> + + <LI><A NAME="user-authentication"> + <STRONG>How do I set up Apache to require a username and + password to access certain documents?</STRONG> + </A> + <P> + There are several ways to do this; some of the more popular + ones are to use the <A HREF="../mod/mod_auth.html">mod_auth</A>, + <A HREF="../mod/mod_auth_db.html">mod_auth_db</A>, or + <A HREF="../mod/mod_auth_dbm.html">mod_auth_dbm</A> modules. + </P> + <P> + For an explanation on how to implement these restrictions, see + <A HREF="http://www.apacheweek.com/"><CITE>Apache Week</CITE></A>'s + articles on + <A HREF="http://www.apacheweek.com/features/userauth" + ><CITE>Using User Authentication</CITE></A> + or + <A HREF="http://www.apacheweek.com/features/dbmauth" + ><CITE>DBM User Authentication</CITE></A>. + </P> + <HR> + </LI> + <LI><A NAME="remote-auth-only"> <STRONG>How do I set up Apache to allow access to certain documents only if a site is either a local site <EM>or</EM> @@ -1726,54 +2426,6 @@ <HR> </LI> - <LI><A NAME="no-info-directives"> - <STRONG>Why doesn't mod_info list any directives?</STRONG> - </A> - <P> - The <A HREF="../mod/mod_info.html"><SAMP>mod_info</SAMP></A> - module allows you to use a Web browser to see how your server is - configured. Among the information it displays is the list modules and - their configuration directives. The "current" values for - the directives are not necessarily those of the running server; they - are extracted from the configuration files themselves at the time of - the request. If the files have been changed since the server was last - reloaded, the display will will not match the values actively in use. - If the files and the path to the files are not readable by the user as - which the server is running (see the - <A HREF="../mod/core.html#user"><SAMP>User</SAMP></A> - directive), then <SAMP>mod_info</SAMP> cannot read them in order to - list their values. An entry <EM>will</EM> be made in the error log in - this event, however. - </P> - <HR> - </LI> - - <LI><A NAME="linux-shmget"> - <STRONG>When I run it under Linux I get "shmget: - function not found", what should I do?</STRONG> - </A> - <P> - Your kernel has been built without SysV IPC support. You will have to - rebuild the kernel with that support enabled (it's under the - "General Setup" submenu). Documentation for - kernel building is beyond the scope of this FAQ; you should consult - the - <A HREF="http://www.linuxhq.com/HOWTO/Kernel-HOWTO.html" - >Kernel HOWTO</A>, - or the documentation provided with your distribution, or a - <A HREF="http://www.linuxhq.com/HOWTO/META-FAQ.html" - >Linux newsgroup/mailing list</A>. - As a last-resort workaround, you can - comment out the <CODE>#define USE_SHMGET_SCOREBOARD</CODE> - definition in the - <SAMP>LINUX</SAMP> section of - <SAMP>src/conf.h</SAMP> and rebuild the server (prior to 1.3b4, simply - removing <CODE>#define HAVE_SHMGET</CODE> would have sufficed). - This will produce a server which is slower and less reliable. - </P> - <HR> - </LI> - <LI><A NAME="authauthoritative"> <STRONG>Why does my authentication give me a server error?</STRONG> </A> @@ -1867,6 +2519,80 @@ <HR> </LI> + <LI><A NAME="passwdauth"> + <STRONG>Can I use my <SAMP>/etc/passwd</SAMP> file + for Web page authentication?</STRONG> + </A> + <P> + Yes, you can - but it's a <STRONG>very bad idea</STRONG>. Here are + some of the reasons: + </P> + <UL> + <LI>The Web technology provides no governors on how often or how + rapidly password (authentication failure) retries can be made. That + means that someone can hammer away at your system's + <SAMP>root</SAMP> password using the Web, using a dictionary or + similar mass attack, just as fast as the wire and your server can + handle the requests. Most operating systems these days include + attack detection (such as <EM>n</EM> failed passwords for the same + account within <EM>m</EM> seconds) and evasion (breaking the + connection, disabling the account under attack, disabling + <EM>all</EM> logins from that source, <EM>et cetera</EM>), but the + Web does not. + </LI> + <LI>An account under attack isn't notified (unless the server is + heavily modified); there's no "You have 19483 login + failures" message when the legitimate owner logs in. + </LI> + <LI>Without an exhaustive and error-prone examination of the server + logs, you can't tell whether an account has been compromised. + Detecting that an attack has occurred, or is in progress, is fairly + obvious, though - <EM>if</EM> you look at the logs. + </LI> + <LI>Web authentication passwords (at least for Basic authentication) + generally fly across the wire, and through intermediate proxy + systems, in what amounts to plain text. "O'er the net we + go/Caching all the way;/O what fun it is to surf/Giving my password + away!" + </LI> + <LI>Since HTTP is stateless, information about the authentication is + transmitted <EM>each and every time</EM> a request is made to the + server. Essentially, the client caches it after the first + successful access, and transmits it without asking for all + subsequent requests to the same server. + </LI> + <LI>It's relatively trivial for someone on your system to put up a + page that will steal the cached password from a client's cache + without them knowing. Can you say "password grabber"? + </LI> + </UL> + <P> + If you still want to do this in light of the above disadvantages, the + method is left as an exercise for the reader. It'll void your Apache + warranty, though, and you'll lose all accumulated UNIX guru points. + </P> + <HR> + </LI> +</OL> + + + + + + + + + + + + + + + + + <H3>H. URL Rewriting</H3> +<OL> + <LI><A NAME="rewrite-more-config"> <STRONG>Where can I find mod_rewrite rulesets which already solve particular URL-related problems?</STRONG> @@ -1955,13 +2681,13 @@ get prefixed with DocumentRoot when using mod_rewrite?</STRONG> </A> <P> - If the rule starts with <SAMP>/somedir/...</SAMP> make sure that really no - <SAMP>/somedir</SAMP> exists on the filesystem if you don't want to lead the - URL to match this directory, <EM>i.e.</EM>, there must be no root directory named - <SAMP>somedir</SAMP> on the filesystem. Because if there is such a - directory, the URL will not get prefixed with DocumentRoot. This behaviour - looks ugly, but is really important for some other aspects of URL - rewriting. + If the rule starts with <SAMP>/somedir/...</SAMP> make sure that + really no <SAMP>/somedir</SAMP> exists on the filesystem if you + don't want to lead the URL to match this directory, <EM>i.e.</EM>, + there must be no root directory named <SAMP>somedir</SAMP> on the + filesystem. Because if there is such a directory, the URL will not + get prefixed with DocumentRoot. This behaviour looks ugly, but is + really important for some other aspects of URL rewriting. </P> <HR> </LI> @@ -1971,16 +2697,15 @@ </STRONG> </A> <P> - You can't! The reason is: First, case translations for arbitrary length URLs - cannot be done <EM>via</EM> regex patterns and corresponding substitutions. - One need - a per-character pattern like sed/Perl <SAMP>tr|..|..|</SAMP> feature. - Second, just - making URLs always upper or lower case will not resolve the complete problem - of case-INSENSITIVE URLs, because actually the URLs had to be rewritten to - the correct case-variant residing on the filesystem because in later - processing Apache needs to access the file. And Unix filesystem is always - case-SENSITIVE. + You can't! The reason is: First, case translations for arbitrary + length URLs cannot be done <EM>via</EM> regex patterns and + corresponding substitutions. One need a per-character pattern like + sed/Perl <SAMP>tr|..|..|</SAMP> feature. Second, just making URLs + always upper or lower case will not resolve the complete problem of + case-INSENSITIVE URLs, because actually the URLs had to be rewritten + to the correct case-variant residing on the filesystem because in + later processing Apache needs to access the file. And Unix + filesystem is always case-SENSITIVE. </P> <P> But there is a module named <CODE>mod_speling.c</CODE> (yes, it is named @@ -2005,409 +2730,148 @@ flag?</STRONG> </A> <P> - There is only one ugly solution: You have to surround the complete flag - argument by quotation marks (<SAMP>"[E=...]"</SAMP>). Notice: The argument - to quote here is not the argument to the E-flag, it is the argument of the - Apache config file parser, <EM>i.e.</EM>, the third argument of the RewriteRule here. - So you have to write <SAMP>"[E=any text with whitespaces]"</SAMP>. + There is only one ugly solution: You have to surround the complete + flag argument by quotation marks (<SAMP>"[E=...]"</SAMP>). Notice: + The argument to quote here is not the argument to the E-flag, it is + the argument of the Apache config file parser, <EM>i.e.</EM>, the + third argument of the RewriteRule here. So you have to write + <SAMP>"[E=any text with whitespaces]"</SAMP>. </P> <HR> </LI> - <LI><A NAME="cgi-spec"> - <STRONG>Where can I find the "CGI specification"?</STRONG> - </A> - <P> - The Common Gateway Interface (CGI) specification can be found at - the original NCSA site - <<A HREF="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html"> - <SAMP>http://hoohoo.ncsa.uiuc.edu/cgi/interface.html</SAMP></A>>. - This version hasn't been updated since 1995, and there have been - some efforts to update it. - </P> - <P> - A new draft is being worked on with the intent of making it an informational - RFC; you can find out more about this project at - <<A HREF="http://web.golux.com/coar/cgi/" - ><SAMP>http://web.golux.com/coar/cgi/</SAMP></A>>. - </P> - <HR> - </LI> +</OL> - <LI><A NAME="year2000"> - <STRONG>Is Apache Year 2000 compliant?</STRONG> - </A> - <P> - Yes, Apache is Year 2000 compliant. - </P> - <P> - Apache internally never stores years as two digits. - On the HTTP protocol level RFC1123-style addresses are generated - which is the only format a HTTP/1.1-compliant server should - generate. To be compatible with older applications Apache - recognizes ANSI C's <CODE>asctime()</CODE> and - RFC850-/RFC1036-style date formats, too. - The <CODE>asctime()</CODE> format uses four-digit years, - but the RFC850 and RFC1036 date formats only define a two-digit year. - If Apache sees such a date with a value less than 70 it assumes that - the century is <SAMP>20</SAMP> rather than <SAMP>19</SAMP>. - </P> - <P> - Some aspects of Apache's output may use two-digit years, such as the - automatic listing of directory contents provided by - <A HREF="../mod/mod_autoindex.html"><SAMP>mod_autoindex</SAMP></A> - with the - <A HREF="../mod/mod_autoindex.html#indexoptions" - ><SAMP>FancyIndexing</SAMP></A> - option enabled, but it is improper to depend upon such displays for - specific syntax. And even that issue is being addressed by the - developers; a future version of Apache should allow you to format that - display as you like. - </P> - <P> - Although Apache is Year 2000 compliant, you may still get problems - if the underlying OS has problems with dates past year 2000 - (<EM>e.g.</EM>, OS calls which accept or return year numbers). - Most (UNIX) systems store dates internally as signed 32-bit integers - which contain the number of seconds since 1<SUP>st</SUP> January 1970, so - the magic boundary to worry about is the year 2038 and not 2000. - But modern operating systems shouldn't cause any trouble - at all. - </P> - <HR> - </LI> - <LI><A NAME="namevhost"> - <STRONG>I upgraded to Apache 1.3 and now my virtual hosts don't - work!</STRONG> + + + + + + + + + + + + + + + <H3>I. Features</H3> +<OL> + + <LI><A NAME="proxy"> + <STRONG>Does or will Apache act as a Proxy server?</STRONG> </A> <P> - In versions of Apache prior to 1.3b2, there was a lot of confusion - regarding address-based virtual hosts and (HTTP/1.1) name-based - virtual hosts, and the rules concerning how the server processed - <SAMP><VirtualHost></SAMP> definitions were very complex and not - well documented. - </P> - <P> - Apache 1.3b2 introduced a new directive, - <A HREF="http://www.apache.org/docs/mod/core.html#namevirtualhost" - ><SAMP>NameVirtualHost</SAMP></A>, - which simplifies the rules quite a bit. However, changing the rules - like this means that your existing name-based - <SAMP><VirtualHost></SAMP> containers probably won't work - correctly immediately following the upgrade. - </P> - <P> - To correct this problem, add the following line to the beginning of - your server configuration file, before defining any virtual hosts: - </P> - <DL> - <DD><CODE>NameVirtualHost <EM>n.n.n.n</EM></CODE> - </DD> - </DL> - <P> - Replace the "<SAMP>n.n.n.n</SAMP>" with the IP address to - which the name-based virtual host names resolve; if you have multiple - name-based hosts on multiple addresses, repeat the directive for each - address. - </P> - <P> - Make sure that your name-based <SAMP><VirtualHost></SAMP> blocks - contain <SAMP>ServerName</SAMP> and possibly <SAMP>ServerAlias</SAMP> - directives so Apache can be sure to tell them apart correctly. - </P> - <P> - Please see the - <A HREF="http://www.apache.org/docs/vhosts/">Apache - Virtual Host documentation</A> for further details about configuration. + Apache version 1.1 and above comes with a + <A HREF="../mod/mod_proxy.html">proxy module</A>. + If compiled in, this will make Apache act as a caching-proxy server. </P> <HR> </LI> - <LI><A NAME="redhat"> - <STRONG>I'm using RedHat Linux and I have problems with httpd - dying randomly or not restarting properly</STRONG> + <LI><A NAME="multiviews"> + <STRONG>What are "multiviews"?</STRONG> </A> - - <P> - RedHat Linux versions 4.x (and possibly earlier) RPMs contain - various nasty scripts which do not stop or restart Apache properly. - These can affect you even if you're not running the RedHat supplied - RPMs. - </P> - <P> - If you're using the default install then you're probably running - Apache 1.1.3, which is outdated. From RedHat's ftp site you can - pick up a more recent RPM for Apache 1.2.x. This will solve one of - the problems. - </P> <P> - If you're using a custom built Apache rather than the RedHat RPMs - then you should <CODE>rpm -e apache</CODE>. In particular you want - the mildly broken <CODE>/etc/logrotate.d/apache</CODE> script to be - removed, and you want the broken <CODE>/etc/rc.d/init.d/httpd</CODE> - (or <CODE>httpd.init</CODE>) script to be removed. The latter is - actually fixed by the apache-1.2.5 RPMs but if you're building your - own Apache then you probably don't want the RedHat files. - </P> - <P> - We can't stress enough how important it is for folks, <EM>especially - vendors</EM> to follow the <A HREF="../stopping.html">stopping Apache - directions</A> given in our documentation. In RedHat's defense, - the broken scripts were necessary with Apache 1.1.x because the - Linux support in 1.1.x was very poor, and there were various race - conditions on all platforms. None of this should be necessary with - Apache 1.2 and later. + "Multiviews" is the general name given to the Apache + server's ability to provide language-specific document variants in + response to a request. This is documented quite thoroughly in the + <A HREF="../content-negotiation.html" REL="Help">content negotiation</A> + description page. In addition, <CITE>Apache Week</CITE> carried an + article on this subject entitled + "<A HREF="http://www.apacheweek.com/features/negotiation" REL="Help" + ><CITE>Content Negotiation Explained</CITE></A>". </P> <HR> </LI> - <LI><A NAME="stopping"> - <STRONG>I upgraded from an Apache version earlier - than 1.2.0 and suddenly I have problems with Apache dying randomly - or not restarting properly</STRONG> + <LI><A NAME="putsupport"> + <STRONG>Why can't I publish to my Apache server using PUT on + Netscape Gold and other programs?</STRONG> </A> - <P> - You should read <A HREF="#redhat">the previous note</A> about - problems with RedHat installations. It is entirely likely that your - installation has start/stop/restart scripts which were built for - an earlier version of Apache. Versions earlier than 1.2.0 had - various race conditions that made it necessary to use - <CODE>kill -9</CODE> at times to take out all the httpd servers. - But that should not be necessary any longer. You should follow - the <A HREF="../stopping.html">directions on how to stop - and restart Apache</A>. - </P> - <P>As of Apache 1.3 there is a script - <CODE>src/support/apachectl</CODE> which, after a bit of - customization, is suitable for starting, stopping, and restarting - your server. + Because you need to install and configure a script to handle + the uploaded files. This script is often called a "PUT" handler. + There are several available, but they may have security problems. + Using FTP uploads may be easier and more secure, at least for now. + For more information, see the <CITE>Apache Week</CITE> article + <A HREF="http://www.apacheweek.com/features/put" + ><CITE>Publishing Pages with PUT</CITE></A>. </P> <HR> </LI> - <LI><A NAME="redhat-htm"> - <STRONG>I'm using RedHat Linux and my .htm files are showing - up as HTML source rather than being formatted!</STRONG> + <LI><A NAME="SSL-i"> + <STRONG>Why doesn't Apache include SSL?</STRONG> </A> - <P> - RedHat messed up and forgot to put a content type for <CODE>.htm</CODE> - files into <CODE>/etc/mime.types</CODE>. Edit <CODE>/etc/mime.types</CODE>, - find the line containing <CODE>html</CODE> and add <CODE>htm</CODE> to it. - Then restart your httpd server: - </P> - <DL> - <DD><CODE>kill -HUP `cat /var/run/httpd.pid`</CODE> - </DD> - </DL> - <P> - Then <STRONG>clear your browsers' caches</STRONG>. (Many browsers won't - re-examine the content type after they've reloaded a page.) + SSL (Secure Socket Layer) data transport requires encryption, and many + governments have restrictions upon the import, export, and use of + encryption technology. If Apache included SSL in the base package, + its distribution would involve all sorts of legal and bureaucratic + issues, and it would no longer be freely available. Also, some of + the technology required to talk to current clients using SSL is + patented by <A HREF="http://www.rsa.com/">RSA Data Security</A>, + who restricts its use without a license. </P> - <HR> - </LI> - - <LI><A NAME="glibc-crypt"> - <STRONG>I'm using RedHat Linux 5.0, or some other - <SAMP>glibc</SAMP>-based Linux system, and I get errors with the - <CODE>crypt</CODE> function when I attempt to build Apache 1.2.</STRONG> - </A> - <P> - <SAMP>glibc</SAMP> puts the <CODE>crypt</CODE> function into a separate - library. Edit your <CODE>src/Configuration</CODE> file and set this: + Some SSL implementations of Apache are available, however; see the + "<A HREF="http://www.apache.org/related_projects.html" + >related projects</A>" + page at the main Apache web site. </P> - <DL> - <DD><CODE>EXTRA_LIBS=-lcrypt</CODE> - </DD> - </DL> <P> - Then re-run <SAMP>src/Configure</SAMP> and re-execute the make. + You can find out more about this topic in the <CITE>Apache Week</CITE> + article about + <A HREF="http://www.apacheweek.com/features/ssl" REL="Help" + ><CITE>Apache and Secure Transactions</CITE></A>. </P> <HR> </LI> - - <LI><A NAME="nfslocking"> - <STRONG>Server hangs, or fails to start, and/or error log - fills with "<SAMP>fcntl: F_SETLKW: No record locks - available</SAMP>" or similar messages</STRONG> + <LI><A NAME="footer"> + <STRONG>How can I attach a footer to my documents + without using SSI?</STRONG> </A> - <P> - These are symptoms of a fine locking problem, which usually means that - the server is trying to use a synchronization file on an NFS filesystem. + You can make arbitrary changes to static documents by configuring an + <A HREF="http://www.apache.org/docs/mod/mod_actions.html#action"> + Action</A> which launches a CGI script. The CGI is then + responsible for setting a content-type and delivering the requested + document (the location of which is passed in the + <SAMP>PATH_TRANSLATED</SAMP> environment variable), along with + whatever footer is needed. </P> <P> - Because of its parallel-operation model, the Apache Web server needs to - provide some form of synchronization when accessing certain resources. - One of these synchronization methods involves taking out locks on a file, - which means that the filesystem whereon the lockfile resides must support - locking. In many cases this means it <EM>can't</EM> be kept on an - NFS-mounted filesystem. - </P> - <P> - To cause the Web server to work around the NFS locking limitations, include - a line such as the following in your server configuration files: - </P> - <DL> - <DD><CODE>LockFile /var/run/apache-lock</CODE> - </DD> - </DL> - <P> - The directory should not be generally writable (<EM>e.g.</EM>, don't use - <SAMP>/var/tmp</SAMP>). - See the <A HREF="../mod/core.html#lockfile"><SAMP>LockFile</SAMP></A> - documentation for more information. + Busy sites may not want to run a CGI script on every request, and + should consider using an Apache module to add the footer. There are + several third party modules available through the <A + HREF="http://modules.apache.org/">Apache Module Registry</A> which + will add footers to documents. These include mod_trailer, PHP + (<SAMP>php3_auto_append_file</SAMP>), and mod_perl + (<SAMP>Apache::Sandwich</SAMP>). </P> <HR> </LI> - <LI><A NAME="zoom"> - <STRONG>What's the best hardware/operating system/... How do - I get the most out of my Apache Web server?</STRONG> + <LI><A NAME="search"> + <STRONG>Does Apache include a search engine?</STRONG> </A> - <P> - Check out Dean Gaudet's - <A HREF="http://www.apache.org/docs/misc/perf-tuning.html" - >performance tuning page</A>. + <P>Apache does not include a search engine, but there are many good + commercial and free search engines which can be used easily with + Apache. Some of them are listed on the <A + HREF="http://www.searchtools.com/tools/tools.html">Web Site Search + Tools</A> page. Open source search engines that are often used with + Apache include <A HREF="http://www.htdig.org/">ht://Dig</A> and <A + HREF="http://sunsite.berkeley.edu/SWISH-E/">SWISH-E</A>. </P> <HR> </LI> - <LI><A NAME="regex"> - <STRONG>What are "regular expressions"?</STRONG></A> - <P> - Regular expressions are a way of describing a pattern - for example, "all - the words that begin with the letter A" or "every 10-digit phone number" - or even "Every sentence with two commas in it, and no capital letter Q". - Regular expressions (aka "regexp"s) are useful in Apache because they - let you apply certain attributes against collections of files or resources - in very flexible ways - for example, all .gif and .jpg files under - any "images" directory could be written as /.*\/images\/.*[jpg|gif]/. - </P> - <P> - The best overview around is probably the one which comes with - Perl. We implement a simple subset of Perl's regexp support, but - it's still a good way to learn what they mean. You can start by - going to the - <A - HREF="http://www.perl.com/CPAN-local/doc/manual/html/pod/perlre.html#Version_8_Regular_Expresions" - >CPAN page on regular expressions</A>, and branching out from there. - </P> - <HR> - </LI> - <LI><A NAME="broken-gcc"><STRONG>I'm using gcc and I get some - compilation errors, what is wrong?</STRONG></A> - <P> - GCC parses your system header files and produces a modified subset which - it uses for compiling. This behaviour ties GCC tightly to the version - of your operating system. So, for example, if you were running IRIX 5.3 - when you built GCC and then upgrade to IRIX 6.2 later, you will have to - rebuild GCC. Similarly for Solaris 2.4, 2.5, or 2.5.1 when you upgrade - to 2.6. Sometimes you can type "gcc -v" and it will tell you the version - of the operating system it was built against. - </P> - <P> - If you fail to do this, then it is very likely that Apache will fail - to build. One of the most common errors is with <CODE>readv</CODE>, - <CODE>writev</CODE>, or <CODE>uio.h</CODE>. This is <STRONG>not</STRONG> a - bug with Apache. You will need to re-install GCC. - </P> - <HR> - </LI> - <LI><A NAME="htaccess-work"> - <STRONG>My <CODE>.htaccess</CODE> files are being ignored.</STRONG></A> - <P> - This is almost always due to your <A HREF="../mod/core.html#allowoverride"> - AllowOverride</A> directive being set incorrectly for the directory in - question. If it is set to <CODE>None</CODE> then .htaccess files will - not even be looked for. If you do have one that is set, then be certain - it covers the directory you are trying to use the .htaccess file in. - This is normally accomplished by ensuring it is inside the proper - <A HREF="../mod/core.html#directory">Directory</A> container. - </P> - <HR> - </LI> - <LI><A NAME="submit_patch"> - <STRONG>How do I submit a patch to the Apache Group?</STRONG></A> - <P> - The Apache Group encourages patches from outside developers. There are 2 - main "types" - of patches: small bugfixes and general improvements. Bugfixes should be - submitting using the - Apache <A HREF="http://www.apache.org/bug_report.html">bug report page</A>. - Improvements, modifications, and additions should follow the instructions - below. - </P> - <P> - In general, the first course of action is to be a member of the - <SAMP>new-httpd@apache.org</SAMP> mailing list. This indicates to the Group - that - you are closely following the latest Apache developments. Your patch file - should be - generated using either '<CODE>diff -c</CODE>' or - '<CODE>diff -u</CODE>' against the - latest CVS tree. To submit your patch, send email to - <SAMP>new-httpd@apache.org</SAMP> - with a <SAMP>Subject:</SAMP> line that starts with <SAMP>[PATCH]</SAMP> and - includes a general description of the patch. In the body of the message, the - patch should be clearly described and then included at the end of the - message. - If the patch-file is long, you can note a URL to the file instead of the - file itself. Use of MIME enclosures/attachments should be avoided. - </P> - <P> - Be prepared to respond to any questions about your patches and possibly - defend - your code. If your patch results in a lot of discussion, you may be asked to - submit an updated patch that incorporate all changes and suggestions. - </P> - <HR> - </LI> - <LI><A NAME="aixccbug"><STRONG>Why am I getting "<SAMP>Expected - </Directory> but saw </Directory></SAMP>" when - I try to start Apache?</STRONG></A> - <P> - This is a known problem with certain versions of the AIX C compiler. - IBM are working on a solution, and the issue is being tracked by - <A HREF="http://bugs.apache.org/index/full/2312">problem report #2312</A>. - </P> - <HR> - </LI> - <LI><A NAME="domination"><STRONG>Why has Apache stolen my favourite site's - Internet address?</STRONG></A> - <P> - The simple answer is: "It hasn't." This misconception is usually - caused by the site in question having migrated to the Apache Web - server software, but not having migrated the site's content yet. When - Apache is installed, the default page that gets installed tells the - Webmaster the installation was successful. The expectation is that - this default page will be replaced with the site's real content. - If it doesn't, complain to the Webmaster, not to the Apache project -- - we just make the software and aren't responsible for what people - do (or don't do) with it. - </P> - <HR> - </LI> - <LI><A NAME="apspam"><STRONG>Why am I getting spam mail from the - Apache site?</STRONG></A> - <P> - The short answer is: "You aren't." Usually when someone thinks the - Apache site is originating spam, it's because they've traced the - spam to a Web site, and the Web site says it's using Apache. See the - <A HREF="#domination">previous FAQ entry</A> for more details on this - phenomenon. - </P> - <P> - No marketing spam originates from the Apache site. The only mail - that comes from the site goes only to addresses that have been - <EM>requested</EM> to receive the mail. - </P> - <HR> - </LI> - <!-- Don't forget to add HR tags at the end of each list item.. --> - </OL> + + + + <HR> <H3 ALIGN="CENTER"> diff --git a/usr.sbin/httpd/htdocs/manual/misc/howto.html b/usr.sbin/httpd/htdocs/manual/misc/howto.html index 62f1116656a..7cb757fc58d 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/howto.html +++ b/usr.sbin/httpd/htdocs/manual/misc/howto.html @@ -83,7 +83,7 @@ want to compile mod_rewrite into your server. <P>Here's how to redirect all requests to a script... In the server configuration file, -<BLOCKQUOTE><PRE>ScriptAlias / /usr/local/httpd/cgi-bin/redirect_script</PRE> +<BLOCKQUOTE><PRE>ScriptAlias / /usr/local/httpd/cgi-bin/redirect_script/</PRE> </BLOCKQUOTE> and here's a simple perl script to redirect requests: @@ -91,8 +91,9 @@ and here's a simple perl script to redirect requests: <BLOCKQUOTE><PRE> #!/usr/local/bin/perl -print "Status: 302 Moved Temporarily\r -Location: http://www.some.where.else.com/\r\n\r\n"; +print "Status: 302 Moved Temporarily\r\n" . + "Location: http://www.some.where.else.com/\r\n" . + "\r\n"; </PRE></BLOCKQUOTE></P> diff --git a/usr.sbin/httpd/htdocs/manual/misc/known_client_problems.html b/usr.sbin/httpd/htdocs/manual/misc/known_client_problems.html index 4f64e06a2f4..d432c44953b 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/known_client_problems.html +++ b/usr.sbin/httpd/htdocs/manual/misc/known_client_problems.html @@ -15,144 +15,150 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> <H1 ALIGN="CENTER">Known Problems in Clients</H1> -<p>Over time the Apache Group has discovered or been notified of problems -with various clients which we have had to work around. This document -describes these problems and the workarounds available. It's not arranged -in any particular order. Some familiarity with the standards is assumed, -but not necessary. - -<p>For brevity, <i>Navigator</i> will refer to Netscape's Navigator -product, and <i>MSIE</i> will refer to Microsoft's Internet Explorer -product. All trademarks and copyrights belong to their respective -companies. We welcome input from the various client authors to correct -inconsistencies in this paper, or to provide us with exact version -numbers where things are broken/fixed. - -<p>For reference, -<a href="ftp://ds.internic.net/rfc/rfc1945.txt">RFC1945</a> +<P>Over time the Apache Group has discovered or been notified of problems +with various clients which we have had to work around, or explain. +This document describes these problems and the workarounds available. +It's not arranged in any particular order. Some familiarity with the +standards is assumed, but not necessary. + +<P>For brevity, <EM>Navigator</EM> will refer to Netscape's Navigator +product (which in later versions was renamed "Communicator" and +various other names), and <EM>MSIE</EM> will refer to Microsoft's +Internet Explorer product. All trademarks and copyrights belong to +their respective companies. We welcome input from the various client +authors to correct inconsistencies in this paper, or to provide us with +exact version numbers where things are broken/fixed. + +<P>For reference, +<A HREF="ftp://ds.internic.net/rfc/rfc1945.txt">RFC1945</A> defines HTTP/1.0, and -<a href="ftp://ds.internic.net/rfc/rfc2068.txt">RFC2068</a> +<A HREF="ftp://ds.internic.net/rfc/rfc2068.txt">RFC2068</A> defines HTTP/1.1. Apache as of version 1.2 is an HTTP/1.1 server (with an optional HTTP/1.0 proxy). -<p>Various of these workarounds are triggered by environment variables. +<P>Various of these workarounds are triggered by environment variables. The admin typically controls which are set, and for which clients, by using -<a href="../mod/mod_browser.html">mod_browser</a>. Unless otherwise +<A HREF="../mod/mod_browser.html">mod_browser</A>. Unless otherwise noted all of these workarounds exist in versions 1.2 and later. -<a name="trailing-crlf"><H3>Trailing CRLF on POSTs</H3></a> +<H3><A NAME="trailing-crlf">Trailing CRLF on POSTs</A></H3> -<p>This is a legacy issue. The CERN webserver required <code>POST</code> -data to have an extra <code>CRLF</code> following it. Thus many -clients send an extra <code>CRLF</code> that -is not included in the <code>Content-Length</code> of the request. +<P>This is a legacy issue. The CERN webserver required <CODE>POST</CODE> +data to have an extra <CODE>CRLF</CODE> following it. Thus many +clients send an extra <CODE>CRLF</CODE> that +is not included in the <CODE>Content-Length</CODE> of the request. Apache works around this problem by eating any empty lines which appear before a request. -<a name="broken-keepalive"><h3>Broken keepalive</h3></a> +<H3><A NAME="broken-keepalive">Broken keepalive</A></H3> -<p>Various clients have had broken implementations of <i>keepalive</i> +<P>Various clients have had broken implementations of <EM>keepalive</EM> (persistent connections). In particular the Windows versions of Navigator 2.0 get very confused when the server times out an idle connection. The workaround is present in the default config files: -<blockquote><code> +<BLOCKQUOTE><CODE> BrowserMatch Mozilla/2 nokeepalive -</code></blockquote> +</CODE></BLOCKQUOTE> Note that this matches some earlier versions of MSIE, which began the -practice of calling themselves <i>Mozilla</i> in their user-agent +practice of calling themselves <EM>Mozilla</EM> in their user-agent strings just like Navigator. -<p>MSIE 4.0b2, which claims to support HTTP/1.1, does not properly +<P>MSIE 4.0b2, which claims to support HTTP/1.1, does not properly support keepalive when it is used on 301 or 302 (redirect) -responses. Unfortunately Apache's <code>nokeepalive</code> code +responses. Unfortunately Apache's <CODE>nokeepalive</CODE> code prior to 1.2.2 would not work with HTTP/1.1 clients. You must apply -<a href="http://www.apache.org/dist/patches/apply_to_1.2.1/msie_4_0b2_fixes.patch">this -patch</a> to version 1.2.1. Then add this to your config: -<blockquote><code> +<A +HREF="http://www.apache.org/dist/patches/apply_to_1.2.1/msie_4_0b2_fixes.patch" +>this patch</A> to version 1.2.1. Then add this to your config: +<BLOCKQUOTE><CODE> BrowserMatch "MSIE 4\.0b2;" nokeepalive -</code></blockquote> +</CODE></BLOCKQUOTE> -<a name="force-response-1.0"><h3>Incorrect interpretation of <code>HTTP/1.1</code> in response</h3></a> +<H3><A NAME="force-response-1.0">Incorrect interpretation of +<CODE>HTTP/1.1</CODE> in response</A></H3> -<p>To quote from section 3.1 of RFC1945: -<blockquote> -HTTP uses a "<major>.<minor>" numbering scheme to indicate versions +<P>To quote from section 3.1 of RFC1945: +<BLOCKQUOTE> +HTTP uses a "<MAJOR>.<MINOR>" numbering scheme to indicate versions of the protocol. The protocol versioning policy is intended to allow the sender to indicate the format of a message and its capacity for understanding further HTTP communication, rather than the features obtained via that communication. -</blockquote> +</BLOCKQUOTE> Since Apache is an HTTP/1.1 server, it indicates so as part of its response. Many client authors mistakenly treat this part of the response as an indication of the protocol that the response is in, and then refuse to accept the response. -<p>The first major indication of this problem was with AOL's proxy servers. +<P>The first major indication of this problem was with AOL's proxy servers. When Apache 1.2 went into beta it was the first wide-spread HTTP/1.1 server. After some discussion, AOL fixed their proxies. In -anticipation of similar problems, the <code>force-response-1.0</code> +anticipation of similar problems, the <CODE>force-response-1.0</CODE> environment variable was added to Apache. When present Apache will indicate "HTTP/1.0" in response to an HTTP/1.0 client, but will not in any other way change the response. -<p>The pre-1.1 Java Development Kit (JDK) that is used in many clients +<P>The pre-1.1 Java Development Kit (JDK) that is used in many clients (including Navigator 3.x and MSIE 3.x) exhibits this problem. As do some of the early pre-releases of the 1.1 JDK. We think it is fixed in the 1.1 JDK release. In any event the workaround: -<blockquote><code> -BrowserMatch Java1.0 force-response-1.0 <br> +<BLOCKQUOTE><CODE> +BrowserMatch Java/1.0 force-response-1.0 <BR> BrowserMatch JDK/1.0 force-response-1.0 -</code></blockquote> +</CODE></BLOCKQUOTE> -<p>RealPlayer 4.0 from Progressive Networks also exhibits this problem. +<P>RealPlayer 4.0 from Progressive Networks also exhibits this problem. However they have fixed it in version 4.01 of the player, but version -4.01 uses the same <code>User-Agent</code> as version 4.0. The +4.01 uses the same <CODE>User-Agent</CODE> as version 4.0. The workaround is still: -<blockquote><code> +<BLOCKQUOTE><CODE> BrowserMatch "RealPlayer 4.0" force-response-1.0 -</code></blockquote> +</CODE></BLOCKQUOTE> -<a name="msie4.0b2"><h3>Requests use HTTP/1.1 but responses must be in HTTP/1.0</h3></a> +<H3><A NAME="msie4.0b2">Requests use HTTP/1.1 but responses must be +in HTTP/1.0</A></H3> -<p>MSIE 4.0b2 has this problem. Its Java VM makes requests in HTTP/1.1 +<P>MSIE 4.0b2 has this problem. Its Java VM makes requests in HTTP/1.1 format but the responses must be in HTTP/1.0 format (in particular, it -does not understand <i>chunked</i> responses). The workaround +does not understand <EM>chunked</EM> responses). The workaround is to fool Apache into believing the request came in HTTP/1.0 format. -<blockquote><code> +<BLOCKQUOTE><CODE> BrowserMatch "MSIE 4\.0b2;" downgrade-1.0 force-response-1.0 -</code></blockquote> +</CODE></BLOCKQUOTE> This workaround is available in 1.2.2, and in a -<a href="http://www.apache.org/dist/patches/apply_to_1.2.1/msie_4_0b2_fixes.patch">patch -</a> against 1.2.1. +<A +HREF="http://www.apache.org/dist/patches/apply_to_1.2.1/msie_4_0b2_fixes.patch" +>patch</A> against 1.2.1. -<a name="257th-byte"><h3>Boundary problems with header parsing</h3></a> +<H3><A NAME="257th-byte">Boundary problems with header parsing</A></H3> -<p>All versions of Navigator from 2.0 through 4.0b2 (and possibly later) +<P>All versions of Navigator from 2.0 through 4.0b2 (and possibly later) have a problem if the trailing CRLF of the response header starts at -the 256th or 257th byte of the response. A BrowserMatch for this would +offset 256, 257 or 258 of the response. A BrowserMatch for this would match on nearly every hit, so the workaround is enabled automatically -on all responses. The workaround is to detect when this condition would -occur in a response and add extra padding to the header to push the -trailing CRLF past the 257th byte of the response. +on all responses. The workaround implemented detects when this condition would +occur in a response and adds extra padding to the header to push the +trailing CRLF past offset 258 of the response. -<a name="boundary-string"><h3>Multipart responses and Quoted Boundary Strings</h3></a> +<H3><A NAME="boundary-string">Multipart responses and Quoted Boundary +Strings</A></H3> -<p>On multipart responses some clients will not accept quotes (") +<P>On multipart responses some clients will not accept quotes (") around the boundary string. The MIME standard recommends that such quotes be used. But the clients were probably written based on one of the examples in RFC2068, which does not include quotes. Apache does not include quotes on its boundary strings to workaround this problem. -<a name="byterange-requests"><h3>Byterange requests</h3></a> +<H3><A NAME="byterange-requests">Byterange requests</A></H3> -<p>A byterange request is used when the client wishes to retrieve a +<P>A byterange request is used when the client wishes to retrieve a portion of an object, not necessarily the entire object. There was a very old draft which included these byteranges in the URL. Old clients such as Navigator 2.0b1 and MSIE 3.0 for the MAC @@ -161,48 +167,148 @@ it will appear in the servers' access logs as (failed) attempts to retrieve a URL with a trailing ";xxx-yyy". Apache does not attempt to implement this at all. -<p>A subsequent draft of this standard defines a header -<code>Request-Range</code>, and a response type -<code>multipart/x-byteranges</code>. The HTTP/1.1 standard includes +<P>A subsequent draft of this standard defines a header +<CODE>Request-Range</CODE>, and a response type +<CODE>multipart/x-byteranges</CODE>. The HTTP/1.1 standard includes this draft with a few fixes, and it defines the header -<code>Range</code> and type <code>multipart/byteranges</code>. - -<p>Navigator (versions 2 and 3) sends both <code>Range</code> and -<code>Request-Range</code> headers (with the same value), but does not -accept a <code>multipart/byteranges</code> response. The response must -be <code>multipart/x-byteranges</code>. As a workaround, if Apache -receives a <code>Request-Range</code> header it considers it "higher -priority" than a <code>Range</code> header and in response uses -<code>multipart/x-byteranges</code>. - -<p>The Adobe Acrobat Reader plugin makes extensive use of byteranges and -prior to version 3.01 supports only the <code>multipart/x-byterange</code> +<CODE>Range</CODE> and type <CODE>multipart/byteranges</CODE>. + +<P>Navigator (versions 2 and 3) sends both <CODE>Range</CODE> and +<CODE>Request-Range</CODE> headers (with the same value), but does not +accept a <CODE>multipart/byteranges</CODE> response. The response must +be <CODE>multipart/x-byteranges</CODE>. As a workaround, if Apache +receives a <CODE>Request-Range</CODE> header it considers it "higher +priority" than a <CODE>Range</CODE> header and in response uses +<CODE>multipart/x-byteranges</CODE>. + +<P>The Adobe Acrobat Reader plugin makes extensive use of byteranges and +prior to version 3.01 supports only the <CODE>multipart/x-byterange</CODE> response. Unfortunately there is no clue that it is the plugin making the request. If the plugin is used with Navigator, the above workaround works fine. But if the plugin is used with MSIE 3 (on Windows) the workaround won't work because MSIE 3 doesn't give the -<code>Range-Request</code> clue that Navigator does. To workaround this, -Apache special cases "MSIE 3" in the <code>User-Agent</code> and serves -<code>multipart/x-byteranges</code>. Note that the necessity for this +<CODE>Range-Request</CODE> clue that Navigator does. To workaround this, +Apache special cases "MSIE 3" in the <CODE>User-Agent</CODE> and serves +<CODE>multipart/x-byteranges</CODE>. Note that the necessity for this with MSIE 3 is actually due to the Acrobat plugin, not due to the browser. -<p>Netscape Communicator appears to not issue the non-standard -<code>Request-Range</code> header. When an Acrobat plugin prior to +<P>Netscape Communicator appears to not issue the non-standard +<CODE>Request-Range</CODE> header. When an Acrobat plugin prior to version 3.01 is used with it, it will not properly understand byteranges. The user must upgrade their Acrobat reader to 3.01. -<a name="cookie-merge"><h3><code>Set-Cookie</code> header is unmergeable</h3></a> +<H3><A NAME="cookie-merge"><CODE>Set-Cookie</CODE> header is +unmergeable</A></H3> -<p>The HTTP specifications say that it is legal to merge headers with -duplicate names into one (separated by semicolon). Some browsers +<P>The HTTP specifications say that it is legal to merge headers with +duplicate names into one (separated by commas). Some browsers that support Cookies don't like merged headers and prefer that each -<code>Set-Cookie</code> header is sent separately. When parsing the +<CODE>Set-Cookie</CODE> header is sent separately. When parsing the headers returned by a CGI, Apache will explicitly avoid merging any -<code>Set-Cookie</code> headers. +<CODE>Set-Cookie</CODE> headers. + +<H3><A NAME="gif89-expires"><CODE>Expires</CODE> headers and GIF89A +animations</A></H3> + +<P>Navigator versions 2 through 4 will erroneously re-request +GIF89A animations on each loop of the animation if the first +response included an <CODE>Expires</CODE> header. This happens +regardless of how far in the future the expiry time is set. There +is no workaround supplied with Apache, however there are hacks for <A +HREF="http://www.arctic.org/~dgaudet/patches/apache-1.2-gif89-expires-hack.patch">1.2</A> +and for <A +HREF="http://www.arctic.org/~dgaudet/patches/apache-1.3-gif89-expires-hack.patch">1.3</A>. + +<H3><A NAME="no-content-length"><CODE>POST</CODE> without +<CODE>Content-Length</CODE></A></H3> + +<P>In certain situations Navigator 3.01 through 3.03 appear to incorrectly +issue a POST without the request body. There is no +known workaround. It has been fixed in Navigator 3.04, Netscapes +provides some +<A HREF="http://help.netscape.com/kb/client/971014-42.html">information</A>. +There's also +<A HREF="http://www.arctic.org/~dgaudet/apache/no-content-length/"> +some information</A> about the actual problem. + +<H3><A NAME="jdk-12-bugs">JDK 1.2 betas lose parts of responses.</A></H3> + +<P>The http client in the JDK1.2beta2 and beta3 will throw away the first part of +the response body when both the headers and the first part of the body are sent +in the same network packet AND keep-alive's are being used. If either condition +is not met then it works fine. + +<P>See also Bug-ID's 4124329 and 4125538 at the java developer connection. + +<P>If you are seeing this bug yourself, you can add the following BrowserMatch +directive to work around it: + +<BLOCKQUOTE><CODE> +BrowserMatch "Java1\.2beta[23]" nokeepalive +</CODE></BLOCKQUOTE> + +<P>We don't advocate this though since bending over backwards for beta software +is usually not a good idea; ideally it gets fixed, new betas or a final release +comes out, and no one uses the broken old software anymore. In theory. + +<H3><A NAME="content-type-persistence"><CODE>Content-Type</CODE> change +is not noticed after reload</A></H3> + +<P>Navigator (all versions?) will cache the <CODE>content-type</CODE> +for an object "forever". Using reload or shift-reload will not cause +Navigator to notice a <CODE>content-type</CODE> change. The only +work-around is for the user to flush their caches (memory and disk). By +way of an example, some folks may be using an old <CODE>mime.types</CODE> +file which does not map <CODE>.htm</CODE> to <CODE>text/html</CODE>, +in this case Apache will default to sending <CODE>text/plain</CODE>. +If the user requests the page and it is served as <CODE>text/plain</CODE>. +After the admin fixes the server, the user will have to flush their caches +before the object will be shown with the correct <CODE>text/html</CODE> +type. + +<h3><a name="msie-cookie-y2k">MSIE Cookie problem with expiry date in +the year 2000</a></h3> + +<p>MSIE versions 3.00 and 3.02 (without the Y2K patch) do not handle +cookie expiry dates in the year 2000 properly. Years after 2000 and +before 2000 work fine. This is fixed in IE4.01 service pack 1, and in +the Y2K patch for IE3.02. Users should avoid using expiry dates in the +year 2000. + +<h3><a name="lynx-negotiate-trans">Lynx incorrectly asking for transparent +content negotiation</a></h3> + +<p>The Lynx browser versions 2.7 and 2.8 send a "negotiate: trans" header +in their requests, which is an indication the browser supports transparent +content negotiation (TCN). However the browser does not support TCN. +As of version 1.3.4, Apache supports TCN, and this causes problems with +these versions of Lynx. As a workaround future versions of Apache will +ignore this header when sent by the Lynx client. + +<h3><a name="ie40-vary">MSIE 4.0 mishandles Vary response header</a></h3> + +<p>MSIE 4.0 does not handle a Vary header properly. The Vary header is +generated by mod_rewrite in apache 1.3. The result is an error from MSIE +saying it cannot download the requested file. There are more details +in <a href="http://bugs.apache.org/index/full/4118">PR#4118</a>. +</P> +<P> +A workaround is to add the following to your server's configuration +files: +</P> +<PRE> + BrowserMatch "MSIE 4\.0" force-no-vary +</PRE> +<P> +(This workaround is only available with releases <STRONG>after</STRONG> +1.3.6 of the Apache Web server.) +</P> + <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/misc/perf-dec.html b/usr.sbin/httpd/htdocs/manual/misc/perf-dec.html index eb0551a1ecd..21edc29af9b 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/perf-dec.html +++ b/usr.sbin/httpd/htdocs/manual/misc/perf-dec.html @@ -14,7 +14,7 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> @@ -22,7 +22,7 @@ Below is a set of newsgroup posts made by an engineer from DEC in response to queries about how to modify DEC's Digital Unix OS for more -heavily loaded web sites. Copied with permission. +heavily loaded web sites. Copied with permission. <HR> @@ -38,10 +38,10 @@ Date: Fri, 28 Jun 96 16:07:56 MDT<BR> mechanism. <LI>Patch ID OSF350-146 has been superseded by -<blockquote> +<BLOCKQUOTE> Patch ID OSF350-195 for V3.2C<BR> Patch ID OSF360-350195 for V3.2D -</blockquote> +</BLOCKQUOTE> Patch IDs for V3.2E and V3.2F should be available soon. There is no known reason why the Patch ID OSF360-350195 won't work on these releases, but such use is not officially @@ -56,7 +56,7 @@ From mogul@pa.dec.com (Jeffrey Mogul) Organization DEC Western Research Date 30 May 1996 00:50:25 GMT Newsgroups <A HREF="news:comp.unix.osf.osf1">comp.unix.osf.osf1</A> -Message-ID <A HREF="news:4oirch$bc8@usenet.pa.dec.com"><4oirch$bc8@usenet.pa.dec.com></A> +Message-ID <4oirch$bc8@usenet.pa.dec.com> Subject Re: Web Site Performance References 1 @@ -69,8 +69,10 @@ In article <skoogDs54BH.9pF@netcom.com> skoog@netcom.com (Jim Skoog) write >runing DEC UNIX 3.2C, which run DEC's seal firewall and behind >that Alpha 1000 and 2100 webservers. -Our experience (running such Web servers as <A HREF="http://altavista.digital.com">altavista.digital.com</A> -and <A HREF="http://www.digital.com">www.digital.com</A>) is that there is one important kernel tuning +Our experience (running such Web servers as <A + HREF="http://altavista.digital.com">altavista.digital.com</A> +and <A HREF="http://www.digital.com" + >www.digital.com</A>) is that there is one important kernel tuning knob to adjust in order to get good performance on V3.2C. You need to patch the kernel global variable "somaxconn" (use dbx -k to do this) from its default value of 8 to something much larger. @@ -104,7 +106,10 @@ with no obvious performance bottlenecks at the millions-of-hits-per-day level. We have some Webstone performance results available at - <A HREF="http://www.digital.com/info/alphaserver/news/webff.html">http://www.digital.com/info/alphaserver/news/webff.html</A> + http://www.digital.com/info/alphaserver/news/webff.html + +<EM>[The document referenced above is no longer at that URL -- Ed.]</EM> + I'm not sure if these were done using V4.0 or an earlier version of Digital UNIX, although I suspect they were done using a test version of V4.0. @@ -119,7 +124,7 @@ From mogul@pa.dec.com (Jeffrey Mogul) Organization DEC Western Research Date 31 May 1996 21:01:01 GMT Newsgroups <A HREF="news:comp.unix.osf.osf1">comp.unix.osf.osf1</A> -Message-ID <A HREF="news:4onmmd$mmd@usenet.pa.dec.com"><4onmmd$mmd@usenet.pa.dec.com></A> +Message-ID <4onmmd$mmd@usenet.pa.dec.com> Subject Digital UNIX V3.2C Internet tuning patch info ---------------------------------------------------------------------------- @@ -142,7 +147,8 @@ so the description of the various tuning parameters in this README file might be useful to people running V4.0 systems. This patch kit does not appear to be available (yet?) from - <A HREF="http://www.service.digital.com/html/patch_service.html">http://www.service.digital.com/html/patch_service.html</A> + <A HREF="http://www.service.digital.com/html/patch_service.html" + >http://www.service.digital.com/html/patch_service.html</A> so I guess you'll have to call Digital's Customer Support to get it. -Jeff @@ -213,7 +219,7 @@ TUNING tcp_keepinit This is the amount of time a partially established connection will sit on the listen - queue before timing out (e.g. if a client + queue before timing out (<EM>e.g.</EM>, if a client sends a SYN but never answers our SYN/ACK). Partially established connections tie up slots on the listen queue. If the queue starts to @@ -281,8 +287,9 @@ sysconfig -q socket - - X </PRE> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/misc/perf-tuning.html b/usr.sbin/httpd/htdocs/manual/misc/perf-tuning.html index 956a7febbc5..46995c9eccd 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/perf-tuning.html +++ b/usr.sbin/httpd/htdocs/manual/misc/perf-tuning.html @@ -209,12 +209,12 @@ consider tuning these settings. Use the <CODE>mod_status</CODE> output as a guide. <P>Related to process creation is process death induced by the -<CODE>MaxRequestsPerChild</CODE> setting. By default this is 30, which -is probably far too low unless your server is using a module such as -<CODE>mod_perl</CODE> which causes children to have bloated memory -images. If your server is serving mostly static pages then consider -raising this value to something like 10000. The code is robust enough -that this shouldn't be a problem. +<CODE>MaxRequestsPerChild</CODE> setting. By default this is 0, which +means that there is no limit to the number of requests handled +per child. If your configuration currently has this set to some +very low number, such as 30, you may want to bump this up significantly. +If you are running SunOS or an old version of Solaris, limit this +to 10000 or so because of memory leaks. <P>When keep-alives are in use, children will be kept busy doing nothing waiting for more requests on the already open diff --git a/usr.sbin/httpd/htdocs/manual/misc/security_tips.html b/usr.sbin/httpd/htdocs/manual/misc/security_tips.html index 20942181fa0..d1b186d3caa 100644 --- a/usr.sbin/httpd/htdocs/manual/misc/security_tips.html +++ b/usr.sbin/httpd/htdocs/manual/misc/security_tips.html @@ -15,44 +15,80 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> <H1 ALIGN="CENTER">Security Tips for Server Configuration</H1> -<hr> +<HR> <P>Some hints and tips on security issues in setting up a web server. Some of the suggestions will be general, others specific to Apache. <HR> -<H2>Permissions on Log File Directories</H2> -<P>When Apache starts, it opens the log files as the user who started the -server before switching to the user defined in the -<a href="../mod/core.html#user"><b>User</b></a> directive. Anyone who -has write permission for the directory where any log files are -being written to can append pseudo-arbitrary data to any file on the -system which is writable by the user who starts Apache. Since the -server is normally started by root, you should <EM>NOT</EM> give anyone -write permission to the directory where logs are stored unless you -want them to have root access. +<H2><A NAME="serverroot">Permissions on ServerRoot Directories</A></H2> +<P>In typical operation, Apache is started by the root +user, and it switches to the user defined by the <A +HREF="../mod/core.html#user"><STRONG>User</STRONG></A> directive to serve hits. +As is the case with any command that root executes, you must take care +that it is protected from modification by non-root users. Not only +must the files themselves be writeable only by root, but so must the +directories, and parents of all directories. For example, if you +choose to place ServerRoot in <CODE>/usr/local/apache</CODE> then it is +suggested that you create that directory as root, with commands +like these: + +<BLOCKQUOTE><PRE> + mkdir /usr/local/apache + cd /usr/local/apache + mkdir bin conf logs + chown 0 . bin conf logs + chgrp 0 . bin conf logs + chmod 755 . bin conf logs +</PRE></BLOCKQUOTE> + +It is assumed that /, /usr, and /usr/local are only modifiable by root. +When you install the httpd executable, you should ensure that it is +similarly protected: + +<BLOCKQUOTE><PRE> + cp httpd /usr/local/apache/bin + chown 0 /usr/local/apache/bin/httpd + chgrp 0 /usr/local/apache/bin/httpd + chmod 511 /usr/local/apache/bin/httpd +</PRE></BLOCKQUOTE> + +<P>You can create an htdocs subdirectory which is modifiable by other +users -- since root never executes any files out of there, and shouldn't +be creating files in there. + +<P>If you allow non-root users to modify any files that root either +executes or writes on then you open your system to root compromises. +For example, someone could replace the httpd binary so that the next +time you start it, it will execute some arbitrary code. If the logs +directory is writeable (by a non-root user), someone +could replace a log file with a symlink to some other system file, +and then root might overwrite that file with arbitrary data. If the +log files themselves are writeable (by a non-root user), then someone +may be able to overwrite the log itself with bogus data. <P> <HR> <H2>Server Side Includes</H2> <P>Server side includes (SSI) can be configured so that users can execute arbitrary programs on the server. That thought alone should send a shiver -down the spine of any sys-admin.<p> +down the spine of any sys-admin.<P> One solution is to disable that part of SSI. To do that you use the IncludesNOEXEC option to the <A HREF="../mod/core.html#options">Options</A> -directive.<p> +directive.<P> <HR> <H2>Non Script Aliased CGI</H2> -<P>Allowing users to execute <B>CGI</B> scripts in any directory should only +<P>Allowing users to execute <STRONG>CGI</STRONG> scripts in any directory +should only be considered if; <OL> <LI>You trust your users not to write scripts which will deliberately or @@ -60,26 +96,27 @@ accidentally expose your system to an attack. <LI>You consider security at your site to be so feeble in other areas, as to make one more potential hole irrelevant. <LI>You have no users, and nobody ever visits your server. -</OL><p> +</OL><P> <HR> <H2>Script Alias'ed CGI</H2> -<P>Limiting <B>CGI</B> to special directories gives the admin control over +<P>Limiting <STRONG>CGI</STRONG> to special directories gives the admin +control over what goes into those directories. This is inevitably more secure than -non script aliased CGI, but <strong>only if users with write access to the -directories are trusted</strong> or the admin is willing to test each new CGI +non script aliased CGI, but <STRONG>only if users with write access to the +directories are trusted</STRONG> or the admin is willing to test each new CGI script/program for potential security holes.<P> -Most sites choose this option over the non script aliased CGI approach.<p> +Most sites choose this option over the non script aliased CGI approach.<P> <HR> <H2>CGI in general</H2> <P>Always remember that you must trust the writers of the CGI script/programs or your ability to spot potential security holes in CGI, whether they were -deliberate or accidental.<p> +deliberate or accidental.<P> All the CGI scripts will run as the same user, so they have potential to -conflict (accidentally or deliberately) with other scripts e.g. +conflict (accidentally or deliberately) with other scripts <EM>e.g.</EM> User A hates User B, so he writes a script to trash User B's CGI database. One program which can be used to allow scripts to run as different users is <A HREF="../suexec.html">suEXEC</A> which is @@ -93,21 +130,21 @@ the Apache server code. Another popular way of doing this is with <H2>Stopping users overriding system wide settings...</H2> <P>To run a really tight ship, you'll want to stop users from setting up <CODE>.htaccess</CODE> files which can override security features -you've configured. Here's one way to do it...<p> +you've configured. Here's one way to do it...<P> In the server configuration file, put -<blockquote><code> -<Directory /> <br> -AllowOverride None <br> -Options None <br> -allow from all <br> -</Directory> <br> -</code></blockquote> +<BLOCKQUOTE><CODE> +<Directory /> <BR> +AllowOverride None <BR> +Options None <BR> +allow from all <BR> +</Directory> <BR> +</CODE></BLOCKQUOTE> Then setup for specific directories<P> This stops all overrides, Includes and accesses in all directories apart -from those named.<p> +from those named.<P> <HR> <H2> Protect server files by default @@ -176,19 +213,30 @@ Also be wary of playing games with the >UserDir</A> directive; setting it to something like <SAMP>"./"</SAMP> would have the same effect, for root, as the first example above. +If you are using Apache 1.3 or above, we strongly recommend that you +include the following line in your server configuration files: +</P> +<DL> + <DD><SAMP>UserDir disabled root</SAMP> + </DD> +</DL> <HR> <P>Please send any other useful security tips to The Apache Group by filling out a -<A HREF="http://www.apache.org/bugdb.cgi">problem report</A>, or by -sending mail to -<A HREF="mailto:apache-bugs@mail.apache.org">apache-bugs@mail.apache.org</A> -<p> +<A HREF="http://www.apache.org/bug_report.html">problem report</A>. +If you are confident you have found a security bug in the Apache +source code itself, <A +HREF="http://www.apache.org/security_report.html">please let us +know</A>. + +<P> <HR> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/core.html b/usr.sbin/httpd/htdocs/manual/mod/core.html index f7a38be36bc..b189202b797 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/core.html +++ b/usr.sbin/httpd/htdocs/manual/mod/core.html @@ -55,6 +55,7 @@ always available. <LI><A HREF="#keepalive">KeepAlive</A> <LI><A HREF="#keepalivetimeout">KeepAliveTimeout</A> <LI><A HREF="#limit"><Limit></A> +<LI><A HREF="#limitexcept"><LimitExcept></A> <LI><A HREF="#limitrequestbody">LimitRequestBody</A> <LI><A HREF="#limitrequestfields">LimitRequestFields</A> <LI><A HREF="#limitrequestfieldsize">LimitRequestFieldsize</A> @@ -81,6 +82,7 @@ always available. <LI><A HREF="#rlimitnproc">RLimitNPROC</A> <LI><A HREF="#satisfy">Satisfy</A> <LI><A HREF="#scoreboardfile">ScoreBoardFile</A> +<LI><A HREF="#scriptinterpretersource">ScriptInterpreterSource</A> <LI><A HREF="#sendbuffersize">SendBufferSize</A> <LI><A HREF="#serveradmin">ServerAdmin</A> <LI><A HREF="#serveralias">ServerAlias</A> @@ -664,7 +666,8 @@ page for more details. The directory sections typically occur in the access.conf file, but they may appear in any configuration file. <Directory> directives cannot -nest, and cannot appear in a <A HREF="#limit"><Limit></A> section. +nest, and cannot appear in a <A HREF="#limit"><Limit></A> or +<A HREF="#limitexcept"><LimitExcept></A> section. <P> <STRONG>See also</STRONG>: <A HREF="../sections.html">How Directory, @@ -824,7 +827,12 @@ responses.</A><P><HR> <A HREF="directive-dict.html#Default" REL="Help" -><STRONG>Default:</STRONG></A> <CODE>ErrorLog logs/error_log</CODE><BR> +><STRONG>Default:</STRONG></A> <CODE>ErrorLog logs/error_log</CODE> (Unix)<BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>ErrorLog logs/error.log</CODE> + (Windows and OS/2)<BR> <A HREF="directive-dict.html#Context" REL="Help" @@ -1319,24 +1327,57 @@ applies. REL="Help" ><STRONG>Status:</STRONG></A> core<P> -<Limit> and </Limit> are used to enclose a group of -access control directives which will then apply only to the specified -access methods, where <EM>method</EM> is any valid HTTP method. -Any directive except another <Limit> or -<A HREF="#directory"><Directory></A> may be used; the majority will be -unaffected by the <Limit>. Example: +Access controls are normally effective for <STRONG>all</STRONG> access +methods, and this is the usual desired behaviour. <STRONG>In the +general case, access control directives should not be placed within a +<CODE><limit></CODE> section.</STRONG> + +<P>The purpose of the <Limit> directive is to restrict the effect +of the access controls to the nominated HTTP methods. For all other +methods, the access restrictions that are enclosed in the +<Limit> bracket <STRONG>will have no effect</STRONG>. The +following example applies the access control only to the methods POST, +PUT, and DELETE, leaving all other methods unprotected: + <BLOCKQUOTE><CODE> -<Limit GET POST><BR> +<Limit POST PUT DELETE><BR> require valid-user<BR> </Limit></CODE></BLOCKQUOTE> -If an access control directive appears outside a <Limit> -directive, then it applies to all access methods. The method names -listed can be one or more of: GET, POST, PUT, DELETE, CONNECT or -OPTIONS. <STRONG>The method name is case-sensitive.</STRONG> -If GET is used it will also restrict HEAD requests. -<STRONG>If you wish to limit all methods, do not include any -<Limit> directive at all.</STRONG> +The method names listed can be one or more of: GET, POST, PUT, DELETE, +CONNECT, OPTIONS, TRACE, PATCH, PROPFIND, PROPPATCH, MKCOL, COPY, +MOVE, LOCK, and UNLOCK. <STRONG>The method name is +case-sensitive.</STRONG> If GET is used it will also restrict HEAD +requests. + +<P><HR> + +<H2><A NAME="limitexcept"><LimitExcept> directive</A></H2> +<!--%plaintext <?INDEX {\tt LimitExcept} section directive> --> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> + <LimitExcept <EM>method method</EM> ... > ... </LimitExcept><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> any<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> core<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Available in Apache 1.3.5 and later<P> + +<LimitExcept> and </LimitExcept> are used to enclose a group of +access control directives which will then apply to any HTTP access method +<STRONG>not</STRONG> listed in the arguments; i.e., it is the opposite of a +<A HREF="#limit"><Limit></A> section and can be used to control both +standard and nonstandard/unrecognized methods. See the documentation for +<A HREF="#limit"><Limit></A> for more details. <P><HR> @@ -1967,6 +2008,10 @@ number of processes when the server load reduces. <P>This directive has no effect on Win32. +<P><STRONG>NOTE:</STRONG> For <EM>KeepAlive</EM> requests, only the first +request is counted towards this limit. In effect, it changes the +behavior to limit the number of <EM>connections</EM> per child. + <P><HR> <H2><A NAME="maxspareservers">MaxSpareServers directive</A></H2> @@ -2336,24 +2381,25 @@ Only users in the named groups can access the directory.<P> All valid users can access the directory. </UL> <P> -If <CODE>require</CODE> appears in a <A HREF="#limit"><Limit></A> -section, then it restricts access to the named methods, otherwise -it restricts access for all methods. Example: +Require must be accompanied by <A HREF="#authname">AuthName</A> and +<A HREF="#authtype">AuthType</A> directives, and directives such as +<A HREF="mod_auth.html#authuserfile">AuthUserFile</A> and +<A HREF="mod_auth.html#authgroupfile">AuthGroupFile</A> (to define users and +groups) in order to work correctly. Example: <BLOCKQUOTE><CODE> AuthType Basic<BR> -AuthName somedomain<BR> +AuthName "Restricted Directory"<BR> AuthUserFile /web/users<BR> AuthGroupFile /web/groups<BR> -<Limit GET POST><BR> require group admin<BR> -</Limit> </CODE></BLOCKQUOTE> -Require must be accompanied by <A HREF="#authname">AuthName</A> and -<A HREF="#authtype">AuthType</A> directives, and directives such as -<A HREF="mod_auth.html#authuserfile">AuthUserFile</A> and -<A HREF="mod_auth.html#authgroupfile">AuthGroupFile</A> (to define users and -groups) in order to work correctly.<P><HR> +Access controls which are applied in this way are effective for +<STRONG>all</STRONG> methods. <STRONG>This is what is normally +desired.</STRONG> If you wish to apply access controls only to +specific methods, while leaving other methods unprotected, then place +the <CODE>require</CODE> statement into a <A +HREF="#limit"><Limit></A> section<P><HR> <H2><A NAME="resourceconfig">ResourceConfig directive</A></H2> <!--%plaintext <?INDEX {\tt ResourceConfig} directive> --> @@ -2420,6 +2466,11 @@ that the limit should be set to the maximum allowed by the operating system configuration. Raising the maximum resource limit requires that the server is running as root, or in the initial startup phase.<P> +This applies to processes forked off from Apache children servicing requests, +not the Apache children themselves. This includes CGI scripts and SSI +exec commands, but not any processes forked off from the Apache parent +such as piped logs.<P> + CPU resource limits are expressed in seconds per process.<P> See also <A HREF="#rlimitmem">RLimitMEM</A> or @@ -2458,6 +2509,11 @@ limit should be set to the maximum allowed by the operating system configuration. Raising the maximum resource limit requires that the server is running as root, or in the initial startup phase.<P> +This applies to processes forked off from Apache children servicing requests, +not the Apache children themselves. This includes CGI scripts and SSI +exec commands, but not any processes forked off from the Apache parent +such as piped logs.<P> + Memory resource limits are expressed in bytes per process.<P> See also <A HREF="#rlimitcpu">RLimitCPU</A> or @@ -2496,6 +2552,11 @@ that the limit should be set to the maximum allowed by the operating system configuration. Raising the maximum resource limit requires that the server is running as root, or in the initial startup phase.<P> +This applies to processes forked off from Apache children servicing requests, +not the Apache children themselves. This includes CGI scripts and SSI +exec commands, but not any processes forked off from the Apache parent +such as piped logs.<P> + Process limits control the number of processes per user.<P> Note: If CGI processes are <STRONG>not</STRONG> running under userids other @@ -2599,6 +2660,32 @@ release. (Prior to 1.3b4, <CODE>HAVE_SHMGET</CODE> would have sufficed.)<P> <P><HR> +<H2><A NAME="scriptinterpretersource">ScriptInterpreterSource directive</A></H2> +<!--%plaintext <?INDEX {\tt ScriptInterpreterSource} directive> --> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ScriptInterpreterSource <EM>'registry' or 'script'</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>ScriptInterpreterSource script</CODE> +<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> core (Windows only)<P> + +This directive is used to control how Apache 1.3.5 and later finds the interpreter +used to run CGI scripts. The default technique is to use the interpreter pointed to by +the #! line in the script. Setting ScriptInterpreterSource registry will cause the +Windows Registry to be searched using the script file extension (e.g., .pl) as a search key. +<P><HR> + <H2><A NAME="sendbuffersize">SendBufferSize directive</A></H2> <!--%plaintext <?INDEX {\tt SendBufferSize} directive> --> <A @@ -3005,12 +3092,11 @@ a packet is sent. <H2><A NAME="usecanonicalname">UseCanonicalName directive</A></H2> <!--%plaintext <?INDEX {\tt UseCanonicalName} directive> --> <A HREF="directive-dict.html#Syntax" REL="Help"> -<STRONG>Syntax:</STRONG></A> UseCanonicalName <EM>on|off</EM><BR> +<STRONG>Syntax:</STRONG></A> UseCanonicalName <EM>on|off|dns</EM><BR> <A HREF="directive-dict.html#Default" REL="Help"> <STRONG>Default:</STRONG></A> <CODE>UseCanonicalName on</CODE><BR> <A HREF="directive-dict.html#Context" REL="Help"> -<STRONG>Context:</STRONG></A> server config, virtual host, directory, .htaccess -<BR> +<STRONG>Context:</STRONG></A> server config, virtual host<BR> <A HREF="directive-dict.html#Override" REL="Help"> <STRONG>Override:</STRONG></A> Options<BR> <A HREF="directive-dict.html#Compatibility" REL="Help"> @@ -3045,6 +3131,12 @@ for <CODE>www</CODE> and once again for <CODE>www.domain.com</CODE>). But if <CODE>UseCanonicalName</CODE> is set off, then Apache will redirect to <CODE>http://www/splat/</CODE>. +<P>There is a third option, <CODE>UseCanonicalName DNS</CODE>, which +is intended for use with mass IP-based virtual hosting to support +ancient clients that do not provide a <CODE>Host:</CODE> header. With +this option Apache does a reverse DNS lookup on the server IP address +that the client connected to in order to work out self-referential URLs. + <P><STRONG>Warning:</STRONG> if CGIs make assumptions about the values of <CODE>SERVER_NAME</CODE> they may be broken by this option. The client is essentially free to give whatever value they want as a hostname. diff --git a/usr.sbin/httpd/htdocs/manual/mod/directive-dict.html b/usr.sbin/httpd/htdocs/manual/mod/directive-dict.html index 831cf838fe3..6cccc5a2ca6 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/directive-dict.html +++ b/usr.sbin/httpd/htdocs/manual/mod/directive-dict.html @@ -134,8 +134,11 @@ <DT><STRONG>directory</STRONG> </DT> <DD>A directive marked as being valid in this context may be used - inside <SAMP><Directory></SAMP> containers in the server - configuration files. + inside <SAMP><Directory></SAMP>, + <SAMP><Location></SAMP>, and <SAMP><Files></SAMP> + containers in the server configuration files, subject to the + restrictions outlined in <A HREF="../sections.html">How Directory, + Location and Files sections work</A>. <P> </P> </DD> diff --git a/usr.sbin/httpd/htdocs/manual/mod/directives.html b/usr.sbin/httpd/htdocs/manual/mod/directives.html index 39394ceb305..993bccf805d 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/directives.html +++ b/usr.sbin/httpd/htdocs/manual/mod/directives.html @@ -96,6 +96,7 @@ of the terms used in their descriptions available. <LI><A HREF="mod_autoindex.html#defaulticon">DefaultIcon</A> <LI><A HREF="mod_mime.html#defaultlanguage">DefaultLanguage</A> <LI><A HREF="core.html#defaulttype">DefaultType</A> +<LI><A HREF="mod_define.html#define">Define</A> <LI><A HREF="mod_access.html#deny">deny</A> <LI><A HREF="core.html#directory"><Directory></A> <LI><A HREF="core.html#directorymatch"><DirectoryMatch></A> @@ -129,6 +130,7 @@ of the terms used in their descriptions available. <LI><A HREF="core.html#keepalivetimeout">KeepAliveTimeout</A> <LI><A HREF="mod_negotiation.html#languagepriority">LanguagePriority</A> <LI><A HREF="core.html#limit"><Limit></A> +<LI><A HREF="core.html#limitexcept"><LimitExcept></A> <LI><A HREF="core.html#limitrequestbody">LimitRequestBody</A> <LI><A HREF="core.html#limitrequestfields">LimitRequestFields</A> <LI><A HREF="core.html#limitrequestfieldsize">LimitRequestFieldsize</A> @@ -173,6 +175,7 @@ of the terms used in their descriptions available. <LI><A HREF="mod_alias.html#redirecttemp">RedirectTemp</A> <LI><A HREF="mod_log_referer.html#refererignore">RefererIgnore</A> <LI><A HREF="mod_log_referer.html#refererlog">RefererLog</A> +<LI><A HREF="mod_mime#removehandler">RemoveHandler</A> <LI><A HREF="core.html#require">require</A> <LI><A HREF="core.html#resourceconfig">ResourceConfig</A> <LI><A HREF="mod_rewrite.html#RewriteBase">RewriteBase</A> @@ -192,6 +195,7 @@ of the terms used in their descriptions available. <LI><A HREF="mod_actions.html#script">Script</A> <LI><A HREF="mod_alias.html#scriptalias">ScriptAlias</A> <LI><A HREF="mod_alias.html#scriptaliasmatch">ScriptAliasMatch</A> +<LI><A HREF="core.html#scriptinterpretersource">ScriptInterpreterSource</A> <LI><A HREF="mod_cgi.html#scriptlog">ScriptLog</A> <LI><A HREF="mod_cgi.html#scriptlogbuffer">ScriptLogBuffer</A> <LI><A HREF="mod_cgi.html#scriptloglength">ScriptLogLength</A> @@ -208,19 +212,22 @@ of the terms used in their descriptions available. <LI><A HREF="mod_setenvif.html#setenvif">SetEnvIf</A> <LI><A HREF="mod_setenvif.html#SetEnvIfNoCase">SetEnvIfNoCase</A> <LI><A HREF="mod_mime.html#sethandler">SetHandler</A> -<LI><A HREF="mod_ssl/ssl_reference.html#SSLMutex">SSLMutex</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLPassPhraseDialog">SSLPassPhraseDialog</A> +<LI><A HREF="mod_ssl/ssl_reference.html#SSLMutex">SSLMutex</A> +<LI><A HREF="mod_ssl/ssl_reference.html#SSLRandomSeed">SSLRandomSeed</A> +<LI><A HREF="mod_ssl/ssl_reference.html#SSLSessionCache">SSLSessionCache</A> +<LI><A HREF="mod_ssl/ssl_reference.html#SSLSessionCacheTimeout">SSLSessionCacheTimeout</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLEngine">SSLEngine</A> +<LI><A HREF="mod_ssl/ssl_reference.html#SSLProtocol">SSLProtocol</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLCipherSuite">SSLCipherSuite</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLCertificateFile">SSLCertificateFile</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLCertificateKeyFile">SSLCertificateKeyFile</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLCACertificatePath">SSLCACertificatePath</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLCACertificateFile">SSLCACertificateFile</A> -<LI><A HREF="mod_ssl/ssl_reference.html#SSLCACertificateReqFile">SSLCACertificateReqFile</A> +<LI><A HREF="mod_ssl/ssl_reference.html#SSLCARevocationPath">SSLCARevocationPath</A> +<LI><A HREF="mod_ssl/ssl_reference.html#SSLCARevocationFile">SSLCARevocationFile</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLVerifyClient">SSLVerifyClient</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLVerifyDepth">SSLVerifyDepth</A> -<LI><A HREF="mod_ssl/ssl_reference.html#SSLSessionCache">SSLSessionCache</A> -<LI><A HREF="mod_ssl/ssl_reference.html#SSLSessionCacheTimeout">SSLSessionCacheTimeout</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLLog">SSLLog</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLLogLevel">SSLLogLevel</A> <LI><A HREF="mod_ssl/ssl_reference.html#SSLOptions">SSLOptions</A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/index.html b/usr.sbin/httpd/htdocs/manual/mod/index.html index 117021686ef..564f76b5ef8 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/index.html +++ b/usr.sbin/httpd/htdocs/manual/mod/index.html @@ -48,6 +48,8 @@ Apache distribution. See also the complete alphabetical list of <DD>User authentication using Berkeley DB files. <DT><A HREF="mod_auth_dbm.html">mod_auth_dbm</A> <DD>User authentication using DBM files. +<DT><A HREF="mod_auth_digest.html">mod_auth_digest</A> +<DD>MD5 authentication (experimental) <DT><A HREF="mod_autoindex.html">mod_autoindex</A> <DD>Automatic directory listings. <DT><A HREF="mod_browser.html">mod_browser</A> Apache 1.2.* only @@ -60,6 +62,8 @@ Apache distribution. See also the complete alphabetical list of <DT><A HREF="mod_cookies.html">mod_cookies</A> up to Apache 1.1.1 <DD>Support for Netscape-like cookies. Replaced in Apache 1.2 by mod_usertrack +<DT><A HREF="mod_define.html">mod_define</A> +<DD>Variable Definition for Arbitrary Directives <DT><A HREF="mod_digest.html">mod_digest</A> <DD>MD5 authentication <DT><A HREF="mod_dir.html">mod_dir</A> @@ -121,6 +125,8 @@ mod_log_config module in Apache 1.2 and up <DD>Generate unique request identifier for every request <DT><A HREF="mod_usertrack.html">mod_usertrack</A> Apache 1.2 and up <DD>User tracking using Cookies (replacement for mod_cookies.c) +<DT><A HREF="mod_vhost_alias.html">mod_vhost_alias</A> Apache 1.3.7 and up +<DD>Support for dynamically configured mass virtual hosting </DL> <HR> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_access.html b/usr.sbin/httpd/htdocs/manual/mod/mod_access.html index 0787282a9db..ff1a01d7b0c 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_access.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_access.html @@ -15,170 +15,308 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<H1 ALIGN="CENTER">Module mod_access</h1> - -This module is contained in the <code>mod_access.c</code> file, and +<H1 ALIGN="CENTER">Module mod_access</H1> +<P> +This module is contained in the <CODE>mod_access.c</CODE> file, and is compiled in by default. It provides access control based on client hostname or IP address. +</P> + +<UL> +<LI><A HREF="#allow">allow</A> +<LI><A HREF="#allowfromenv">allow from env=</A> +<LI><A HREF="#deny">deny</A> +<LI><A HREF="#denyfromenv">deny from env=</A> +<LI><A HREF="#order">order</A> +</UL> +<HR> -<menu> -<li><A HREF="#allow">allow</A> -<li><A HREF="#allowfromenv">allow from env=</A> -<li><A HREF="#deny">deny</A> -<li><A HREF="#denyfromenv">deny from env=</A> -<li><A HREF="#order">order</A> -</menu> -<hr> - - -<A name="allow"><h2>allow</h2></A> +<H2><A NAME="allow">allow directive</A></H2> +<P> <!--%plaintext <?INDEX {\tt allow} directive> --> -<strong>Syntax:</strong> allow from <em>host host ...</em><br> -<Strong>Context:</strong> directory, .htaccess<br> -<Strong>Override:</strong> Limit<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_access<p> - +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> allow from <EM>host host ...</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Limit<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_access +</P> +<P> The allow directive affects which hosts can access a given directory. -<em>Host</em> is one of the following: -<dl> -<dt><code>all</code> -<dd>all hosts are allowed access -<dt>A (partial) domain-name -<dd>host whose name is, or ends in, this string are allowed access. -<dt>A full IP address -<dd>An IP address of a host allowed access -<dt>A partial IP address -<dd>The first 1 to 3 bytes of an IP address, for subnet restriction. -</dl> - -Example:<blockquote><code>allow from .ncsa.uiuc.edu</code></blockquote> -All hosts in the specified domain are allowed access.<p> - -Note that this compares whole components; <code>bar.edu</code> -would not match <code>foobar.edu</code>.<p> - +<EM>Host</EM> is one of the following: +</P> +<DL> +<DT><CODE>all</CODE> +<DD>All hosts are allowed access +<DT>A (partial) domain-name +<DD>Hosts whose names match, or end in, this string are allowed access. +<DT>A full IP address +<DD>An IP address of a host allowed access +<DT>A partial IP address +<DD>The first 1 to 3 bytes of an IP address, for subnet restriction. +<DT>A network/netmask pair (<STRONG>Apache 1.3 and later</STRONG>) +<DD>A network a.b.c.d, and a netmask w.x.y.z. For more fine-grained subnet + restriction. (<EM>i.e.</EM>, 10.1.0.0/255.255.0.0) +<DT>A network/nnn CIDR specification (<STRONG>Apache 1.3 and later</STRONG>) +<DD>Similar to the previous case, except the netmask consists of nnn + high-order 1 bits. (<EM>i.e.</EM>, 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0) +</DL> +<P> +Example: +</P> +<BLOCKQUOTE><CODE>allow from .ncsa.uiuc.edu</CODE></BLOCKQUOTE> +<P> +All hosts in the specified domain are allowed access. +</P> +<P> +Note that this compares whole components; <CODE>bar.edu</CODE> +would not match <CODE>foobar.edu</CODE>. +</P> +<P> See also <A HREF="#deny">deny</A>, <A HREF="#order">order</A>, and -<a href="mod_browser.html#browsermatch">BrowserMatch</a>.<p> - -<a name="allowfromenv"><strong>Syntax:</strong> allow from env=<em>variablename</em></a><br> -<Strong>Context:</strong> directory, .htaccess<br> -<Strong>Override:</strong> Limit<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_access<br> -<strong>Compatibility:</strong> Apache 1.2 and above<p> - +<A HREF="mod_browser.html#browsermatch">BrowserMatch</A>. +</P> + +<P> +<A NAME="allowfromenv"><STRONG>Syntax:</STRONG> allow from + env=<EM>variablename</EM></A><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Limit<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_access<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Apache 1.2 and above +</P> +<P> The allow from env directive controls access to a directory by the existence (or non-existence) of an environment variable. - -Example:<blockquote><pre> +</P> +<P> +Example: +</P> +<BLOCKQUOTE><PRE> BrowserMatch ^KnockKnock/2.0 let_me_in <Directory /docroot> -order allow,deny -allow from env=let_me_in -deny from all + order deny,allow + deny from all + allow from env=let_me_in </Directory> -</pre></blockquote> - +</PRE></BLOCKQUOTE> +In this case browsers with the user-agent string <TT>KnockKnock/2.0</TT> will +be allowed access, and all others will be denied. +<P> See also <A HREF="#denyfromenv">deny from env</A> -and <A HREF="#order">order</A>.<p><hr> +and <A HREF="#order">order</A>. +</P> +<HR> -<A name="deny"><h2>deny</h2></A> +<H2><A NAME="deny">deny directive</A></H2> +<P> <!--%plaintext <?INDEX {\tt deny} directive> --> -<strong>Syntax:</strong> deny from <em>host host ...</em><br> -<Strong>Context:</strong> directory, .htaccess<br> -<Strong>Override:</strong> Limit<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_access<p> - +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> deny from <EM>host host ...</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Limit<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_access +</P> +<P> The deny directive affects which hosts can access a given directory. -<em>Host</em> is one of the following: -<dl> -<dt><code>all</code> -<dd>all hosts are denied access -<dt>A (partial) domain-name -<dd>host whose name is, or ends in, this string are denied access. -<dt>A full IP address -<dd>An IP address of a host denied access -<dt>A partial IP address -<dd>The first 1 to 3 bytes of an IP address, for subnet restriction. -</dl> - -Example:<blockquote><code>deny from 16</code></blockquote> -All hosts in the specified network are denied access.<p> - -Note that this compares whole components; <code>bar.edu</code> -would not match <code>foobar.edu</code>.<p> - -See also <A HREF="#allow">allow</A> and <A HREF="#order">order</A>.<p> - -<a name="denyfromenv"><strong>Syntax:</strong> deny from env=<em>variablename</em></a><br> -<Strong>Context:</strong> directory, .htaccess<br> -<Strong>Override:</strong> Limit<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_access<br> -<strong>Compatibility:</strong> Apache 1.2 and above<p> - +<EM>Host</EM> is one of the following: +</P> +<DL> +<DT><CODE>all</CODE> +<DD>all hosts are denied access +<DT>A (partial) domain-name +<DD>host whose name is, or ends in, this string are denied access. +<DT>A full IP address +<DD>An IP address of a host denied access +<DT>A partial IP address +<DD>The first 1 to 3 bytes of an IP address, for subnet restriction. +<DT>A network/netmask pair (<STRONG>Apache 1.3 and later</STRONG>) +<DD>A network a.b.c.d, and a netmask w.x.y.z. For more fine-grained subnet + restriction. (<EM>i.e.</EM>, 10.1.0.0/255.255.0.0) +<DT>A network/nnn CIDR specification (<STRONG>Apache 1.3 and later</STRONG>) +<DD>Similar to the previous case, except the netmask consists of nnn + high-order 1 bits. (<EM>i.e.</EM>, 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0) +</DL> +<P> +Example: +</P> +<BLOCKQUOTE><CODE>deny from 16</CODE></BLOCKQUOTE> +<P> +All hosts in the specified network are denied access. +</P> +<P> +Note that this compares whole components; <CODE>bar.edu</CODE> +would not match <CODE>foobar.edu</CODE>. +</P> +<P> +See also <A HREF="#allow">allow</A> and <A HREF="#order">order</A>. +</P> + +<P> +<A NAME="denyfromenv"><STRONG>Syntax:</STRONG> deny from + env=<EM>variablename</EM></A><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Limit<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_access<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Apache 1.2 and above +</P> +<P> The deny from env directive controls access to a directory by the existence (or non-existence) of an environment variable. - -Example:<blockquote><pre> +</P> +<P> +Example: +</P> +<BLOCKQUOTE><PRE> BrowserMatch ^BadRobot/0.9 go_away <Directory /docroot> -order deny,allow -deny from env=go_away -allow from all + order allow,deny + allow from all + deny from env=go_away </Directory> -</pre></blockquote> +</PRE></BLOCKQUOTE> +In this case browsers with the user-agent string <TT>BadRobot/0.9</TT> will +be denied access, and all others will be allowed. +<P> See also <A HREF="#allowfromenv">allow from env</A> -and <A HREF="#order">order</A>.<p><hr> +and <A HREF="#order">order</A>. +</P> +<HR> -<A name="order"><h2>order</h2></A> +<H2><A NAME="order">order directive</A></H2> +<P> <!--%plaintext <?INDEX {\tt order} directive> --> -<strong>Syntax:</strong> order <em>ordering</em><br> -<strong>Default:</strong> <code>order deny,allow</code><br> -<strong>Context:</strong> directory, .htaccess<br> -<strong>Override:</strong> Limit<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_access<p> - +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> order <EM>ordering</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>order deny,allow</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Limit<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_access +</P> +<P> The order directive controls the order in which <A HREF="#allow">allow</A> and -<A HREF="#deny">deny</A> directives are evaluated. <em>Ordering</em> is one +<A HREF="#deny">deny</A> directives are evaluated. <EM>Ordering</EM> is one of -<dl> -<dt>deny,allow -<dd>the deny directives are evaluated before the allow directives. (The +</P> +<DL> +<DT>deny,allow +<DD>the deny directives are evaluated before the allow directives. (The initial state is OK.) -<dt>allow,deny -<dd>the allow directives are evaluated before the deny directives. (The +<DT>allow,deny +<DD>the allow directives are evaluated before the deny directives. (The initial state is FORBIDDEN.) -<dt>mutual-failure -<dd>Only those hosts which appear on the allow list and do not appear +<DT>mutual-failure +<DD>Only those hosts which appear on the allow list and do not appear on the deny list are granted access. (The initial state is irrelevant.) -</dl> - -Note that in all cases every <code>allow</code> and <code>deny</code> -statement is evaluated, there is no "short-circuiting". - -<p>Example: -<blockquote><code> -order deny,allow<br> -deny from all<br> -allow from .ncsa.uiuc.edu<br> -</code></blockquote> +</DL> +<P> +Keywords may only be separated by a comma; no whitespace is allowed between +them. +<STRONG>Note that in all cases every <CODE>allow</CODE> and <CODE>deny</CODE> +statement is evaluated, there is no "short-circuiting".</STRONG> +</P> +<P> +Example: +</P> +<BLOCKQUOTE><CODE> + order deny,allow<BR> + deny from all<BR> + allow from .ncsa.uiuc.edu<BR> +</CODE></BLOCKQUOTE> +<P> Hosts in the ncsa.uiuc.edu domain are allowed access; all other hosts are denied access. - +</P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> @@ -186,4 +324,3 @@ denied access. </BODY> </HTML> - diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_alias.html b/usr.sbin/httpd/htdocs/manual/mod/mod_alias.html index affa6d3cc9f..a30b9a0dedf 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_alias.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_alias.html @@ -227,7 +227,8 @@ the function <CODE>send_error_response</CODE> in http_protocol.c). <A HREF="directive-dict.html#Context" REL="Help" -><STRONG>Context:</STRONG></A> server config, virtual host<BR> +><STRONG>Context:</STRONG></A> server config, virtual host, directory, + .htaccess<BR> <A HREF="directive-dict.html#Override" REL="Help" @@ -292,7 +293,7 @@ one might use: <P> This directive makes the client know that the Redirect is only temporary (status 302). Exactly equivalent to <CODE>Redirect -temporary</CODE>. +temp</CODE>. </P> <HR> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_auth.html b/usr.sbin/httpd/htdocs/manual/mod/mod_auth.html index 9fa7c47159f..f576088b048 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_auth.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_auth.html @@ -15,139 +15,209 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<H1 ALIGN="CENTER">Module mod_auth</h1> +<H1 ALIGN="CENTER">Module mod_auth</H1> -This module is contained in the <code>mod_auth.c</code> file, and +This module is contained in the <CODE>mod_auth.c</CODE> file, and is compiled in by default. It provides for user authentication using textual files. -<menu> -<li><A HREF="#authgroupfile">AuthGroupFile</A> -<li><A HREF="#authuserfile">AuthUserFile</A> -<li><A HREF="#authauthoritative">AuthAuthoritative</A> -</menu> -<hr> +<MENU> +<LI><A HREF="#authgroupfile">AuthGroupFile</A> +<LI><A HREF="#authuserfile">AuthUserFile</A> +<LI><A HREF="#authauthoritative">AuthAuthoritative</A> +</MENU> +<HR> -<A name="authgroupfile"><h2>AuthGroupFile</h2></A> +<H2><A NAME="authgroupfile">AuthGroupFile</A></H2> <!--%plaintext <?INDEX {\tt AuthGroupFile} directive> --> -<strong>Syntax:</strong> AuthGroupFile <em>filename</em><br> -<Strong>Context:</strong> directory, .htaccess<br> -<Strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_auth<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> AuthGroupFile <EM>filename</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth<P> The AuthGroupFile directive sets the name of a textual file containing the list -of user groups for user authentication. <em>Filename</em> is the absolute path -to the group file.<p> +of user groups for user authentication. <EM>Filename</EM> is the path +to the group file. If it is not absolute (<EM>i.e.</EM>, if it +doesn't begin with a slash), it is treated as relative to the ServerRoot. +<P> Each line of the group file contains a groupname followed by a colon, followed by the member usernames separated by spaces. Example: -<blockquote><code>mygroup: bob joe anne</code></blockquote> -Note that searching large groups files is <em>very</em> inefficient; +<BLOCKQUOTE><CODE>mygroup: bob joe anne</CODE></BLOCKQUOTE> +Note that searching large text files is <EM>very</EM> inefficient; <A HREF="mod_auth_dbm.html#authdbmgroupfile">AuthDBMGroupFile</A> should -be used instead.<p> +be used instead.<P> Security: make sure that the AuthGroupFile is stored outside the -document tree of the web-server; do <em>not</em> put it in the directory that -it protects. Otherwise, clients will be able to download the AuthGroupFile.<p> +document tree of the web-server; do <EM>not</EM> put it in the directory that +it protects. Otherwise, clients will be able to download the AuthGroupFile.<P> See also <A HREF="core.html#authname">AuthName</A>, <A HREF="core.html#authtype">AuthType</A> and -<A HREF="#authuserfile">AuthUserFile</A>.<p><hr> +<A HREF="#authuserfile">AuthUserFile</A>.<P><HR> -<A name="authuserfile"><h2>AuthUserFile</h2></A> +<H2><A NAME="authuserfile">AuthUserFile</A></H2> <!--%plaintext <?INDEX {\tt AuthUserFile} directive> --> -<strong>Syntax:</strong> AuthUserFile <em>filename</em><br> -<Strong>Context:</strong> directory, .htaccess<br> -<Strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_auth<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> AuthUserFile <EM>filename</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth<P> The AuthUserFile directive sets the name of a textual file containing the list of users and passwords for user -authentication. <em>Filename</em> is the absolute path to the user -file.<p> Each line of the user file file contains a username followed +authentication. <EM>Filename</EM> is the path to the user +file. If it is not absolute (<EM>i.e.</EM>, if it doesn't begin with a +slash), it is treated as relative to the ServerRoot. +<P> Each line of the user file file contains a username followed by a colon, followed by the crypt() encrypted password. The behavior -of multiple occurrences of the same user is undefined.<p> Note that -searching user groups files is inefficient; <A -HREF="mod_auth_dbm.html#authdbmuserfile">AuthDBMUserFile</A> should be -used instead.<p> +of multiple occurrences of the same user is undefined. +<P> +The utility <code>htpasswd</code> which is installed as part of the +binary distribution, or which can be found in <code>src/support</code>, +is used to maintain this password file. See the <code>man</code> +page for more details. In short +<p> +<blockquote> + <code>htpasswd -c Filename username</code><br> + Create a password file 'Filename' with 'username' + as the initial ID. It will prompt for the password. + <code>htpasswd Filename username2</code><br> + Adds or modifies in password file 'Filename' the 'username'. +</blockquote> +<P> Note that +searching large text files is <EM>very</EM> inefficient; +<A HREF="mod_auth_dbm.html#authdbmuserfile">AuthDBMUserFile</A> should be +used instead. +<P> Security: make sure that the AuthUserFile is stored outside the -document tree of the web-server; do <em>not</em> put it in the directory that -it protects. Otherwise, clients will be able to download the AuthUserFile.<p> +document tree of the web-server; do <EM>not</EM> put it in the directory that +it protects. Otherwise, clients will be able to download the AuthUserFile.<P> See also <A HREF="core.html#authname">AuthName</A>, <A HREF="core.html#authtype">AuthType</A> and -<A HREF="#authgroupfile">AuthGroupFile</A>.<p> -<hr> -<A name="authauthoritative"><h2>AuthAuthoritative</h2></A> +<A HREF="#authgroupfile">AuthGroupFile</A>.<P> +<HR> +<H2><A NAME="authauthoritative">AuthAuthoritative</A></H2> <!--%plaintext <?INDEX {\tt AuthAuthoritative} directive> --> -<strong>Syntax:</strong> AuthAuthoritative < <strong> on</strong>(default) | off > <br> -<Strong>Context:</strong> directory, .htaccess<br> -<Strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_auth<p> - -Setting the AuthAuthoritative directive explicitly to <b>'off'</b> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> AuthAuthoritative < + <STRONG> on</STRONG>(default) | off > <BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth<P> + +Setting the AuthAuthoritative directive explicitly to <STRONG>'off'</STRONG> allows for both authentication and authorization to be passed on to -lower level modules (as defined in the <code>Configuration</code> and -<code>modules.c</code> files) if there is <b>no userID</b> or -<b>rule</b> matching the supplied userID. If there is a userID and/or +lower level modules (as defined in the <CODE>Configuration</CODE> and +<CODE>modules.c</CODE> files) if there is <STRONG>no userID</STRONG> or +<STRONG>rule</STRONG> matching the supplied userID. If there is a userID and/or rule specified; the usual password and access checks will be applied and a failure will give an Authorization Required reply. -<p> +<P> So if a userID appears in the database of more than one module; or if a valid require directive applies to more than one module; then the first module will verify the credentials; and no access is passed on; regardless of the AuthAuthoritative setting. -<p> +<P> A common use for this is in conjunction with one of the database -modules; such as <a -href="mod_auth_db.html"><code>mod_auth_db.c</code></a>, <a -href="mod_auth_dbm.html"><code>mod_auth_dbm.c</code></a>, <a -href="mod_auth_msql.html"><code>mod_auth_msql.c</code></a> and <a -href="mod_auth_anon.html"><code>mod_auth_anon.c</code></a>. These modules +modules; such as <A +HREF="mod_auth_db.html"><CODE>mod_auth_db.c</CODE></A>, <A +HREF="mod_auth_dbm.html"><CODE>mod_auth_dbm.c</CODE></A>, +<CODE>mod_auth_msql.c</CODE>, and <A +HREF="mod_auth_anon.html"><CODE>mod_auth_anon.c</CODE></A>. These modules supply the bulk of the user credential checking; but a few (administrator) related accesses fall through to a lower level with a well protected AuthUserFile. -<p> +<P> -<b>Default:</b> By default; control is not passed on; and an unknown +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> By default; control is not passed on; and an + unknown userID or rule will result in an Authorization Required reply. Not -setting it thus keeps the system secure; and forces an NSCA compliant +setting it thus keeps the system secure; and forces an NCSA compliant behaviour. -<p> +<P> Security: Do consider the implications of allowing a user to allow fall-through in his .htaccess file; and verify that this is really what you want; Generally it is easier to just secure a single .htpasswd file, than it is to secure a database such as mSQL. Make sure that the AuthUserFile is stored outside the document tree of the -web-server; do <em>not</em> put it in the directory that it +web-server; do <EM>not</EM> put it in the directory that it protects. Otherwise, clients will be able to download the AuthUserFile. -<p> +<P> See also <A HREF="core.html#authname">AuthName</A>, <A HREF="core.html#authtype">AuthType</A> and -<A HREF="#authgroupfile">AuthGroupFile</A>.<p> +<A HREF="#authgroupfile">AuthGroupFile</A>.<P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_auth_anon.html b/usr.sbin/httpd/htdocs/manual/mod/mod_auth_anon.html index b9ee13bcba6..2248c99a84d 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_auth_anon.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_auth_anon.html @@ -14,129 +14,220 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> <H1 ALIGN="CENTER">Module mod_auth_anon</H1> -This module is contained in the <code>mod_auth_anon.c</code> file and +This module is contained in the <CODE>mod_auth_anon.c</CODE> file and is not compiled in by default. It is only available in Apache 1.1 and later. It allows "anonymous" user access to authenticated areas. -<h2>Summary</h2> +<H2>Summary</H2> -It does access control in a manner similar to anonymous-ftp sites; i.e. +It does access control in a manner similar to anonymous-ftp sites; <EM>i.e.</EM> have a 'magic' user id 'anonymous' and the email address as a password. These email addresses can be logged. -<p> +<P> Combined with other (database) access control methods, this allows for effective user tracking and customization according to a user profile while still keeping the site open for 'unregistered' users. One advantage of using Auth-based user tracking is that, unlike magic-cookies and funny URL pre/postfixes, it is completely browser independent and it allows users to share URLs. -<p> - -<a href="#Directives">Directives</a> / -<a href="#Example">Example</a> / -<a href="#CompileTimeOptions">Compile time options</a> / -<a href="#RevisionHistory">RevisionHistory</a> / -<a href="#Person">Person to blame</a> / -<a href="#Sourcecode">Sourcecode</a> -<p> - -<h2><a name="Directives">Directives</a></h2> -<ul> -<li><A HREF="#anonymous">Anonymous</A> -<li><A HREF="#Authoritative">Anonymous_Authoritative</A> -<li><A HREF="#LogEmail">Anonymous_LogEmail</A> -<li><A HREF="#MustGiveEmail">Anonymous_MustGiveEmail</A> -<li><A HREF="#NoUserID">Anonymous_NoUserID</A> -<li><A HREF="#VerifyEmail">Anonymous_VerifyEmail</A> -</ul> - -<hr> - -<A name="anonymous"><h2>Anonymous</h2></a> +<P> + +<A HREF="#Directives">Directives</A> / +<A HREF="#Example">Example</A> / +<A HREF="#CompileTimeOptions">Compile time options</A> / +<A HREF="#RevisionHistory">RevisionHistory</A> / +<A HREF="#Person">Person to blame</A> / +<A HREF="#Sourcecode">Sourcecode</A> +<P> + +<H2><A NAME="Directives">Directives</A></H2> +<UL> +<LI><A HREF="#anonymous">Anonymous</A> +<LI><A HREF="#Authoritative">Anonymous_Authoritative</A> +<LI><A HREF="#LogEmail">Anonymous_LogEmail</A> +<LI><A HREF="#MustGiveEmail">Anonymous_MustGiveEmail</A> +<LI><A HREF="#NoUserID">Anonymous_NoUserID</A> +<LI><A HREF="#VerifyEmail">Anonymous_VerifyEmail</A> +</UL> + +<HR> + +<H2><A NAME="anonymous">Anonymous directive</A></H2> <!--%plaintext <?INDEX {\tt Anonymous} directive> --> -<strong>Syntax:</strong> Anonymous <em>user user ...</em><br> -<strong>Default:</strong> none<br> -<strong>Context:</strong> directory, .htaccess<br> -<strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_auth_anon<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Anonymous <EM>user user ...</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> none<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth_anon<P> A list of one or more 'magic' userIDs which are allowed access without password verification. The userIDs are space separated. It is possible to use the ' and " quotes to allow a space in a userID as well as the \ escape character. - <p> - Please note that the comparison is <b>case-IN-sensitive</b>. - <br> - I strongly suggest that the magic username '<code>anonymous</code>' + <P> + Please note that the comparison is <STRONG>case-IN-sensitive</STRONG>. + <BR> + I strongly suggest that the magic username '<CODE>anonymous</CODE>' is always one of the allowed userIDs. - <p> - Example:<br> - <code> - Anonymous: anonymous "Not Registered" 'I don\'t know' - </code><p> + <P> + Example:<BR> + <CODE> + Anonymous anonymous "Not Registered" 'I don\'t know' + </CODE><P> This would allow the user to enter without password verification by using the userId's 'anonymous', 'AnonyMous','Not Registered' and 'I Don't Know'. <HR> -<A name="Authoritative"><h2>Anonymous_Authoritative</h2></A> -<strong>Syntax:</strong> Anonymous_Authoritative <em>on | off</em><br> -<strong>Default:</strong> <code>Anonymous_Authoritative off</code><br> -<strong>Context:</strong> directory, .htaccess<br> -<strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_auth_anon<p> +<H2><A NAME="Authoritative">Anonymous_Authoritative directive</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Anonymous_Authoritative <EM>on | off</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>Anonymous_Authoritative off</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth_anon<P> When set 'on', there is no fall-through to other authorization methods. So if a userID does not match the values specified in the - <code>Anonymous</code> directive, access is denied. - <p> - Be sure you know what you are doing when you decide to switch + <CODE>Anonymous</CODE> directive, access is denied. + <P> + Be sure you know what you are doing when you decide to switch it on. And remember that it is the linking order of the modules (in the Configuration / Make file) which details the order in which the Authorization modules are queried. -<hr> +<HR> -<A name="LogEmail"><h2>Anonymous_LogEmail</h2></A> -<strong>Syntax:</strong> Anonymous_LogEmail <em>on | off</em><br> -<strong>Default:</strong> <code>off</code><br> -<strong>Context:</strong> directory, .htaccess<br> -<strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_auth_anon<p> +<H2><A NAME="LogEmail">Anonymous_LogEmail directive</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Anonymous_LogEmail <EM>on | off</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>Anonymous_LogEmail on</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth_anon<P> When set 'on', the default, the 'password' entered (which hopefully - contains a sensible email address) is logged in the httpd-log file. -<hr> + contains a sensible email address) is logged in the error log. +<HR> -<A name="MustGiveEmail"><h2>Anonymous_MustGiveEmail</h2></a> +<H2><A NAME="MustGiveEmail">Anonymous_MustGiveEmail directive</A></H2> <!--%plaintext <?INDEX {\tt Anonymous_MustGiveEmail} directive> --> -<strong>Syntax:</strong> Anonymous_MustGiveEmail <em>on</em> | <em>off</em><br> -<strong>Default:</strong> off<br> -<strong>Context:</strong> directory, .htaccess<br> -<strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_auth_anon<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Anonymous_MustGiveEmail <EM>on</EM> + | <EM>off</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>Anonymous_MustGiveEmail on</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth_anon<P> Specifies whether the user must specify an email address as the password. This prohibits blank passwords. <HR> -<A name="NoUserID"><h2>Anonymous_NoUserID</h2></A> -<strong>Syntax:</strong> Anonymous_NoUserID <em>on | off</em><br> -<strong>Default:</strong> <code>Anonymous_NoUserID off</code><br> -<strong>Context:</strong> directory, .htaccess<br> -<strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_auth_anon<p> +<H2><A NAME="NoUserID">Anonymous_NoUserID directive</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Anonymous_NoUserID <EM>on | off</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>Anonymous_NoUserID off</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth_anon<P> When set 'on', users can leave the userID (and perhaps the password field) empty. This @@ -144,119 +235,143 @@ allows users to share URLs. just hit return or click directly on the OK button; which seems a natural reaction. -<hr> +<HR> -<A name="VerifyEmail"><h2>Anonymous_VerifyEmail</h2></A> -<strong>Syntax:</strong> Anonymous <em>on | off</em><br> -<strong>Default:</strong> <code>Anonymous_VerifyEmail off</code><br> -<strong>Context:</strong> directory, .htaccess<br> -<strong>Override:</strong> AuthConfig<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_auth_anon<p> +<H2><A NAME="VerifyEmail">Anonymous_VerifyEmail directive</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Anonymous_VerifyEmail <EM>on | off</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>Anonymous_VerifyEmail off</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> AuthConfig<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_auth_anon<P> When set 'on' the 'password' entered is checked for at least one '@' and a '.' to encourage users to enter - valid email addresses (see the above <code>Auth_LogEmail</code>). + valid email addresses (see the above <CODE>Auth_LogEmail</CODE>). -<hr><a name="Example"><h2>Example</h2></a> +<HR> +<H2><A NAME="Example">Example</A></H2> The example below (when combined with the Auth directives -of a htpasswd-file based (or GDM, mSQL etc) base access +of a htpasswd-file based (or GDM, mSQL <EM>etc.</EM>) base access control system allows users in as 'guests' with the following properties: -<ul> -<li> -It insists that the user enters a userId. (<code>Anonymous_NoUserId</code>) -<li> -It insists that the user enters a password. (<code>Anonymous_MustGiveEmail</code>) -<li> -The password entered must be a valid email address, ie. contain at least one '@' and a '.'. -(<code>Anonymous_VerifyEmail</code>) -<li> -The userID must be one of <code>anonymous guest www test welcome</code> -and comparison is <b>not</b> case sensitive. -<code><directory /web/docs/public></code> -<li> -And the Email addresses entered in the passswd field are logged to -the httpd-log file -(<code>Anonymous_LogEmail</code>) -</ul> -<p> +<UL> +<LI> +It insists that the user enters a userId. (<CODE>Anonymous_NoUserId</CODE>) +<LI> +It insists that the user enters a password. +(<CODE>Anonymous_MustGiveEmail</CODE>) +<LI> +The password entered must be a valid email address, ie. contain at least one +'@' and a '.'. (<CODE>Anonymous_VerifyEmail</CODE>) +<LI> +The userID must be one of <CODE>anonymous guest www test welcome</CODE> +and comparison is <STRONG>not</STRONG> case sensitive. +<LI> +And the Email addresses entered in the passwd field are logged to +the error log file +(<CODE>Anonymous_LogEmail</CODE>) +</UL> +<P> Excerpt of access.conf: -<dl> -<dt><code> -Anonymous anonymous guest www test welcome<p> -Anonymous_MustGiveEmail on<br> -Anonymous_VerifyEmail on<br> -Anonymous_NoUserId off<br> -Anonymous_LogEmail on<br> -<p> -AuthName Use 'anonymous' & Email address for guest entry<br> -AuthType basic<p> - -</code></dt> -<dd> - Normal Apache/NCSA tokens for access control - <p> - <code><limit get post head></code><br> - <code>order deny,allow </code><br> - <code>allow from all </code><br> - <p> - <code>require valid-user </code><br> - <code><limit> </code><br> -</dd> -</dl> - - -<hr><h2><a name="CompileTimeOptions">Compile Time Options</a></h2> +<BLOCKQUOTE><CODE> +Anonymous_NoUserId off<BR> +Anonymous_MustGiveEmail on<BR> +Anonymous_VerifyEmail on<BR> +Anonymous_LogEmail on<BR> +Anonymous anonymous guest www test welcome<P> +<P> +AuthName "Use 'anonymous' & Email address for guest entry"<BR> +AuthType basic +<P> +# An AuthUserFile/AuthDBUserFile/AuthDBMUserFile<BR> +# directive must be specified, or use<BR> +# Anonymous_Authoritative for public access.<BR> +# In the .htaccess for the public directory, add:<BR> +<Files *><BR> +order deny,allow <BR> +allow from all <BR> +<P> +require valid-user <BR> +</Files><BR> +</CODE></BLOCKQUOTE> + + +<HR> +<H2><A NAME="CompileTimeOptions">Compile Time Options</A></H2> Currently there are no Compile options. -<hr><h2><a name="RevisionHistory">Revision History</a></h2> +<HR> +<H2><A NAME="RevisionHistory">Revision History</A></H2> This version: 23 Nov 1995, 24 Feb 1996, 16 May 1996. -<dl> +<DL> -<dt>Version 0.4<br></dt> - <dd>First release - </dd> -<dt>Version 0.5<br></dt> - <dd>Added 'VerifyEmail' and 'LogEmail' options. Multiple +<DT>Version 0.4<BR></DT> + <DD>First release + </DD> +<DT>Version 0.5<BR></DT> + <DD>Added 'VerifyEmail' and 'LogEmail' options. Multiple 'anonymous' tokens allowed. more docs. Added Authoritative functionality. - </dd> -</dl> + </DD> +</DL> -<hr><h2><a name="Person">Contact/person to blame</a></h2> +<HR> +<H2><A NAME="Person">Contact/person to blame</A></H2> This module was written for the -<a href="http://ewse.ceo.org">European Wide Service Exchange</a> by -<<a href="mailto:Dirk.vanGulik@jrc.it"><code>Dirk.vanGulik@jrc.it</code></a>>. +<A HREF="http://ewse.ceo.org">European Wide Service Exchange</A> by +<<A + HREF="mailto:Dirk.vanGulik@jrc.it" + ><CODE>Dirk.vanGulik@jrc.it</CODE></A>>. Feel free to contact me if you have any problems, ice-creams or bugs. This -documentation, courtesy of Nick Himba, <a href="mailto:himba@cs.utwente.nl"> -<code><himba@cs.utwente.nl></code></a>. -<p> +documentation, courtesy of Nick Himba, <A HREF="mailto:himba@cs.utwente.nl"> +<CODE><himba@cs.utwente.nl></CODE></A>. +<P> -<hr><h2><a NAME="Sourcecode">Sourcecode</a></h2> +<HR> +<H2><A NAME="Sourcecode">Sourcecode</A></H2> -The source code can be found at <a href="http://www.apache.org"><code> -http://www.apache.org</code></a>. A snapshot of a development version -usually resides at <a href="http://me-www.jrc.it/~dirkx/mod_auth_anon.c"><code> -http://me-www.jrc.it/~dirkx/mod_auth_anon.c</code></a>. Please make sure +The source code can be found at <A HREF="http://www.apache.org"><CODE> +http://www.apache.org</CODE></A>. A snapshot of a development version +usually resides at <A HREF="http://me-www.jrc.it/~dirkx/mod_auth_anon.c"><CODE> +http://me-www.jrc.it/~dirkx/mod_auth_anon.c</CODE></A>. Please make sure that you always quote the version you use when filing a bug report. -<p> +<P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> <A HREF="../"><IMG SRC="../images/home.gif" ALT="Home"></A> -</body> -</html> +</BODY> +</HTML> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html b/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html index 7fa844647b6..5d88d0b4f42 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_autoindex.html @@ -432,20 +432,53 @@ preference. <A HREF="directive-dict.html#Module" REL="Help" -><STRONG>Module:</STRONG></A> mod_autoindex<P> +><STRONG>Module:</STRONG></A> mod_autoindex + <BR> + <A + HREF="directive-dict.html#Compatibility" + REL="Help" + ><STRONG>Compatibility:</STRONG></A> some features only available after + 1.3.6; see text +<P> The HeaderName directive sets the name of the file that will be inserted at the top of the index listing. <EM>Filename</EM> is the name of the file -to include, and is taken to be relative to the directory being indexed. -The server first attempts to include <EM>filename</EM><CODE>.html</CODE> -as an HTML document, otherwise it will include <EM>filename</EM> as plain -text. Example: +to include. +</P> +<BLOCKQUOTE><STRONG>Apache 1.3.6 and earlier:</STRONG> +The module first attempts to include <EM>filename</EM><CODE>.html</CODE> +as an HTML document, otherwise it will try to include <EM>filename</EM> as +plain text. <EM>Filename</EM> is treated as a filesystem path relative +to the directory being indexed. In no case is SSI processing done. +Example: <BLOCKQUOTE><CODE>HeaderName HEADER</CODE></BLOCKQUOTE> when indexing the directory <CODE>/web</CODE>, the server will first look for the HTML file <CODE>/web/HEADER.html</CODE> and include it if found, otherwise it will include the plain text file <CODE>/web/HEADER</CODE>, if it exists. - -<P>See also <A HREF="#readmename">ReadmeName</A>.<P><HR> +</BLOCKQUOTE> +<BLOCKQUOTE><STRONG>Apache versions after 1.3.6:</STRONG> +<EM>Filename</EM> is treated as a URI path relative to the one used +to access the directory being indexed, and must resolve to a document +with a major content type of "<SAMP>text</SAMP>" (<EM>e.g.</EM>, +<SAMP>text/html</SAMP>, <SAMP>text/plain</SAMP>, <EM>etc.</EM>). +This means that <EM>filename</EM> may refer to a CGI script if the +script's actual file type (as opposed to its output) is marked as +<SAMP>text/html</SAMP> such as with a directive like: +<PRE> + AddType text/html .cgi +</PRE> +<A HREF="../content-negotiation.html">Content negotiation</A> +will be performed if the <SAMP>MultiViews</SAMP> +<A HREF="core.html#options">option</A> is enabled. +If <EM>filename</EM> resolves to a static <SAMP>text/html</SAMP> document +(not a CGI script) and the +<SAMP>Includes</SAMP> <A HREF="core.html#options">option</A> is enabled, +the file will be processed for server-side includes (see the +<A HREF="mod_include.html"><SAMP>mod_include</SAMP></A> documentation). +</BLOCKQUOTE> +<P> +See also <A HREF="#readmename">ReadmeName</A>. +<P><HR> <H2><A NAME="indexignore">IndexIgnore</A></H2> <!--%plaintext <?INDEX {\tt IndexIgnore} directive> --> @@ -759,19 +792,26 @@ the client from requesting the directory listing in a different order. <A HREF="directive-dict.html#Module" REL="Help" -><STRONG>Module:</STRONG></A> mod_autoindex<P> +><STRONG>Module:</STRONG></A> mod_autoindex + <BR> + <A + HREF="directive-dict.html#Compatibility" + REL="Help" + ><STRONG>Compatibility:</STRONG></A> some features only available after + 1.3.6; see text +<P> The ReadmeName directive sets the name of the file that will be appended to the end of the index listing. <EM>Filename</EM> is the name of the file -to include, and is taken to be relative to the directory being indexed. -The server first attempts to include <EM>filename</EM><CODE>.html</CODE> -as an HTML document, otherwise it will include <EM>filename</EM> as plain -text. Example: -<BLOCKQUOTE><CODE>ReadmeName README</CODE></BLOCKQUOTE> -when indexing the directory <CODE>/web</CODE>, the server will first look for -the HTML file <CODE>/web/README.html</CODE> and include it if found, otherwise -it will include the plain text file <CODE>/web/README</CODE>, if it exists. - +to include, and is taken to be relative to the location being indexed. +</P> +<BLOCKQUOTE> +<STRONG>The <EM>filename</EM> argument is treated as a stub filename +in Apache 1.3.6 and earlier, and as a relative URI in later versions. +Details of how it is handled may be found under the description of +the <A HREF="#headername">HeaderName</A> directive, which uses the +same mechanism and changed at the same time as ReadmeName.</STRONG> +</BLOCKQUOTE> <P>See also <A HREF="#headername">HeaderName</A>.<P> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_example.html b/usr.sbin/httpd/htdocs/manual/mod/mod_example.html index 013966e9f92..53b1017332e 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_example.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_example.html @@ -14,11 +14,11 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> - <H1 ALIGN="CENTER">Module mod_example</h1> + <H1 ALIGN="CENTER">Module mod_example</H1> <P> This module is contained in the <CODE>modules/mod_example.c</CODE> file, and <STRONG>is not</STRONG> compiled in by default. It illustrates many of @@ -38,7 +38,7 @@ </P> <P> The main file is <CODE>mod_example.c</CODE>, which illustrates all - the different callback mechanisms and call syntaces. By no means does + the different callback mechanisms and call syntaxes. By no means does an add-on module need to include routines for all of the callbacks - quite the contrary! </P> @@ -53,11 +53,12 @@ To include the example module in your server, follow the steps below: </P> <OL> - <LI>Uncomment the "Module example_module" line near the bottom of + <LI>Uncomment the "AddModule modules/example/mod_example" line near + the bottom of the <CODE>src/Configuration</CODE> file. If there isn't one, add it; it should look like this: <PRE> - Module example_module modules/example/mod_example.o + AddModule modules/example/mod_example.o </PRE> </LI> <LI>Run the <CODE>src/Configure</CODE> script @@ -122,28 +123,56 @@ Example </A></H2> <P> - <STRONG>Syntax:</STRONG> Example + <A + HREF="directive-dict.html#Syntax" + REL="Help" + ><STRONG>Syntax:</STRONG></A> Example <BR> - <STRONG>Default:</STRONG> None + <A + HREF="directive-dict.html#Default" + REL="Help" + ><STRONG>Default:</STRONG></A> None <BR> - <STRONG>Context:</STRONG> server config, virtual host, directory, .htaccess + <A + HREF="directive-dict.html#Context" + REL="Help" + ><STRONG>Context:</STRONG></A> server config, virtual host, directory, + .htaccess <BR> - <STRONG>Override:</STRONG> Options + <A + HREF="directive-dict.html#Override" + REL="Help" + ><STRONG>Override:</STRONG></A> Options <BR> - <STRONG>Status:</STRONG> Extension + <A + HREF="directive-dict.html#Status" + REL="Help" + ><STRONG>Status:</STRONG></A> Extension <BR> - <STRONG>Module:</STRONG> mod_example + <A + HREF="directive-dict.html#Module" + REL="Help" + ><STRONG>Module:</STRONG></A> mod_example + <BR> + <A + HREF="directive-dict.html#Compatibility" + REL="Help" + ><STRONG>Compatibility:</STRONG></A> <SAMP>Example</SAMP> is only + available in Apache 1.2 and later. </P> <P> - The Example directive activates the example module's content handler - for a particular location or file type. It takes no arguments. If - you browse to an URL to which the example content-handler applies, you - will get a display of the routines within the module and how and in - what order they were called to service the document request. + The <SAMP>Example</SAMP> directive just sets a demonstration flag which the + example module's content handler displays. It takes no arguments. If you + browse to an URL to which the example content-handler applies, you will get + a display of the routines within the module and how and in what order they + were called to service the document request. The effect of this directive + one can observe under the point "<SAMP>Example directive declared + here: YES/NO</SAMP>". </P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_headers.html b/usr.sbin/httpd/htdocs/manual/mod/mod_headers.html index 212c519bf7e..f7b79dfbd97 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_headers.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_headers.html @@ -15,57 +15,74 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<h1 ALIGN="CENTER">Module mod_headers</h1> +<H1 ALIGN="CENTER">Module mod_headers</H1> The optional headers module allows for the customization of HTTP response headers. Headers can be merged, replaced or removed. The directives described in this document are only available if Apache is -compiled with <b>mod_headers.c</b>. +compiled with <STRONG>mod_headers.c</STRONG>. -<hr> +<HR> -<h2>Directive</h2> -<ul> -<li><A HREF="#header">Header</A> -</ul> +<H2>Directive</H2> +<UL> +<LI><A HREF="#header">Header</A> +</UL> -<hr> +<HR> -<h2><A name="header">Header</A></h2> -<strong>Syntax:</strong> Header [ set | append | add ] <em>header</em> <em>value</em><br> -<strong>Syntax:</strong> Header unset <em>header</em><br> -<strong>Context:</strong> server config, virtual host, access.conf, .htaccess<br> -<strong>Status:</strong> optional<br> -<strong>Module:</strong> mod_header<p> +<H2><A NAME="header">Header</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Header [ set | append | add ] + <EM>header</EM> <EM>value</EM><BR> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> Header unset <EM>header</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, access.conf, + .htaccess<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> optional<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_header<P> This directive can replace, merge or remove HTTP response headers. The action it performs is determined by the first argument. This can be one of the following values: -<ul> -<li><b>set</b><br> +<UL> +<LI><STRONG>set</STRONG><BR> The response header is set, replacing any previous header with this name -<li><b>append</b><br> +<LI><STRONG>append</STRONG><BR> The response header is appended to any existing header of the same name. When a new value is merged onto an existing header it is separated from the existing header with a comma. This is the HTTP standard way of giving a header multiple values. -<li><b>add</b><br> +<LI><STRONG>add</STRONG><BR> The response header is added to the existing set of headers, even if this header already exists. This can result in two (or more) headers having the same name. This can lead to unforeseen consequences, and in general "append" should be used instead. -<li><b>unset</b><br> +<LI><STRONG>unset</STRONG><BR> The response header of this name is removed, if it exists. If there are - multiple headers of the same name, only the first one set will be removed. -</ul> + multiple headers of the same name, all will be removed. +</UL> This argument is followed by a header name, which can include the final colon, but it is not required. Case is ignored. For @@ -73,31 +90,31 @@ add, append and set a value is given as the third argument. If this value contains spaces, it should be surrounded by double quotes. For unset, no value should be given. -<h3>Order of Processing</h3> +<H3>Order of Processing</H3> The Header directive can occur almost anywhere within the server configuration. It is valid in the main server config and virtual host sections, inside <Directory>, <Location> and <Files> sections, and within .htaccess files. -<p> +<P> The Header directives are processed in the following order: -<ol> -<li>main server -<li>virtual host -<li><Directory> sections and .htaccess -<li><Location> -<li><Files> -</ol> +<OL> +<LI>main server +<LI>virtual host +<LI><Directory> sections and .htaccess +<LI><Location> +<LI><Files> +</OL> Order is important. These two headers have a different effect if reversed: -<pre> +<PRE> Header append Author "John P. Doe" Header unset Author -</pre> +</PRE> This way round, the Author header is not set. If reversed, the Author header is set to "John P. Doe". -<p> +<P> The Header directives are processed just before the response is sent by its handler. These means that some headers that are added just @@ -106,8 +123,9 @@ includes headers such as "Date" and "Server". <P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_imap.html b/usr.sbin/httpd/htdocs/manual/mod/mod_imap.html index 25875b86002..aa1e3de06cc 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_imap.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_imap.html @@ -1,8 +1,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<title>Apache module mod_imap</title> -</head> +<HTML> +<HEAD> +<TITLE>Apache module mod_imap</TITLE> +</HEAD> <!-- Background white, links blue (unvisited), navy (visited), red (active) --> <BODY @@ -15,31 +15,31 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<h1 ALIGN="CENTER">Module mod_imap</h1> +<H1 ALIGN="CENTER">Module mod_imap</H1> -This module is contained in the <code>mod_imap.c</code> file, and is -compiled in by default. It provides for <code>.map</code> files, -replacing the functionality of the <code>imagemap</code> CGI +This module is contained in the <CODE>mod_imap.c</CODE> file, and is +compiled in by default. It provides for <CODE>.map</CODE> files, +replacing the functionality of the <CODE>imagemap</CODE> CGI program. Any directory or document type configured to use the handler -<code>imap-file</code> (using either <code><A -HREF="mod_mime.html#addhandler">AddHandler</A> </code> or <code><A -HREF="mod_mime.html#sethandler">SetHandler</A></code>) will be +<CODE>imap-file</CODE> (using either <CODE><A +HREF="mod_mime.html#addhandler">AddHandler</A> </CODE> or <CODE><A +HREF="mod_mime.html#sethandler">SetHandler</A></CODE>) will be processed by this module. -<h2>Summary</h2> +<H2>Summary</H2> This module is in the default Apache distribution. The following directive will -activate files ending with <code>.map</code> as imagemap files: +activate files ending with <CODE>.map</CODE> as imagemap files: -<blockquote><code>AddHandler imap-file map</code></blockquote> +<BLOCKQUOTE><CODE>AddHandler imap-file map</CODE></BLOCKQUOTE> Note that the following is still supported: - <blockquote><code>AddType application/x-httpd-imap map</code></blockquote> + <BLOCKQUOTE><CODE>AddType application/x-httpd-imap map</CODE></BLOCKQUOTE> However, we are trying to phase out "magic MIME types" so we are deprecating this method. @@ -48,244 +48,290 @@ this method. The imagemap module adds some new features that were not possible with previously distributed imagemap programs.<P> -<ul> +<UL> <LI>URL references relative to the Referer: information. <LI>Default <BASE> assignment through a new map directive -<code>base</code>. -<LI>No need for <code>imagemap.conf</code> file. +<CODE>base</CODE>. +<LI>No need for <CODE>imagemap.conf</CODE> file. <LI>Point references. <LI>Configurable generation of imagemap menus. -</ul> +</UL> <P> -<h2>Configuration Directives</h2> -<ul> -<li><A HREF="#imapmenu">ImapMenu</A> -<li><A HREF="#imapdefault">ImapDefault</A> -<li><A HREF="#imapbase">ImapBase</A> -</ul> +<H2>Configuration Directives</H2> +<UL> +<LI><A HREF="#imapmenu">ImapMenu</A> +<LI><A HREF="#imapdefault">ImapDefault</A> +<LI><A HREF="#imapbase">ImapBase</A> +</UL> -<p> +<P> -<h3><A name="imapmenu">ImapMenu</A></h3> -<strong>Syntax:</strong> ImapMenu <code>{none, formatted, semi-formatted, - unformatted}</code><br> -<Strong>Context:</strong> server config, virtual host, directory, .htaccess<br> -<Strong>Override:</strong> Indexes<br> -<strong>Module:</strong> mod_imap.c<br> -<strong>Compatibility:</strong> ImapMenu is only available in Apache -1.1 and later.<p> +<H3><A NAME="imapmenu">ImapMenu</A></H3> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ImapMenu <CODE>{none, formatted, semiformatted, + unformatted}</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Indexes<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_imap.c<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ImapMenu is only available in Apache +1.1 and later.<P> The ImapMenu directive determines the action taken if an imagemap file is called without valid coordinates. -<dl> - <dt><code>none</code> - <dd>If ImapMenu is - <code>none</code>, no menu is generated, and the <code>default</code> - action is performed. - <dt><code>formatted</code> - <dd>A <code>formatted</code> menu is the simplest menu. Comments +<DL> + <DT><CODE>none</CODE> + <DD>If ImapMenu is + <CODE>none</CODE>, no menu is generated, and the <CODE>default</CODE> + action is performed. + <DT><CODE>formatted</CODE> + <DD>A <CODE>formatted</CODE> menu is the simplest menu. Comments in the imagemap file are ignored. A level one header is printed, then an hrule, then the links each on a separate line. The menu has a consistent, plain look close to that of a directory listing. - <dt><code>semiformatted</code> - <dd>In the <code>semiformatted</code> menu, comments are printed + <DT><CODE>semiformatted</CODE> + <DD>In the <CODE>semiformatted</CODE> menu, comments are printed where they occur in the imagemap file. Blank lines are turned into HTML breaks. No header or hrule is printed, but otherwise - the menu is the same as a <code>formatted</code> menu. - <dt><code>unformatted</code> - <dd>Comments are printed, blank lines are ignored. Nothing is + the menu is the same as a <CODE>formatted</CODE> menu. + <DT><CODE>unformatted</CODE> + <DD>Comments are printed, blank lines are ignored. Nothing is printed that does not appear in the imagemap file. All breaks and headers must be included as comments in the imagemap file. This gives you the most flexibility over the appearance of your menus, but requires you to treat your map files as HTML instead of plaintext. -</dl> - -<p> - -<h3><A name="imapdefault">ImapDefault</A></h3> -<strong>Syntax:</strong> ImapDefault <code>{error, nocontent, - map, referer, URL}</code><br> -<Strong>Context:</strong> server config, virtual host, directory, .htaccess<br> -<Strong>Override:</strong> Indexes<br> -<strong>Module:</strong> mod_imap.c<br> -<strong>Compatibility:</strong> ImapDefault is only available in Apache -1.1 and later.<p> +</DL> +<P> -The ImapDefault directive sets the default <code>default</code> used in -the imagemap files. It's value is overridden by a <code>default</code> +<H3><A NAME="imapdefault">ImapDefault</A></H3> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ImapDefault <CODE>{error, nocontent, + map, referer, URL}</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Indexes<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_imap.c<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ImapDefault is only available in Apache +1.1 and later.<P> + + +The ImapDefault directive sets the default <CODE>default</CODE> used in +the imagemap files. It's value is overridden by a <CODE>default</CODE> directive within the imagemap file. If not present, the -<code>default</code> action is <code>nocontent</code>, which means -that a <code>204 No Content</code> is sent to the client. In this +<CODE>default</CODE> action is <CODE>nocontent</CODE>, which means +that a <CODE>204 No Content</CODE> is sent to the client. In this case, the client should continue to display the original page. -<p> - -<h3><A name="imapbase">ImapBase</A></h3> -<strong>Syntax:</strong> ImapBase <code>{map, referer, URL}</code><br> -<Strong>Context:</strong> server config, virtual host, directory, .htaccess<br> -<Strong>Override:</strong> Indexes<br> -<strong>Module:</strong> mod_imap.c<br> -<strong>Compatibility:</strong> ImapBase is only available in Apache -1.1 and later.<p> +<P> -The ImapBase directive sets the default <code>base</code> used in -the imagemap files. It's value is overridden by a <code>base</code> +<H3><A NAME="imapbase">ImapBase</A></H3> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ImapBase <CODE>{map, referer, URL}</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, directory, .htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> Indexes<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_imap.c<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ImapBase is only available in Apache +1.1 and later.<P> + +The ImapBase directive sets the default <CODE>base</CODE> used in +the imagemap files. It's value is overridden by a <CODE>base</CODE> directive within the imagemap file. If not present, the -<code>base</code> defaults to <code>http://servername/</code>. +<CODE>base</CODE> defaults to <CODE>http://servername/</CODE>. -<hr> -<p> +<HR> +<P> -<h2>Imagemap File</h2> +<H2>Imagemap File</H2> The lines in the imagemap files can have one of several formats: -<blockquote> -<code>directive value [x,y ...]</code><br> -<code>directive value "Menu text" [x,y ...]</code><br> -<code>directive value x,y ... "Menu text"</code><br> -</blockquote> -The directive is one of <code>base</code>, <code>default</code>, -<code>poly</code>, <code>circle</code>, <code>rect</code>, or -<code>point</code>. The value is an absolute or relative URL, or one +<BLOCKQUOTE> +<CODE>directive value [x,y ...]</CODE><BR> +<CODE>directive value "Menu text" [x,y ...]</CODE><BR> +<CODE>directive value x,y ... "Menu text"</CODE><BR> +</BLOCKQUOTE> +The directive is one of <CODE>base</CODE>, <CODE>default</CODE>, +<CODE>poly</CODE>, <CODE>circle</CODE>, <CODE>rect</CODE>, or +<CODE>point</CODE>. The value is an absolute or relative URL, or one of the special values listed below. The coordinates are -<code>x,y</code> pairs separated by whitespace. The quoted text is +<CODE>x,y</CODE> pairs separated by whitespace. The quoted text is used as the text of the link if a imagemap menu is generated. Lines beginning with '#' are comments. -<h3>Imagemap File Directives</h3> +<H3>Imagemap File Directives</H3> There are six directives allowed in the imagemap file. The directives can come in any order, but are processed in the order they are found -in the imagemap file. -<dl> -<dt><code>base</code> Directive -<dd>Has the effect of <code><BASE href="value"></code>. The +in the imagemap file. +<DL> +<DT><CODE>base</CODE> Directive +<DD>Has the effect of <CODE><BASE HREF="value"></CODE>. The non-absolute URLs of the map-file are taken relative to this value. - The <code>base</code> directive overrides ImapBase as set in a + The <CODE>base</CODE> directive overrides ImapBase as set in a .htaccess file or in the server configuration files. In the absence - of an ImapBase configuration directive, <code>base</code> defaults to - <code>http://server_name/</code>. <br> - <code>base_uri</code> is synonymous with <code>base</code>. Note that + of an ImapBase configuration directive, <CODE>base</CODE> defaults to + <CODE>http://server_name/</CODE>. <BR> + <CODE>base_uri</CODE> is synonymous with <CODE>base</CODE>. Note that a trailing slash on the URL is significant. -<p> -<dt><code>default</code> Directive -<dd>The action taken if the coordinates given do not fit any of the - <code>poly</code>, <code>circle</code> or <code>rect</code> - directives, and there are no <code>point</code> directives. Defaults - to <code>nocontent</code> in the absence of an ImapDefault - configuration setting, causing a status code of <code>204 No - Content</code> to be returned. The client should keep the same +<P> +<DT><CODE>default</CODE> Directive +<DD>The action taken if the coordinates given do not fit any of the + <CODE>poly</CODE>, <CODE>circle</CODE> or <CODE>rect</CODE> + directives, and there are no <CODE>point</CODE> directives. Defaults + to <CODE>nocontent</CODE> in the absence of an ImapDefault + configuration setting, causing a status code of <CODE>204 No + Content</CODE> to be returned. The client should keep the same page displayed. -<p> -<dt><code>poly</code> Directive -<dd>Takes three to one-hundred points, and is obeyed if the user selected +<P> +<DT><CODE>poly</CODE> Directive +<DD>Takes three to one-hundred points, and is obeyed if the user selected coordinates fall within the polygon defined by these points. -<p> -<dt><code>circle</code> -<dd>Takes the center coordinates of a circle and a point on the circle. Is +<P> +<DT><CODE>circle</CODE> +<DD>Takes the center coordinates of a circle and a point on the circle. Is obeyed if the user selected point is with the circle. -<p> -<dt><code>rect</code> Directive -<dd>Takes the coordinates of two opposing corners of a rectangle. Obeyed +<P> +<DT><CODE>rect</CODE> Directive +<DD>Takes the coordinates of two opposing corners of a rectangle. Obeyed if the point selected is within this rectangle. -<p> -<dt><code>point</code> Directive -<dd>Takes a single point. The point directive closest to the user +<P> +<DT><CODE>point</CODE> Directive +<DD>Takes a single point. The point directive closest to the user selected point is obeyed if no other directives are satisfied. - Note that <code>default</code> will not be followed if a - <code>point</code> directive is present and valid coordinates are + Note that <CODE>default</CODE> will not be followed if a + <CODE>point</CODE> directive is present and valid coordinates are given. -</dl> +</DL> -<h3>Values</h3> +<H3>Values</H3> The values for each of the directives can any of the following: -<dl> - <dt>a URL - <dd>The URL can be relative or absolute URL. Relative URLs can +<DL> + <DT>a URL + <DD>The URL can be relative or absolute URL. Relative URLs can contain '..' syntax and will be resolved relative to the - <code>base</code> value. <br> - <code>base</code> itself will not resolved according to the current - value. A statement <code>base mailto:</code> will work properly, though. -<p> - <dt><code>map</code> - <dd>Equivalent to the URL of the imagemap file itself. No + <CODE>base</CODE> value. <BR> + <CODE>base</CODE> itself will not resolved according to the current + value. A statement <CODE>base mailto:</CODE> will work properly, though. +<P> + <DT><CODE>map</CODE> + <DD>Equivalent to the URL of the imagemap file itself. No coordinates are sent with this, so a menu will be generated unless ImapMenu is set to 'none'. -<p> - <dt><code>menu</code> - <dd>Synonymous with <code>map</code>. -<p> - <dt><code>referer</code> - <dd>Equivalent to the URL of the referring document. - Defaults to <code>http://servername/</code> if no Referer: - header was present. -<p> - <dt><code>nocontent</code> - <dd>Sends a status code of <code>204 No Content</code>, +<P> + <DT><CODE>menu</CODE> + <DD>Synonymous with <CODE>map</CODE>. +<P> + <DT><CODE>referer</CODE> + <DD>Equivalent to the URL of the referring document. + Defaults to <CODE>http://servername/</CODE> if no Referer: + header was present. +<P> + <DT><CODE>nocontent</CODE> + <DD>Sends a status code of <CODE>204 No Content</CODE>, telling the client to keep the same page displayed. Valid for - all but <code>base</code>. -<p> - <dt><code>error</code> - <dd>Fails with a <code>500 Server Error</code>. Valid for all but - <code>base</code>, but sort of silly for anything but - <code>default</code>. -</dl> - -<h3>Coordinates</h3> -<dl> - <dt><code>0,0 200,200</code> - <dd>A coordinate consists of an <tt>x</tt> and a <tt>y</tt> value + all but <CODE>base</CODE>. +<P> + <DT><CODE>error</CODE> + <DD>Fails with a <CODE>500 Server Error</CODE>. Valid for all but + <CODE>base</CODE>, but sort of silly for anything but + <CODE>default</CODE>. +</DL> + +<H3>Coordinates</H3> +<DL> + <DT><CODE>0,0 200,200</CODE> + <DD>A coordinate consists of an <TT>x</TT> and a <TT>y</TT> value separated by a comma. The coordinates are separated from each other by whitespace. To accommodate the way Lynx handles imagemaps, should a - user select the coordinate <code>0,0</code>, it is as if - no coordinate had been selected. -</dl> - -<h3>Quoted Text</h3> -<dl> - <dt><code>"Menu Text"</code> - <dd>After the value or after the coordinates, the line optionally may + user select the coordinate <CODE>0,0</CODE>, it is as if + no coordinate had been selected. +</DL> + +<H3>Quoted Text</H3> +<DL> + <DT><CODE>"Menu Text"</CODE> + <DD>After the value or after the coordinates, the line optionally may contain text within double quotes. This string is used as the - text for the link if a menu is generated:<br> - <code><a href="http://foo.com/">Menu text</a></code><br> + text for the link if a menu is generated:<BR> + <CODE><a HREF="http://foo.com/">Menu text</a></CODE><BR> If no quoted text is present, the name of the link will be used - as the text:<br> - <code><a href="http://foo.com/">http://foo.com</a></code><br> + as the text:<BR> + <CODE><a HREF="http://foo.com/">http://foo.com</a></CODE><BR> It is impossible to escape double quotes within this text. -</dl> - -<hr> - -<h2>Example Mapfile</h2> -<blockquote><code> -#Comments are printed in a 'formatted' or 'semiformatted' menu. <br> -#And can contain html tags. <hr> <br> -base referer <br> -poly map "Could I have a menu, please?" 0,0 0,10 10,10 10,0 <br> -rect .. 0,0 77,27 "the directory of the referer"<br> -circle http://www.inetnebr.com/lincoln/feedback/ 195,0 305,27 <br> -rect another_file "in same directory as referer" 306,0 419,27 <br> -point http://www.zyzzyva.com/ 100,100 <br> -point http://www.tripod.com/ 200,200 <br> -rect mailto:nate@tripod.com 100,150 200,0 "Bugs?" <br> -</code></blockquote> +</DL> + +<HR> + +<H2>Example Mapfile</H2> +<BLOCKQUOTE><CODE> +#Comments are printed in a 'formatted' or 'semiformatted' menu. <BR> +#And can contain html tags. <hr> <BR> +base referer <BR> +poly map "Could I have a menu, please?" 0,0 0,10 10,10 10,0 <BR> +rect .. 0,0 77,27 "the directory of the referer"<BR> +circle http://www.inetnebr.com/lincoln/feedback/ 195,0 305,27 <BR> +rect another_file "in same directory as referer" 306,0 419,27 <BR> +point http://www.zyzzyva.com/ 100,100 <BR> +point http://www.tripod.com/ 200,200 <BR> +rect mailto:nate@tripod.com 100,150 200,0 "Bugs?" <BR> +</CODE></BLOCKQUOTE> <P> -<h2>Referencing your mapfile</h2> -<blockquote><code> -<A HREF="/maps/imagmap1.map"> <br> -<IMG ISMAP SRC="/images/imagemap1.gif"> <br> +<H2>Referencing your mapfile</H2> +<BLOCKQUOTE><CODE> +<A HREF="/maps/imagemap1.map"> <BR> +<IMG ISMAP SRC="/images/imagemap1.gif"> <BR> </A> -</code></blockquote><p> +</CODE></BLOCKQUOTE><P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_log_agent.html b/usr.sbin/httpd/htdocs/manual/mod/mod_log_agent.html index a0913517dc0..abe241745e7 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_log_agent.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_log_agent.html @@ -15,55 +15,72 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<H1 ALIGN="CENTER">Module mod_log_agent</h1> +<H1 ALIGN="CENTER">Module mod_log_agent</H1> -This module is contained in the <code>mod_log_agent.c</code> file, and is not +This module is contained in the <CODE>mod_log_agent.c</CODE> file, and is not compiled in by default. It provides for logging of the client user agents. +mod_log_agent is deprecated. Use <A HREF="mod_log_config.html">mod_log_config</A> +instead. - -<ul> -<li><A HREF="#agentlog">AgentLog</A> -</ul> -<hr> +<UL> +<LI><A HREF="#agentlog">AgentLog</A> +</UL> +<HR> -<h2><A name="agentlog">AgentLog</A></h2> +<H2><A NAME="agentlog">AgentLog</A></H2> <!--%plaintext <?INDEX {\tt AgentLog} directive> --> -<strong>Syntax:</strong> AgentLog <em>file-pipe</em><br> -<strong>Default:</strong> <code>AgentLog logs/agent_log</code><br> -<Strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_log_agent<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> AgentLog <EM>file-pipe</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>AgentLog logs/agent_log</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_agent<P> The AgentLog directive sets the name of the file to which the server will -log the UserAgent header of incoming requests. <em>File-pipe</em> is one +log the UserAgent header of incoming requests. <EM>File-pipe</EM> is one of -<dl><dt>A filename -<dd>A filename relative to the <A HREF="core.html#serverroot">ServerRoot</A>. -<dt> `|' followed by a command -<dd>A program to receive the agent log information on its standard input. +<DL><DT>A filename +<DD>A filename relative to the <A HREF="core.html#serverroot">ServerRoot</A>. +<DT> `|' followed by a command +<DD>A program to receive the agent log information on its standard input. Note the a new program will not be started for a VirtualHost if it inherits the AgentLog from the main server. -</dl> -<strong>Security:</strong> if a program is used, then it will be +</DL> +<STRONG>Security:</STRONG> if a program is used, then it will be run under the user who started httpd. This will be root if the server -was started by root; be sure that the program is secure.<p> +was started by root; be sure that the program is secure.<P> -<strong>Security:</strong> See the <A +<STRONG>Security:</STRONG> See the <A HREF="../misc/security_tips.html">security tips</A> document for details on why your security could be compromised if the directory where logfiles are stored is writable by anyone other than the user that starts the server.<P> -This directive is provided for compatibility with NCSA 1.4.<p> +This directive is provided for compatibility with NCSA 1.4.<P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_log_config.html b/usr.sbin/httpd/htdocs/manual/mod/mod_log_config.html index a670e824458..1b8b0e15add 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_log_config.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_log_config.html @@ -15,98 +15,113 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<H1 ALIGN="CENTER">Module mod_log_config</h1> - -This module is contained in the <code>mod_log_config.c</code> file, +<H1 ALIGN="CENTER">Module mod_log_config</H1> +<P> +This module is contained in the <CODE>mod_log_config.c</CODE> file, and is compiled in by default in Apache 1.2. mod_log_config replaces mod_log_common in Apache 1.2. Prior to version 1.2, mod_log_config was an optional module. It provides for logging of the requests made to the server, using the Common Log Format or a user-specified format. +</P> -<h2>Summary</h2> - -Three directives are provided by this module: <code>TransferLog</code> -to create a log file, <code>LogFormat</code> to set a custom format, -and <code>CustomLog</code> to define a log file and format in one go. -The <code>TransferLog</code> and <code>CustomLog</code> directives can +<H2>Summary</H2> +<P> +Three directives are provided by this module: <CODE>TransferLog</CODE> +to create a log file, <CODE>LogFormat</CODE> to set a custom format, +and <CODE>CustomLog</CODE> to define a log file and format in one go. +The <CODE>TransferLog</CODE> and <CODE>CustomLog</CODE> directives can be used multiple times in each server to cause each request to be logged to multiple files. -<P> +</P> -<h3>Compatibility notes</h3> +<H3>Compatibility notes</H3> -<ul> -<li>This module is based on mod_log_config distributed with +<UL> +<LI>This module is based on mod_log_config distributed with previous Apache releases, now updated to handle multiple logs. There is now no need to re-configure Apache to use configuration log formats. -<li>The module also implements the <code>CookieLog</code> directive, -used to log user-tracking information created by <a -href="mod_usertrack.html">mod_usertrack</a>. The use of -<code>CookieLog</code> is deprecated, and a <code>CustomLog</code> +<LI>The module also implements the <CODE>CookieLog</CODE> directive, +used to log user-tracking information created by <A +HREF="mod_usertrack.html">mod_usertrack</A>. The use of +<CODE>CookieLog</CODE> is deprecated, and a <CODE>CustomLog</CODE> should be defined to log user-tracking information instead. -</ul> +<LI>As of Apache 1.3.5, this module allows conditional logging +based upon the setting of environment variables. That is, +you can control whether a request should be logged or not +based upon whether an arbitrary environment variable is +defined or not. This is settable on a <EM>per</EM>-logfile +basis. -<h2>Log File Formats</h2> +<LI>Beginning with Apache 1.3.5, the mod_log_config module has +also subsumed the <CODE>RefererIgnore</CODE> functionality from +<A HREF="mod_log_referer.html">mod_log_referer</A>. The effect +of <CODE>RefererIgnore</CODE> can be achieved by combinations of +<A HREF="mod_setenvif.html"><CODE>SetEnvIf</CODE></A> directives +and conditional <CODE>CustomLog</CODE> definitions. -Unless told otherwise with <tt>LogFormat</tt> the log files created by -<tt>TransferLog</tt> will be in standard "Common Log Format" +</UL> + +<H2>Log File Formats</H2> + +Unless told otherwise with <TT>LogFormat</TT> the log files created by +<TT>TransferLog</TT> will be in standard "Common Log Format" (CLF). The contents of each line in a CLF file are explained below. Alternatively, the log file can be customized (and if multiple log files are used, each can have a different format). Custom formats -are set with <code>LogFormat</code> and <code>CustomLog</code>. +are set with <CODE>LogFormat</CODE> and <CODE>CustomLog</CODE>. -<h3>Common Log Format</h3> +<H3>Common Log Format</H3> The Common Log Format (CLF) file contains a separate line for each request. A line is composed of several tokens separated by spaces: -<blockquote> +<BLOCKQUOTE> host ident authuser date request status bytes -</blockquote> +</BLOCKQUOTE> If a token does not have a value then it is represented by a hyphen (-). The meanings and values of these tokens are as follows: -<dl> -<dt>host -<dd>The fully-qualified domain name of the client, or its IP number if the +<DL> +<DT>host +<DD>The fully-qualified domain name of the client, or its IP number if the name is not available. -<dt>ident -<dd>If <A HREF="core.html#identitycheck">IdentityCheck</A> is enabled and the +<DT>ident +<DD>If <A HREF="core.html#identitycheck">IdentityCheck</A> is enabled and the client machine runs identd, then this is the identity information reported by the client. -<dt>authuser -<dd>If the request was for an password protected document, then this is +<DT>authuser +<DD>If the request was for an password protected document, then this is the userid used in the request. -<dt>date -<dd>The date and time of the request, in the following format: -<dl><dd><blockquote><code> date = [day/month/year:hour:minute:second zone] <br> -day = 2*digit<br> -month = 3*letter<br> -year = 4*digit<br> -hour = 2*digit<br> -minute = 2*digit<br> -second = 2*digit<br> -zone = (`+' | `-') 4*digit</code></blockquote></dl> -<dt>request -<dd>The request line from the client, enclosed in double quotes -(<code>"</code>). -<dt>status -<dd>The three digit status code returned to the client. -<dt>bytes -<dd>The number of bytes in the object returned to the client, not including +<DT>date +<DD>The date and time of the request, in the following format: +<DL><DD><BLOCKQUOTE><CODE> date = [day/month/year:hour:minute:second zone] <BR> +day = 2*digit<BR> +month = 3*letter<BR> +year = 4*digit<BR> +hour = 2*digit<BR> +minute = 2*digit<BR> +second = 2*digit<BR> +zone = (`+' | `-') 4*digit</CODE></BLOCKQUOTE></DL> +<DT>request +<DD>The request line from the client, enclosed in double quotes +(<CODE>"</CODE>). +<DT>status +<DD>The three digit status code returned to the client. +<DT>bytes +<DD>The number of bytes in the object returned to the client, not including any headers. -</dl> +</DL> -<h3><A NAME="formats">Custom Log Formats</A></h3> +<H3><A NAME="formats">Custom Log Formats</A></H3> -The format argument to the <code>LogFormat</code> and -<code>CustomLog</code> is a string. This string is logged to the log +The format argument to the <CODE>LogFormat</CODE> and +<CODE>CustomLog</CODE> is a string. This string is logged to the log file for each request. It can contain literal characters copied into the log files, and `%' directives which are replaced in the log file by the values as follows: @@ -116,26 +131,29 @@ by the values as follows: %...f: Filename %...{FOOBAR}e: The contents of the environment variable FOOBAR %...h: Remote host +%...a: Remote IP-address +%...A: Local IP-address %...{Foobar}i: The contents of Foobar: header line(s) in the request sent to the server. %...l: Remote logname (from identd, if supplied) %...{Foobar}n: The contents of note "Foobar" from another module. %...{Foobar}o: The contents of Foobar: header line(s) in the reply. -%...p: The port the request was served to +%...p: The canonical Port of the server serving the request %...P: The process ID of the child that serviced the request. %...r: First line of request %...s: Status. For requests that got internally redirected, this is status of the *original* request --- %...>s for the last. -%...t: Time, in common log format time format +%...t: Time, in common log format time format (standard english format) %...{format}t: The time, in the form given by format, which should - be in strftime(3) format. + be in strftime(3) format. (potentially localised) %...T: The time taken to serve the request, in seconds. %...u: Remote user (from auth; may be bogus if return status (%s) is 401) %...U: The URL path requested. -%...v: The name of the server (i.e. which virtual host?) +%...v: The canonical ServerName of the server serving the request. +%...V: The server name according to the UseCanonicalName setting. </PRE> -The `...' can be nothing at all (e.g. <code>"%h %u %r %s %b"</code>), or it can +The `...' can be nothing at all (<EM>e.g.</EM>, <CODE>"%h %u %r %s %b"</CODE>), or it can indicate conditions for inclusion of the item (which will cause it to be replaced with `-' if the condition is not met). Note that there is no escaping performed on the strings from %r, %...i and @@ -150,121 +168,293 @@ The forms of condition are a list of HTTP status codes, which may or may not be preceded by `!'. Thus, `%400,501{User-agent}i' logs User-agent: on 400 errors and 501 errors (Bad Request, Not Implemented) only; `%!200,304,302{Referer}i' logs Referer: on all -requests which did <b>not</b> return some sort of normal status. +requests which did <STRONG>not</STRONG> return some sort of normal status. + +<P> + +Note that the common log format is defined by the string <CODE>"%h %l +%u %t \"%r\" %s %b"</CODE>, which can be used as the basis for +extending for format if desired (<EM>e.g.</EM>, to add extra fields at the end). +NCSA's extended/combined log format would be <CODE>"%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\""</CODE>. <P> -Note that the common log format is defined by the string <code>"%h %l -%u %t \"%r\" %s %b"</code>, which can be used as the basis for -extending for format if desired (e.g. to add extra fields at the end). -NCSA's extended/combined log format would be <code>"%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\""</code>. +Note that the canonical <A HREF="core.html#servername">ServerName</A> +and <A HREF="core.html#port">Port</A> of the server serving the request +are used for <CODE>%v</CODE> and <CODE>%p</CODE> respectively. This +happens regardless of the +<A HREF="core.html#usecanonicalname">UseCanonicalName</A> setting because +otherwise log analysis programs would have to duplicate the entire +vhost matching algorithm in order to decide what host really served +the request. -<h2>Using Multiple Log Files</h2> +<H2>Using Multiple Log Files</H2> -The <code>TransferLog</code> and <code>CustomLog</code> directives can +The <CODE>TransferLog</CODE> and <CODE>CustomLog</CODE> directives can be given more than once to log requests to multiple log files. Each request will be logged to all the log files defined by either of these directives. -<h3>Use with Virtual Hosts</h3> +<H3>Use with Virtual Hosts</H3> If a <VirtualHost> section does not contain any -<tt>TransferLog</tt> or <tt>CustomLog</tt> directives, the +<TT>TransferLog</TT> or <TT>CustomLog</TT> directives, the logs defined for the main server will be used. If it does contain one or more of these directives, requests serviced by this virtual host will only be logged in the log files defined within its definition, not in any of the main server's log files. See the examples below. -<p> +<P> -<h2>Security Considerations</h2> +<H2>Security Considerations</H2> -See the <A HREF="../misc/security_tips.html">security tips</A> document -for details on why your security could be compromised if the directory -where logfiles are stored is writable by anyone other than the user -that starts the server. -<p> -<h2>Directives</h2> +See the <A HREF="../misc/security_tips.html#security">security tips</A> +document for details on why your security could be compromised if the +directory where logfiles are stored is writable by anyone other than +the user that starts the server. +<P> +<H2>Directives</H2> -<ul> -<li><A HREF="#cookielog">CookieLog</A> +<UL> +<LI><A HREF="#cookielog">CookieLog</A> <LI><A HREF="#customlog">CustomLog</A> -<li><A HREF="#logformat">LogFormat</A> -<li><A HREF="#transferlog">TransferLog</A> -</ul> -<hr> +<LI><A HREF="#customlog-conditional">CustomLog (conditional)</A> +<LI><A HREF="#logformat">LogFormat</A> +<LI><A HREF="#transferlog">TransferLog</A> +</UL> +<HR> -<h2><A name="cookielog">CookieLog</A></h2> +<H2><A NAME="cookielog">CookieLog</A></H2> <!--%plaintext <?INDEX {\tt CookieLog} directive> --> -<strong>Syntax:</strong> CookieLog <em>filename</em><br> -<Strong>Context:</strong> server config, virtual host<br> -<strong>Module:</strong> mod_cookies<br> -<strong>Compatibility:</strong> Only available in Apache 1.2 and above<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CookieLog <EM>filename</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_cookies<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Only available in Apache 1.2 and above<P> The CookieLog directive sets the filename for logging of cookies. The filename is relative to the <A HREF="core.html#serverroot">ServerRoot</A>. This directive is included -only for compatibility with <a -href="mod_cookies.html">mod_cookies</a>, and is deprecated. -<p> +only for compatibility with +<A HREF="mod_cookies.html">mod_cookies</A>, and is deprecated. +<P> +<HR> <H2><A NAME="customlog">CustomLog</A></H2> -<STRONG>Syntax:</STRONG> CustomLog <em>file-pipe</em> <em>format</em><BR> -<STRONG>Context:</STRONG> server config, virtual host<BR> -<STRONG>Status:</STRONG> Base<BR> -<STRONG>Module:</STRONG> mod_log_config<P> - -The first argument is the filename to log to. This is used -exactly like the argument to <tt>TransferLog</tt>, that is, -it is either a full path, or relative to the current -server root. <p> - +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CustomLog <EM>file-pipe</EM> + <EM>format-or-nickname</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Nickname only available in Apache 1.3 + or later +<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_config +<P> +The first argument is the filename to which log records should be +written. This is used +exactly like the argument to +<A + HREF="#transferlog" +><SAMP>TransferLog</SAMP></A>; +that is, it is either a full path or relative to the current +server root. +</P> +<P> The format argument specifies a format for each line of the log file. The options available for the format are exactly the same as for -the argument of the <tt>LogFormat</tt> directive. If the format +the argument of the <TT>LogFormat</TT> directive. If the format includes any spaces (which it will do in almost all cases) it should be enclosed in double quotes. +</P> +<P> +Instead of an actual format string, you can use a format nickname defined with +the +<A + HREF="#logformat" +><SAMP>LogFormat</SAMP></A> +directive. +</P> -<h2><A name="logformat">LogFormat</A></h2> -<!--%plaintext <?INDEX {\tt LogFormat} directive> --> -<strong>Syntax:</strong> LogFormat <em>string</em><br> -<strong>Default:</strong> <code>LogFormat "%h %l %u %t \"%r\" -%s %b"</code><br> -<Strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_log_config<p> +<HR> +<H2><A NAME="customlog-conditional">CustomLog (conditional)</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CustomLog <EM>file-pipe</EM> + <EM>format-or-nickname</EM> + env=[!]<EM>environment-variable</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Only available in Apache 1.3.5 + or later +<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_config +<P> + +The behaviour of this form of the <SAMP>CustomLog</SAMP> directive is almost +identical to the <A HREF="#customlog">standard <CODE>CustomLog</CODE></A> +directive. The difference is that the '<CODE>env=</CODE>' clause controls +whether a particular request will be logged in the specified file or +not. If the specified environment variable is set for the +request (or is not set, in the case of a '<CODE>env=!<EM>name</EM></CODE>' +clause), then the request will be logged. +</P> +<P> +Environment variables can be set on a <EM>per</EM>-request basis +using the <A HREF="mod_setenvif.html">mod_setenvif</A> and/or +<A HREF="mod_rewrite.html">mod_rewrite</A> modules. For example, +if you don't want to record requests for all GIF images on +your server in a separate logfile but not your main log, you +can use: +</P> +<PRE> + SetEnvIf Request_URI \.gif$ gif-image + CustomLog gif-requests.log common env=gif-image + CustomLog nongif-requests.log common env=!gif-image +</PRE> -This sets the format of the logfile. See <A HREF="#formats"> -Custom Log Formats</A> for details on the format arguments.<p><hr> +<HR> +<H2><A NAME="logformat">LogFormat</A></H2> +<!--%plaintext <?INDEX {\tt LogFormat} directive> --> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> LogFormat <EM>format</EM> [<EM>nickname</EM>] +<BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>LogFormat "%h %l %u %t \"%r\" +%s %b"</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Nickname only available in Apache 1.3 + or later +<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_config +<P> +This sets the format of the default logfile named by the +<A + HREF="#transferlog" +><SAMP>TransferLog</SAMP></A> +directive . See the section on +<A HREF="#formats">Custom Log Formats</A> for details on the format +arguments. +</P> +<P> +If you include a nickname for the format on the directive line, you can +use it in other <SAMP>LogFormat</SAMP> and +<A HREF="#customlog"><SAMP>CustomLog</SAMP></A> +directives rather than repeating the entire format string. +</P> +<P> +A +<SAMP>LogFormat</SAMP> directive which defines a nickname <STRONG>does +nothing else</STRONG> -- that is, it <EM>only</EM> defines the nickname, +it doesn't actually apply the format and make it the default. +</P> +<HR> -<h2><A name="transferlog">TransferLog</A></h2> +<H2><A NAME="transferlog">TransferLog</A></H2> <!--%plaintext <?INDEX {\tt TransferLog} directive> --> -<strong>Syntax:</strong> TransferLog <em>file-pipe</em><br> -<strong>Default:</strong> none<br> -<Strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_log_config<p> - -The TransferLog directive adds a log file in Common Log Format. -<em>File-pipe</em> is one +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> TransferLog <EM>file-pipe</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> none<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_config<P> + +The TransferLog directive adds a log file in the format defined by the +most recent +<A + HREF="#logformat" +><SAMP>LogFormat</SAMP></A> +directive, or Common Log Format if no other default format has been +specified. +<EM>File-pipe</EM> is one of -<dl><dt>A filename -<dd>A filename relative to the <A HREF="core.html#serverroot">ServerRoot</A>. -<dt> `|' followed by a command -<dd>A program to receive the agent log information on its standard input. +<DL><DT>A filename +<DD>A filename relative to the <A HREF="core.html#serverroot">ServerRoot</A>. +<DT> `|' followed by a command +<DD>A program to receive the agent log information on its standard input. Note the a new program will not be started for a VirtualHost if it inherits the TransferLog from the main server. -</dl> -<strong>Security:</strong> if a program is used, then it will be +</DL> +<STRONG>Security:</STRONG> if a program is used, then it will be run under the user who started httpd. This will be root if the server -was started by root; be sure that the program is secure.<p> +was started by root; be sure that the program is secure.<P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> @@ -272,5 +462,3 @@ was started by root; be sure that the program is secure.<p> </BODY> </HTML> - - diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_log_referer.html b/usr.sbin/httpd/htdocs/manual/mod/mod_log_referer.html index ab86f2967a8..04955d3f06d 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_log_referer.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_log_referer.html @@ -15,82 +15,112 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<H1 ALIGN="CENTER">Module mod_log_referer</h1> +<H1 ALIGN="CENTER">Module mod_log_referer</H1> -This module is contained in the <code>mod_log_referer.c</code> file, and is not +This module is contained in the <CODE>mod_log_referer.c</CODE> file, and is not compiled in by default. It provides for logging of the documents which -reference documents on the server. +reference documents on the server. As of Apache 1.3.5 it is deprecated. +Use <A HREF="mod_log_config.html#customlog-conditional">CustomLog +(conditional)</A> instead. -<h2>Log file format</h2> +<H2>Log file format</H2> The log file contains a separate line for each refer. Each line has the format -<blockquote><em>uri</em> <code>-></code> <em>document</em></blockquote> -where <em>uri</em> is the (%-escaped) URI for the document that references -the one requested by the client, and <em>document</em> is the (%-decoded) +<BLOCKQUOTE><EM>uri</EM> <CODE>-></CODE> <EM>document</EM></BLOCKQUOTE> +where <EM>uri</EM> is the (%-escaped) URI for the document that references +the one requested by the client, and <EM>document</EM> is the (%-decoded) local URL to the document being referred to. -<h2>Directives</h2> -<ul> -<li><A HREF="#refererignore">RefererIgnore</A> -<li><A HREF="#refererlog">RefererLog</A> -</ul> -<hr> +<H2>Directives</H2> +<UL> +<LI><A HREF="#refererignore">RefererIgnore</A> +<LI><A HREF="#refererlog">RefererLog</A> +</UL> +<HR> -<h2><A name="refererignore">RefererIgnore</A></h2> +<H2><A NAME="refererignore">RefererIgnore</A></H2> <!--%plaintext <?INDEX {\tt RefererIgnore} directive> --> -<strong>Syntax:</strong> RefererIgnore <em>string string ...</em><br> -<Strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_log_referer<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> RefererIgnore <EM>string string ...</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_referer<P> The RefererIgnore directive adds to the list of strings to ignore in Referer headers. If any of the strings in the list is contained in the Referer header, then no referrer information will be logged for the request. Example: -<blockquote><code>RefererIgnore www.ncsa.uiuc.edu</code></blockquote> +<BLOCKQUOTE><CODE>RefererIgnore www.ncsa.uiuc.edu</CODE></BLOCKQUOTE> This avoids logging references from www.ncsa.uiuc.edu. -<p><hr> +<P><HR> -<h2><A name="refererlog">RefererLog</A></h2> +<H2><A NAME="refererlog">RefererLog</A></H2> <!--%plaintext <?INDEX {\tt RefererLog} directive> --> -<strong>Syntax:</strong> RefererLog <em>file-pipe</em><br> -<strong>Default:</strong> <code>RefererLog logs/referer_log</code><br> -<Strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Extension<br> -<strong>Module:</strong> mod_log_referer<p> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> RefererLog <EM>file-pipe</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>RefererLog logs/referer_log</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Extension<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_referer<P> The RefererLog directive sets the name of the file to which the server will -log the Referer header of incoming requests. <em>File-pipe</em> is one +log the Referer header of incoming requests. <EM>File-pipe</EM> is one of -<dl><dt>A filename -<dd>A filename relative to the <A HREF="core.html#serverroot">ServerRoot</A>. -<dt> `|' followed by a command -<dd>A program to receive the referrer log information on its standard input. +<DL><DT>A filename +<DD>A filename relative to the <A HREF="core.html#serverroot">ServerRoot</A>. +<DT> `|' followed by a command +<DD>A program to receive the referrer log information on its standard input. Note the a new program will not be started for a VirtualHost if it inherits the RefererLog from the main server. -</dl> -<strong>Security:</strong> if a program is used, then it will be +</DL> +<STRONG>Security:</STRONG> if a program is used, then it will be run under the user who started httpd. This will be root if the server -was started by root; be sure that the program is secure.<p> +was started by root; be sure that the program is secure.<P> -<strong>Security:</strong> See the <A +<STRONG>Security:</STRONG> See the <A HREF="../misc/security_tips.html">security tips</A> document for details on why your security could be compromised if the directory where logfiles are stored is writable by anyone other than the user that starts the server.<P> -This directive is provided for compatibility with NCSA 1.4.<p> +This directive is provided for compatibility with NCSA 1.4.<P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_mime.html b/usr.sbin/httpd/htdocs/manual/mod/mod_mime.html index 1c02c8c3212..5afba4e0de5 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_mime.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_mime.html @@ -232,34 +232,51 @@ multiple extensions</A> <A HREF="directive-dict.html#Module" REL="Help" -><STRONG>Module:</STRONG></A> mod_mime<P> +><STRONG>Module:</STRONG></A> mod_mime +<P> The AddLanguage directive maps the given filename extensions to the specified content language. <EM>MIME-lang</EM> is the MIME language of filenames containing <EM>extension</EM>. This mapping is added to any already in force, overriding any mappings that already exist for the same <EM>extension</EM>. - +</P> +<P> Example: <BLOCKQUOTE><CODE> AddEncoding x-compress Z<BR> AddLanguage en .en<BR> AddLanguage fr .fr<BR> </CODE></BLOCKQUOTE> - +</P> +<P> Then the document <CODE>xxxx.en.Z</CODE> will be treated as being a compressed English document (as will the document <CODE>xxxx.Z.en</CODE>). Although the content language is reported to the client, the browser is unlikely to use this information. The -AddLanguage directive is more useful for <A -HREF="../content-negotiation.html">content negotiation</A>, where +AddLanguage directive is more useful for +<A HREF="../content-negotiation.html">content negotiation</A>, where the server returns one from several documents based on the client's -language preference.<P> - +language preference. +</P> +<P> +If multiple language assignments are made for the same extension, +the last one encountered is the one that is used. That is, for the +case of: +</P> +<PRE> + AddLanguage en .en + AddLanguage en-uk .en + AddLanguage en-us .en +</PRE> +<P> +documents with the extension "<CODE>.en</CODE>" would be treated as +being "<CODE>en-us</CODE>". +</P> <P> - <STRONG>See also</STRONG>: <A HREF="#multipleext">Files with multiple extensions</A> <BR> <STRONG>See also</STRONG>: <A HREF="./mod_negotiation.html">mod_negotiation</A> +</P> <HR> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_negotiation.html b/usr.sbin/httpd/htdocs/manual/mod/mod_negotiation.html index 818d5e1fd68..7e49cfa35b6 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_negotiation.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_negotiation.html @@ -52,26 +52,35 @@ The headers allowed are: <DL> <DT>Content-Encoding: -<DD>The encoding of the file. Currently only two encodings are recognized -by http; <CODE>x-compress</CODE> for compressed files, and <CODE>x-gzip</CODE> -for gzipped files. +<DD>The encoding of the file. Apache only recognizes encodings that are +defined by an <A HREF="mod_mime.html#addencoding">AddEncoding</A> directive. +This normally includes the encodings <CODE>x-compress</CODE> for compress'd +files, and <CODE>x-gzip</CODE> for gzip'd files. The <CODE>x-</CODE> prefix +is ignored for encoding comparisons. <DT>Content-Language: -<DD>The language of the variant, as an Internet standard language code, such -as <CODE>en</CODE>. +<DD>The language of the variant, as an Internet standard language tag +(RFC 1766). An example is <CODE>en</CODE>, meaning English. <DT>Content-Length: <DD>The length of the file, in bytes. If this header is not present, then the actual length of the file is used. <DT>Content-Type: <DD>The MIME media type of the document, with optional parameters. -parameters are separated from the media type and from one another by -semi-colons. Parameter syntax is name=value; allowed parameters are: +Parameters are separated from the media type and from one another by a +semi-colon, with a syntax of <CODE>name=value</CODE>. Common parameters +include: <DL> <DT>level -<DD>the value is an integer, which specifies the version of the media type. +<DD>an integer specifying the version of the media type. For <CODE>text/html</CODE> this defaults to 2, otherwise 0. <DT>qs -<DD>the value is a floating-point number with value between 0. and 1. -It indications the 'quality' of this variant. +<DD>a floating-point number with a value in the range 0.0 to 1.0, + indicating the relative 'quality' of this variant + compared to the other available variants, independent of the client's + capabilities. For example, a jpeg file is usually of higher source + quality than an ascii file if it is attempting to represent a + photograph. However, if the resource being represented is ascii art, + then an ascii file would have a higher source quality than a jpeg file. + All qs values are therefore specific to a given resource. </DL> Example: <BLOCKQUOTE><CODE>Content-Type: image/jpeg; qs=0.8</CODE></BLOCKQUOTE> @@ -97,6 +106,14 @@ requirements, and returns that document.<P> <LI><A HREF="#cachenegotiateddocs">CacheNegotiatedDocs</A> <LI><A HREF="#languagepriority">LanguagePriority</A> </UL> + +<STRONG>See also</STRONG>: +<A HREF="./mod_mime.html#defaultlanguage">DefaultLanguage</A>, +<A HREF="./mod_mime.html#addencoding">AddEncoding</A>, +<A HREF="./mod_mime.html#addlanguage">AddLanguage</A>, +<A HREF="./mod_mime.html#addtype">AddType</A>, and +<A HREF="core.html#options">Option</A>. + <HR> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_proxy.html b/usr.sbin/httpd/htdocs/manual/mod/mod_proxy.html index baf4c4ff65f..ae058fbc322 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_proxy.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_proxy.html @@ -15,72 +15,128 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<H1 ALIGN="CENTER">Module mod_proxy</H1> +<H1 ALIGN="CENTER">Apache module mod_proxy</H1> -This module is contained in the <code>mod_proxy.c</code> file for Apache 1.1.x, -or the <code>modules/proxy</code> subdirectory for Apache 1.2, and -is not compiled in by default. It provides for an <b>HTTP 1.0</b> caching proxy +This module is contained in the <CODE>mod_proxy.c</CODE> file for Apache 1.1.x, +or the <CODE>modules/proxy</CODE> subdirectory for Apache 1.2, and +is not compiled in by default. It provides for an <STRONG>HTTP +1.0</STRONG> caching proxy server. It is only available in Apache 1.1 and later. Common configuration -questions are addressed <a href="#configs">here</a>. +questions are addressed <A HREF="#configs">after the directive +descriptions</A>. -<h3>Note:</h3> -<p>This module was experimental in Apache 1.1.x. As of Apache 1.2, mod_proxy -stability is <i>greatly</i> improved.<p> +<H3>Note:</H3> +<P>This module was experimental in Apache 1.1.x. As of Apache 1.2, mod_proxy +stability is <EM>greatly</EM> improved.<P> -<h2>Summary</h2> +<H2>Summary</H2> This module implements a proxy/cache for Apache. It implements proxying capability for -<code>FTP</code>, -<code>CONNECT</code> (for SSL), -<code>HTTP/0.9</code>, and -<code>HTTP/1.0</code>. +<CODE>FTP</CODE>, +<CODE>CONNECT</CODE> (for SSL), +<CODE>HTTP/0.9</CODE>, and +<CODE>HTTP/1.0</CODE>. The module can be configured to connect to other proxy modules for these and other protocols. -<h2>Directives</h2> -<ul> -<li><a href="#proxyrequests">ProxyRequests</a> -<li><a href="#proxyremote">ProxyRemote</a> -<li><a href="#proxypass">ProxyPass</a> -<li><a href="#proxyblock">ProxyBlock</a> -<li><a href="#cacheroot">CacheRoot</a> -<li><a href="#cachesize">CacheSize</a> -<li><a href="#cachemaxexpire">CacheMaxExpire</a> -<li><a href="#cachedefaultexpire">CacheDefaultExpire</a> -<li><a href="#cachelastmodifiedfactor">CacheLastModifiedFactor</a> -<li><a href="#cachegcinterval">CacheGcInterval</a> -<li><a href="#cachedirlevels">CacheDirLevels</a> -<li><a href="#cachedirlength">CacheDirLength</a> -<li><a href="#nocache">NoCache</a> -</ul> - -<hr> - -<A name="proxyrequests"><h2>ProxyRequests</h2></A> -<strong>Syntax:</strong> ProxyRequests <em>on/off</em><br> -<strong>Default:</strong> <code>ProxyRequests Off</code><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> ProxyRequest is only available in -Apache 1.1 and later.<p> +<H2>Directives</H2> +<UL> +<LI><A HREF="#proxyrequests">ProxyRequests</A> +<LI><A HREF="#proxyremote">ProxyRemote</A> +<LI><A HREF="#proxypass">ProxyPass</A> +<LI><A HREF="#proxypassreverse">ProxyPassReverse</A> +<LI><A HREF="#proxyblock">ProxyBlock</A> +<LI><A HREF="#allowconnect">AllowCONNECT</A> +<LI><A HREF="#proxyreceivebuffersize">ProxyReceiveBufferSize</A> +<LI><A HREF="#noproxy">NoProxy</A> +<LI><A HREF="#proxydomain">ProxyDomain</A> +<LI><A HREF="#proxyvia">ProxyVia</A> +<LI><A HREF="#cacheroot">CacheRoot</A> +<LI><A HREF="#cachesize">CacheSize</A> +<LI><A HREF="#cachemaxexpire">CacheMaxExpire</A> +<LI><A HREF="#cachedefaultexpire">CacheDefaultExpire</A> +<LI><A HREF="#cachelastmodifiedfactor">CacheLastModifiedFactor</A> +<LI><A HREF="#cachegcinterval">CacheGcInterval</A> +<LI><A HREF="#cachedirlevels">CacheDirLevels</A> +<LI><A HREF="#cachedirlength">CacheDirLength</A> +<LI><A HREF="#cacheforcecompletion">CacheForceCompletion</A> +<LI><A HREF="#nocache">NoCache</A> +</UL> + +<HR> + +<H2><A NAME="proxyrequests">ProxyRequests</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyRequests <EM>on/off</EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>ProxyRequests Off</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyRequests is only available in +Apache 1.1 and later.<P> This allows or prevents Apache from functioning as a proxy -server. Setting ProxyRequests to 'off' does not disable use of the <a -href="#proxypass">ProxyPass</a> directive. +server. Setting ProxyRequests to 'off' does not disable use of the <A +HREF="#proxypass">ProxyPass</A> directive. + +<HR> -<A name="proxyremote"><h2>ProxyRemote</h2></A> -<strong>Syntax:</strong> ProxyRemote <em><match> <remote-server></em><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> ProxyRemote is only available in -Apache 1.1 and later.<p> +<H2><A NAME="proxyremote">ProxyRemote</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyRemote <EM><match> <remote-server></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyRemote is only available in +Apache 1.1 and later.<P> This defines remote proxies to this proxy. <match> is either the name of a URL-scheme that the remote server supports, or a partial URL @@ -88,287 +144,1028 @@ for which the remote server should be used, or '*' to indicate the server should be contacted for all requests. <remote-server> is a partial URL for the remote server. Syntax: -<pre> +<PRE> <remote-server> = <protocol>://<hostname>[:port] -</pre> +</PRE> <protocol> is the protocol that should be used to communicate with the remote server; only "http" is supported by this module. - +<P> Example: -<pre> +<PRE> ProxyRemote http://goodguys.com/ http://mirrorguys.com:8000 ProxyRemote * http://cleversite.com ProxyRemote ftp http://ftpproxy.mydomain.com:8080 -</pre> +</PRE> In the last example, the proxy will forward FTP requests, encapsulated as yet another HTTP proxy request, to another proxy which can handle them. -<A name="proxypass"><h2>ProxyPass</h2></A> -<strong>Syntax:</strong> ProxyPass <em><path> <url></em><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> ProxyPass is only available in -Apache 1.1 and later.<p> +<HR> + +<H2><A NAME="proxypass">ProxyPass</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyPass <EM><path> <url></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyPass is only available in +Apache 1.1 and later.<P> This directive allows remote servers to be mapped into the space of the local server; the local server does not act as a proxy in the conventional sense, but appears to be a mirror of the remote server. <path> is the name of a local virtual path; <url> is a partial URL for the remote server. +<P> +Suppose the local server has address <SAMP>http://wibble.org/</SAMP>; then +<PRE> + ProxyPass /mirror/foo/ http://foo.com/ +</PRE> +will cause a local request for the +<<SAMP>http://wibble.org/mirror/foo/bar</SAMP>> to be +internally converted into a proxy request to +<<SAMP>http://foo.com/bar</SAMP>>. + +<HR> + +<H2><A NAME="proxypassreverse">ProxyPassReverse</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyPassReverse <EM><path> <url></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyPassReverse is only available in +Apache 1.3b6 and later.<P> + +This directive lets Apache adjust the URL in the <TT>Location</TT> header on +HTTP redirect responses. For instance this is essential when Apache is used as +a reverse proxy to avoid by-passing the reverse proxy because of HTTP +redirects on the backend servers which stay behind the reverse proxy. +<P> +<path> is the name of a local virtual path.<BR> +<url> is a partial URL for the remote server - the same way they are +used for the <TT>ProxyPass</TT> directive. +<P> +Example:<BR> +Suppose the local server has address <SAMP>http://wibble.org/</SAMP>; then +<PRE> + ProxyPass /mirror/foo/ http://foo.com/ + ProxyPassReverse /mirror/foo/ http://foo.com/ +</PRE> +will not only cause a local request for the +<<SAMP>http://wibble.org/mirror/foo/bar</SAMP>> to be internally +converted into a proxy request to <<SAMP>http://foo.com/bar</SAMP>> (the +functionality <SAMP>ProxyPass</SAMP> provides here). It also takes care of +redirects the server foo.com sends: when <SAMP>http://foo.com/bar</SAMP> is +redirected by him to <SAMP>http://foo.com/quux</SAMP> Apache adjusts this to +<SAMP>http://wibble.org/mirror/foo/quux</SAMP> before forwarding the HTTP +redirect response to the client. +<P> +Note that this <SAMP>ProxyPassReverse</SAMP> directive can also be used in +conjunction with the proxy pass-through feature ("<SAMP>RewriteRule ... +[P]</SAMP>") from +<A + HREF="mod_rewrite.html#RewriteRule" +><TT>mod_rewrite</TT></A> because its doesn't depend on a corresponding +<SAMP>ProxyPass</SAMP> directive. + +<HR> + +<H2><A NAME="allowconnect">AllowCONNECT</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> AllowCONNECT <EM><port list></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM><SAMP>AllowCONNECT</SAMP> 443 563</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> <SAMP>AllowCONNECT</SAMP> is only +available in Apache 1.3.2 and later.<P> + +The <SAMP>AllowCONNECT</SAMP> directive specifies a list of port numbers +to which the proxy <SAMP>CONNECT</SAMP> method may connect. +Today's browsers use this method when a <EM>https</EM> connection +is requested and proxy tunneling over <EM>http</EM> is in effect.<BR> +By default, only the default https port (443) and the default +snews port (563) are enabled. Use the <SAMP>AllowCONNECT</SAMP> +directive to overrride this default and allow connections to the +listed ports only. + +<HR> -Suppose the local server has address http://wibble.org; then -<pre> - ProxyPass /mirror/foo http://foo.com -</pre> -Will cause a local request for the http://wibble.org/mirror/foo/bar to be -internally converted into a proxy request to http://foo.com/bar - -<A name="proxyblock"><h2>ProxyBlock</h2></A> -<strong>Syntax:</strong> ProxyBlock <em><word/host/domain list></em><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> ProxyBlock is only available in -Apache 1.2 and later.<p> +<H2><A NAME="proxyblock">ProxyBlock</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyBlock <EM><word/host/domain list></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyBlock is only available in +Apache 1.2 and later.<P> The ProxyBlock directive specifies a list of words, hosts and/or domains, -separated by spaces. HTTP, HTTPS, and FTP document requests to matched words, -hosts or domains are <em>blocked</em> by the proxy server. The proxy module -will also attempt to determine IP addresses of list items which may be -hostnames during startup, and cache them for match test as well. Example: +separated by spaces. HTTP, HTTPS, and FTP document requests to sites whose +names contain matched words, hosts or domains are <EM>blocked</EM> by the +proxy server. The proxy module will also attempt to determine IP addresses of +list items which may be hostnames during startup, and cache them for match +test as well. Example: -<pre> - ProxyBlock joes_garage.com some_host.co.uk rocky.wotsamattau.edu -</pre> +<PRE> + ProxyBlock joes-garage.com some-host.co.uk rocky.wotsamattau.edu +</PRE> -'rocky.wotsamattau.edu' would also be matched if referenced by IP address.<p> +'rocky.wotsamattau.edu' would also be matched if referenced by IP address.<P> -Note that 'wotsamattau' would also be sufficient to match 'wotsamattau.edu'.<p> +Note that 'wotsamattau' would also be sufficient to match 'wotsamattau.edu'.<P> Note also that -<pre> +<PRE> ProxyBlock * -</pre> +</PRE> blocks connections to all sites. -<A name="cacheroot"><h2>CacheRoot</h2></A> -<strong>Syntax:</strong> CacheRoot <em><directory></em><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheRoot is only available in -Apache 1.1 and later.<p> +<HR> + +<H2><A NAME="proxyreceivebuffersize">ProxyReceiveBufferSize</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyReceiveBufferSize <EM><bytes></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyReceiveBufferSize is only available in +Apache 1.3 and later.<P> + +The ProxyReceiveBufferSize directive specifies an explicit network buffer size +for outgoing HTTP and FTP connections, for increased throughput. It has to be +greater than 512 or set to 0 to indicate that the system's default buffer size +should be used. + +<P> +Example: + +<PRE> + ProxyReceiveBufferSize 2048 +</PRE> + +<HR> + +<H2><A NAME="noproxy">NoProxy</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> NoProxy { <A HREF="#domain"><EM><Domain></EM></A> + | <A HREF="#subnet"><EM><SubNet></EM></A> + | <A HREF="#ipaddr"><EM><IpAddr></EM></A> + | <A HREF="#hostname"><EM><Hostname></EM></A> + } <BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> NoProxy is only available in +Apache 1.3 and later.<P> + +This directive is only useful for Apache proxy servers within intranets. +The NoProxy directive specifies a list of subnets, IP addresses, hosts +and/or domains, separated by spaces. A request to a host which matches +one or more of these is always served directly, without forwarding to +the configured ProxyRemote proxy server(s). +<P> +Example: + +<PRE> + ProxyRemote * http://firewall.mycompany.com:81 + NoProxy .mycompany.com 192.168.112.0/21 +</PRE> +The arguments to the NoProxy directive are one of the following type list: + <DL> + <!-- ===================== Domain ======================= --> + <A NAME="domain"> + <DT><EM>Domain</EM></A> + <DD>A <EM>Domain</EM> is a partially qualified DNS domain name, preceded + by a period. + It represents a list of hosts which logically belong to the same DNS + domain or zone (<EM>i.e.</EM>, the suffixes of the hostnames are all ending in + <EM>Domain</EM>).<BR> + Examples: <SAMP>.com</SAMP> <SAMP>.apache.org.</SAMP><BR> + To distinguish <EM>Domain</EM>s from <A HREF="#hostname"><EM>Hostname</EM></A>s (both + syntactically and semantically; a DNS domain can have a DNS A record, + too!), <EM>Domain</EM>s are always written + with a leading period.<BR> + Note: Domain name comparisons are done without regard to the case, + and <EM>Domain</EM>s are always assumed to be anchored in the root + of the DNS tree, therefore two domains <SAMP>.MyDomain.com</SAMP> and + <SAMP>.mydomain.com.</SAMP> (note the trailing period) are + considered equal. Since a domain comparison does not involve a DNS + lookup, it is much more efficient than subnet comparison. + + <!-- ===================== SubNet ======================= --> + <A NAME="subnet"> + <DT><EM>SubNet</EM></A> + <DD>A <EM>SubNet</EM> is a partially qualified internet address in + numeric (dotted quad) form, optionally followed by a slash and the + netmask, specified as the number of significant bits in the + <EM>SubNet</EM>. It is used to represent a subnet of hosts which can + be reached over a common network interface. In the absence of the + explicit net mask it is assumed that omitted (or zero valued) + trailing digits specify the mask. (In this case, the netmask can + only be multiples of 8 bits wide.)<BR> + Examples: + <DL> + <DT><SAMP>192.168</SAMP> or <SAMP>192.168.0.0</SAMP> + <DD>the subnet 192.168.0.0 with an implied netmask of 16 valid bits + (sometimes used in the netmask form <SAMP>255.255.0.0</SAMP>) + <DT><SAMP>192.168.112.0/21</SAMP> + <DD>the subnet <SAMP>192.168.112.0/21</SAMP> with a netmask of 21 + valid bits (also used in the form 255.255.248.0) + </DL> + As a degenerate case, a <EM>SubNet</EM> with 32 valid bits is the + equivalent to an <EM>IPAddr</EM>, while a <EM>SubNet</EM> with zero + valid bits (<EM>e.g.</EM>, 0.0.0.0/0) is the same as the constant + <EM>_Default_</EM>, matching any IP address. + + <!-- ===================== IPAddr ======================= --> + <A NAME="ipaddr"> + <DT><EM>IPAddr</EM></A> + <DD>A <EM>IPAddr</EM> represents a fully qualified internet address in + numeric (dotted quad) form. Usually, this address represents a + host, but there need not necessarily be a DNS domain name + connected with the address.<BR> + Example: 192.168.123.7<BR> + Note: An <EM>IPAddr</EM> does not need to be resolved by the DNS + system, so it can result in more effective apache performance. + <P><STRONG>See Also:</STRONG> + <A HREF="../dns-caveats.html">DNS Issues</A></P> + + <!-- ===================== Hostname ======================= --> + <A NAME="hostname"> + <DT><EM>Hostname</EM></A> + <DD>A <EM>Hostname</EM> is a fully qualified DNS domain name which can + be resolved to one or more <A + HREF="#ipaddr"><EM>IPAddrs</EM></A> via the DNS domain name service. + It represents a logical host (in contrast to + <A HREF="#domain"><EM>Domain</EM></A>s, see + above) and must be resolvable to at least one <A + HREF="#ipaddr"><EM>IPAddr</EM></A> (or often to a list of hosts + with different <A HREF="#ipaddr"><EM>IPAddr</EM></A>'s).<BR> + Examples: <SAMP>prep.ai.mit.edu</SAMP> + <SAMP>www.apache.org.</SAMP><BR> + Note: In many situations, it is more effective to specify an + <A HREF="#ipaddr"><EM>IPAddr</EM></A> in place of a + <EM>Hostname</EM> since a DNS lookup + can be avoided. Name resolution in Apache can take a remarkable deal + of time when the connection to the name server uses a slow PPP + link.<BR> + Note: <EM>Hostname</EM> comparisons are done without regard to the case, + and <EM>Hostname</EM>s are always assumed to be anchored in the root + of the DNS tree, therefore two hosts <SAMP>WWW.MyDomain.com</SAMP> + and <SAMP>www.mydomain.com.</SAMP> (note the trailing period) are + considered equal.<BR> +<P><STRONG>See Also:</STRONG> +<A HREF="../dns-caveats.html">DNS Issues</A></P> + </DL> + +<HR> + +<H2><A NAME="proxydomain">ProxyDomain</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyDomain <EM><Domain></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyDomain is only available in +Apache 1.3 and later.<P> + +This directive is only useful for Apache proxy servers within intranets. +The ProxyDomain directive specifies the default domain which the apache +proxy server will belong to. If a request to a host without a domain name +is encountered, a redirection response to the same host +with the configured <EM>Domain</EM> appended will be generated. +<P> +Example: + +<PRE> + ProxyRemote * http://firewall.mycompany.com:81 + NoProxy .mycompany.com 192.168.112.0/21 + ProxyDomain .mycompany.com +</PRE> + +<HR> + +<H2><A NAME="proxyvia">ProxyVia</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> ProxyVia { <EM>off</EM> + | <EM>on</EM> + | <EM>full</EM> + | <EM>block</EM> + }<BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>ProxyVia off</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> ProxyVia is only available in +Apache 1.3.2 and later.<P> + +This directive controls the use of the <SAMP>Via:</SAMP> HTTP header +by the proxy. Its intended use is to control the flow of of proxy +requests along a chain of proxy servers. +See RFC2068 (HTTP/1.1) for an explanation of <SAMP>Via:</SAMP> header lines.<UL> +<LI>If set to <EM>off</EM>, which is the default, no special +processing is performed. If a request or reply contains a <SAMP>Via:</SAMP> header, +it is passed through unchanged. +<LI>If set to <EM>on</EM>, each request and reply will get a <SAMP>Via:</SAMP> header +line added for the current host. +<LI>If set to <EM>full</EM>, each generated <SAMP>Via:</SAMP> header line will +additionally have the Apache server version shown as a <SAMP>Via:</SAMP> comment field. +<LI>If set to <EM>block</EM>, every proxy request will have all its +<SAMP>Via:</SAMP> header lines removed. No new <SAMP>Via:</SAMP> header will be generated. +</UL> + +<HR> + +<H2><A NAME="cacheforcecompletion">CacheForceCompletion</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheForceCompletion <EM><percentage></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>90</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheForceCompletion is only available in +Apache 1.3.1 and later.<P> + +If an http transfer that is being cached is cancelled, the proxy module will +complete the transfer to cache if more than the percentage specified has +already been transferred.<P> + +This is a percentage, and must be a number between 1 and 100, or 0 to use +the default. 100 will cause a document to be cached only if the transfer +was allowed to complete. A number between 60 and 90 is recommended. + +<HR> + +<H2><A NAME="cacheroot">CacheRoot</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheRoot <EM><directory></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheRoot is only available in +Apache 1.1 and later.<P> Sets the name of the directory to contain cache files; this must be -writable -by the httpd server. - -<A name="cachesize"><h2>CacheSize</h2></A> -<strong>Syntax:</strong> CacheSize <em><size></em><br> -<strong>Default:</strong> <code>CacheSize 5</code><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheSize is only available in -Apache 1.1 and later.<p> - -Sets the desired space usage of the cache, in Kb (1024 byte units). Although +writable by the httpd server. +(see the <A HREF="core.html#user"><CODE>User</CODE></A> directive).<BR> +Setting <CODE>CacheRoot</CODE> enables proxy cacheing; without defining +a <CODE>CacheRoot</CODE>, proxy functionality will be available +if <CODE>ProxyRequests</CODE> are set to <CODE>On</CODE>, but no +cacheing will be available. + +<HR> + +<H2><A NAME="cachesize">CacheSize</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheSize <EM><size></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>CacheSize 5</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheSize is only available in +Apache 1.1 and later.<P> + +Sets the desired space usage of the cache, in KB (1024-byte units). Although usage may grow above this setting, the garbage collection will delete files -until the usage is at or below this setting. +until the usage is at or below this setting.<BR> +Depending on the expected proxy traffic volume and <CODE>CacheGcInterval</CODE>, +use a value which is at least 20 to 40 % lower than the available space. -<A name="cachegcinterval"><h2>CacheGcInterval</h2></A> -<strong>Syntax:</strong> CacheGcInterval <em><time></em><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheGcinterval is only available in -Apache 1.1 and later.<p> +<HR> + +<H2><A NAME="cachegcinterval">CacheGcInterval</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheGcInterval <EM><time></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheGcinterval is only available in +Apache 1.1 and later.<P> Check the cache every <time> hours, and delete files if the space -usage is greater than that set by CacheSize. +usage is greater than that set by CacheSize. Note that <time> accepts a +float value, you could for example use <CODE>CacheGcInterval 1.5</CODE> to +check the cache every 90 minutes. (If unset, no garbage collection will +be performed, and the cache will grow indefinitely.) +Note also that the larger the <CODE>CacheGcInterval</CODE>, the more +extra space beyond the configured <CODE>CacheSize</CODE> will be +needed for the cache between garbage collections.<BR> <!-- +Note that due to a design flaw, Apache does not automatically force a +garbage collection when the available space on the file system where +the cache resides is exhausted. --> + +<HR> -<A name="cachemaxexpire"><h2>CacheMaxExpire</h2></A> -<strong>Syntax:</strong> CacheMaxExpire <em><time></em><br> -<strong>Default:</strong> <code>CacheMaxExpire 24</code><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheMaxExpire is only available in -Apache 1.1 and later.<p> +<H2><A NAME="cachemaxexpire">CacheMaxExpire</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheMaxExpire <EM><time></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>CacheMaxExpire 24</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheMaxExpire is only available in +Apache 1.1 and later.<P> Cachable HTTP documents will be retained for at most <time> hours without checking the origin server. Thus documents can be at most <time> hours out of date. This restriction is enforced even if an expiry date was supplied with the document. -<A name="cachelastmodifiedfactor"><h2>CacheLastModifiedFactor</h2></A> -<strong>Syntax:</strong> CacheLastModifiedFactor <em><factor></em><br> -<strong>Default:</strong> <code>CacheLastModifiedFactor 0.1</code><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheLastModifiedFactor is only available in -Apache 1.1 and later.<p> +<HR> + +<H2><A NAME="cachelastmodifiedfactor">CacheLastModifiedFactor</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheLastModifiedFactor <EM><factor></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>CacheLastModifiedFactor 0.1</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheLastModifiedFactor is only available in +Apache 1.1 and later.<P> If the origin HTTP server did not supply an expiry date for the document, then estimate one using the formula -<pre> +<PRE> expiry-period = time-since-last-modification * <factor> -</pre> +</PRE> For example, if the document was last modified 10 hours ago, and <factor> is 0.1, then the expiry period will be set to 10*0.1 = 1 hour. -<p>If the expiry-period would be longer than that set by CacheMaxExpire, +<P>If the expiry-period would be longer than that set by CacheMaxExpire, then the latter takes precedence. -<A name="cachedirlevels"><h2>CacheDirLevels</h2></A> -<strong>Syntax:</strong> CacheDirLevels <em><levels></em><br> -<strong>Default:</strong> <code>CacheDirLevels 3</code><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheDirLevels is only available in -Apache 1.1 and later.<p> +<HR> + +<H2><A NAME="cachedirlevels">CacheDirLevels</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheDirLevels <EM><levels></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>CacheDirLevels 3</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheDirLevels is only available in +Apache 1.1 and later.<P> CacheDirLevels sets the number of levels of subdirectories in the cache. Cached data will be saved this many directory levels below CacheRoot. -<A name="cachedirlength"><h2>CacheDirLength</h2></A> -<strong>Syntax:</strong> CacheDirLength <em><length></em><br> -<strong>Default:</strong> <code>CacheDirLength 1</code><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheDirLength is only available in -Apache 1.1 and later.<p> +<HR> + +<H2><A NAME="cachedirlength">CacheDirLength</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheDirLength <EM><length></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>CacheDirLength 1</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheDirLength is only available in +Apache 1.1 and later.<P> CacheDirLength sets the number of characters in proxy cache subdirectory names. -<A name="cachedefaultexpire"><h2>CacheDefaultExpire</h2></A> -<strong>Syntax:</strong> CacheDefaultExpire <em><time></em><br> -<strong>Default:</strong> <code>CacheDefaultExpire 1</code><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> CacheDefaultExpire is only available in -Apache 1.1 and later.<p> +<HR> + +<H2><A NAME="cachedefaultexpire">CacheDefaultExpire</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CacheDefaultExpire <EM><time></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <CODE>CacheDefaultExpire 1</CODE><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> CacheDefaultExpire is only available in +Apache 1.1 and later.<P> If the document is fetched via a protocol that does not support expiry times, then use <time> hours as the expiry time. -<a href="#cachemaxexpire">CacheMaxExpire</a> does <strong>not</strong> -override. +<A HREF="#cachemaxexpire">CacheMaxExpire</A> does <STRONG>not</STRONG> +override this setting. + +<HR> -<A name="nocache"><h2>NoCache</h2></A> -<strong>Syntax:</strong> NoCache <em><word/host/domain list></em><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> Base<br> -<strong>Module:</strong> mod_proxy<br> -<strong>Compatibility:</strong> NoCache is only available in -Apache 1.1 and later.<p> +<H2><A NAME="nocache">NoCache</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> NoCache <EM><word/host/domain list></EM><BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>None</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> <EM>Not applicable</EM><BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_proxy<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> NoCache is only available in +Apache 1.1 and later.<P> The NoCache directive specifies a list of words, hosts and/or domains, separated by spaces. HTTP and non-passworded FTP documents from matched words, hosts or -domains are <em>not</em> cached by the proxy server. The proxy module will +domains are <EM>not</EM> cached by the proxy server. The proxy module will also attempt to determine IP addresses of list items which may be hostnames during startup, and cache them for match test as well. Example: -<pre> - NoCache joes_garage.com some_host.co.uk bullwinkle.wotsamattau.edu -</pre> +<PRE> + NoCache joes-garage.com some-host.co.uk bullwinkle.wotsamattau.edu +</PRE> 'bullwinkle.wotsamattau.edu' would also be matched if referenced by IP -address.<p> +address.<P> -Note that 'wotsamattau' would also be sufficient to match 'wotsamattau.edu'.<p> +Note that 'wotsamattau' would also be sufficient to match 'wotsamattau.edu'.<P> Note also that -<pre> +<PRE> NoCache * -</pre> +</PRE> -disables caching completely.<p> +disables caching completely.<P> -<hr> +<HR> -<a name="configs"><h2>Common configuration topics</h2></a> +<H2><A NAME="configs">Common configuration topics</A></H2> -<ul> -<li><a href="#access">Controlling access to your proxy</a> -<li><a href="#shortname">Using Netscape hostname shortcuts</a> -<li><a href="#mimetypes">Why doesn't file type <i>xxx</i> download via FTP?</a> -<li><a href="#startup">Why does Apache start more slowly when using the - proxy module?</a> -<li><a href="#socks">Can I use the Apache proxy module with my SOCKS proxy?</a> -</ul> +<UL> +<LI><A HREF="#access">Controlling access to your proxy</A> +<LI><A HREF="#shortname">Using Netscape hostname shortcuts</A> +<LI><A HREF="#mimetypes">Why doesn't file type <EM>xxx</EM> download via FTP?</A> +<LI><A HREF="#startup">Why does Apache start more slowly when using the + proxy module?</A> +<LI><A HREF="#socks">Can I use the Apache proxy module with my SOCKS proxy?</A> +<LI><A HREF="#intranet">What other functions are useful for an intranet proxy server?</A> +</UL> -<h2><a name="access">Controlling access to your proxy</a></h2> +<H2><A NAME="access">Controlling access to your proxy</A></H2> You can control who can access your proxy via the normal <Directory> -control block using the following example:<p> +control block using the following example:<P> -<pre> +<PRE> <Directory proxy:*> -<Limit GET PUT POST DELETE CONNECT OPTIONS> order deny,allow deny from [machines you'd like *not* to allow by IP address or name] allow from [machines you'd like to allow by IP address or name] -</Limit> </Directory> -</pre><p> +</PRE><P> A <Files> block will also work, and is the only method known to work -for all possible URLs in Apache versions earlier than 1.2b10.<p> +for all possible URLs in Apache versions earlier than 1.2b10.<P> -<h2><a name="shortname">Using Netscape hostname shortcuts</a></h2> +<H2><A NAME="shortname">Using Netscape hostname shortcuts</A></H2> There is an optional patch to the proxy module to allow Netscape-like -hostname shortcuts to be used. It's available -<a href="http://www.apache.org/dist/contrib/patches/1.2/netscapehost.patch"> -here</a>.<p> +hostname shortcuts to be used. It's available from the +<A HREF="http://www.apache.org/dist/contrib/patches/1.2/netscapehost.patch" +><SAMP>contrib/patches/1.2</SAMP></A> directory on the Apache Web site.<P> -<h2><a name="mimetypes">Why doesn't file type <i>xxx</i> download via FTP?</a></h2> +<H2><A NAME="mimetypes">Why doesn't file type <EM>xxx</EM> download via FTP?</A></H2> You probably don't have that particular file type defined as -<i>application/octet-stream</i> in your proxy's mime.types configuration -file. A useful line can be<p> +<EM>application/octet-stream</EM> in your proxy's mime.types configuration +file. A useful line can be<P> -<pre> +<PRE> application/octet-stream bin dms lha lzh exe class tgz taz -</pre> +</PRE> -<h2><a name="startup">Why does Apache start more slowly when using the - proxy module?</a></h2> +<H2><A NAME="type">How can I force an FTP ASCII download of File <EM>xxx</EM>?</A></H2> -If you're using the <code>ProxyBlock</code> or <code>NoCache</code> +In the rare situation where you must download a specific file using the FTP +<STRONG>ASCII</STRONG> transfer method (while the default transfer is in +<STRONG>binary</STRONG> mode), you can override mod_proxy's default by +suffixing the request with <SAMP>;type=a</SAMP> to force an ASCII transfer.<P> + +<H2><A NAME="startup">Why does Apache start more slowly when using the + proxy module?</A></H2> + +If you're using the <CODE>ProxyBlock</CODE> or <CODE>NoCache</CODE> directives, hostnames' IP addresses are looked up and cached during startup for later match test. This may take a few seconds (or more) -depending on the speed with which the hostname lookups occur.<p> +depending on the speed with which the hostname lookups occur.<P> -<h2><a name="socks">Can I use the Apache proxy module with my SOCKS proxy?</a></h2> +<H2><A NAME="socks">Can I use the Apache proxy module with my SOCKS proxy?</A></H2> -Yes. Just build Apache with the rule <code>SOCKS4=yes</code> in your -<i>Configuration</i> file, and follow the instructions there. SOCKS5 -capability can be added in a similar way (there's no <code>SOCKS5</code> -rule yet), so use the <code>EXTRA_LFLAGS</code> definition, or build Apache -normally and run it with the <i>runsocks</i> wrapper provided with SOCKS5, -if your OS supports dynamically linked libraries.<p> +Yes. Just build Apache with the rule <CODE>SOCKS4=yes</CODE> in your +<EM>Configuration</EM> file, and follow the instructions there. SOCKS5 +capability can be added in a similar way (there's no <CODE>SOCKS5</CODE> +rule yet), so use the <CODE>EXTRA_LDFLAGS</CODE> definition, or build Apache +normally and run it with the <EM>runsocks</EM> wrapper provided with SOCKS5, +if your OS supports dynamically linked libraries.<P> Some users have reported problems when using SOCKS version 4.2 on Solaris. -The problem was solved by upgrading to SOCKS 4.3.<p> +The problem was solved by upgrading to SOCKS 4.3.<P> Remember that you'll also have to grant access to your Apache proxy machine by permitting connections on the appropriate ports in your SOCKS daemon's -configuration.<p> +configuration.<P> + +<H2><A NAME="intranet">What other functions are useful for an intranet proxy server?</A></H2> + +<P>An Apache proxy server situated in an intranet needs to forward external +requests through the company's firewall. However, when it has to access +resources within the intranet, it can bypass the firewall when accessing +hosts. The <A HREF="#noproxy">NoProxy</A> directive is useful for specifying +which hosts belong to the intranet and should be accessed directly.</P> + +<P>Users within an intranet tend to omit the local domain name from their +WWW requests, thus requesting "http://somehost/" instead of +"http://somehost.my.dom.ain/". Some commercial proxy servers let them get +away with this and simply serve the request, implying a configured +local domain. When the <A HREF="#proxydomain">ProxyDomain</A> directive +is used and the server is <A HREF="#proxyrequests">configured for +proxy service</A>, Apache can return a redirect response and send the client +to the correct, fully qualified, server address. This is the preferred method +since the user's bookmark files will then contain fully qualified hosts.</P> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_rewrite.html b/usr.sbin/httpd/htdocs/manual/mod/mod_rewrite.html index 118ea068ccd..37a7316bbd4 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_rewrite.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_rewrite.html @@ -558,7 +558,7 @@ RewriteLogLevel 3 <A HREF="directive-dict.html#Context" REL="Help" -><STRONG>Context:</STRONG></A> server config, virtual host<BR> +><STRONG>Context:</STRONG></A> server config<BR> <A HREF="directive-dict.html#Override" REL="Help" @@ -581,7 +581,7 @@ This directive sets the filename for a synchronization lockfile which mod_rewrite needs to communicate with <SAMP>RewriteMap</SAMP> <EM>programs</EM>. Set this lockfile to a local path (not on a NFS-mounted device) when you want to use a rewriting map-program. It is not required for -SAMP using all other types of rewriting maps. +all other types of rewriting maps. <P> <HR NOSHADE SIZE=1> @@ -1084,6 +1084,7 @@ AUTH_TYPE<BR> DOCUMENT_ROOT<BR> SERVER_ADMIN<BR> SERVER_NAME<BR> +SERVER_ADDR<BR> SERVER_PORT<BR> SERVER_PROTOCOL<BR> SERVER_SOFTWARE<BR> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_setenvif.html b/usr.sbin/httpd/htdocs/manual/mod/mod_setenvif.html index 507845a8e54..d199f0c177d 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_setenvif.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_setenvif.html @@ -266,7 +266,9 @@ <A HREF="directive-dict.html#Compatibility" REL="Help" - ><STRONG>Compatibility:</STRONG></A> Apache 1.3 and above + ><STRONG>Compatibility:</STRONG></A> Apache 1.3 and above; the + Request_Protocol keyword and environment-variable matching are only + available with 1.3.7 and later </P> <P> The <SAMP>SetEnvIf</SAMP> directive defines environment variables @@ -291,6 +293,10 @@ <LI><SAMP>Request_Method</SAMP> - the name of the method being used (<SAMP>GET</SAMP>, <SAMP>POST</SAMP>, <EM>et cetera</EM>) </LI> + <LI><SAMP>Request_Protocol</SAMP> - the name and version of the protocol + with which the request was made (<EM>e.g.</EM>, "HTTP/0.9", "HTTP/1.1", + <EM>etc.</EM>) + </LI> <LI><SAMP>Request_URI</SAMP> - the portion of the URL following the scheme and host portion </LI> @@ -300,15 +306,34 @@ <SAMP>Host</SAMP>, <SAMP>User-Agent</SAMP>, and <SAMP>Referer</SAMP>. </P> <P> + If the <EM>attribute</EM> name doesn't match any of the special keywords, + nor any of the request's header field names, it is tested as the name + of an environment variable in the list of those associated with the request. + This allows <CODE>SetEnvIf</CODE> directives to test against the result + of prior matches. + </P> + <BLOCKQUOTE> + <STRONG>Only those environment variables defined by earlier + <CODE>SetEnvIf[NoCase]</CODE> directives are available for testing in + this manner. 'Earlier' means that they were defined at a broader scope + (such as server-wide) or previously in the current directive's + scope.</STRONG> + </BLOCKQUOTE> + <P> Example: </P> <PRE> - SetEnvIf Request_URI "\.(gif)|(jpg)|(xbm)$" object_is_image + SetEnvIf Request_URI "\.gif$" object_is_image=gif + SetEnvIf Request_URI "\.jpg$" object_is_image=jpg + SetEnvIf Request_URI "\.xbm$" object_is_image=xbm + : SetEnvIf Referer www\.mydomain\.com intra_site_referral + : + SetEnvIf object_is_image xbm XBIT_PROCESSING=1 </PRE> <P> - The first will set the envariable <SAMP>object_is_image</SAMP> if the - request was for an image file, and the second sets + The first three will set the envariable <SAMP>object_is_image</SAMP> if the + request was for an image file, and the fourth sets <SAMP>intra_site_referral</SAMP> if the referring page was somewhere on the <SAMP>www.mydomain.com</SAMP> Web site. </P> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_so.html b/usr.sbin/httpd/htdocs/manual/mod/mod_so.html index bd466f4aab9..e650f762ea6 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_so.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_so.html @@ -63,7 +63,7 @@ Shared Object</A> (DSO) mechanism, rather than requiring a recompilation. <A HREF="directive-dict.html#Status" REL="Help" -><STRONG>Status:</STRONG></A> Experimental<BR> +><STRONG>Status:</STRONG></A> Base<BR> <A HREF="directive-dict.html#Module" REL="Help" @@ -88,7 +88,7 @@ HREF="core.html#serverroot">ServerRoot</A>.<P><HR> <A HREF="directive-dict.html#Status" REL="Help" -><STRONG>Status:</STRONG></A> Experimental<BR> +><STRONG>Status:</STRONG></A> Base<BR> <A HREF="directive-dict.html#Module" REL="Help" diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/index.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/index.html index 3b5f78867d2..e34ed1cc1e1 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/index.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/index.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -110,6 +110,14 @@ H4 { font-variant: normal; font-style: normal; } +#howto { + font-weight: bold; + font-size: 16pt; + line-height: 16pt; + font-family: arial,helvetica; + font-variant: normal; + font-style: normal; +} #term { font-weight: bold; font-size: 16pt; @@ -129,21 +137,33 @@ H4 { <table cellspacing="0" cellpadding="0" border="0"> <tr> <td> + <table cellspacing="0" cellpadding="0" border="0"> + <tr> + <td> <img - src="ssl_cover_title.gif" + src="ssl_cover_title.jpg" alt="User Manual" - width="377" height="56"> + width="421" height="73"> + </td> + </tr> + <tr> + <td align="right"> + <font face="Arial,Helvetica">mod_ssl version 2.4</font> + </td> + </tr> + </table> + <br> </td> </tr> <tr> <td> <a - href="http://www.engelschall.com" + href="http://www.modssl.org/" ><img src="ssl_cover_logo.jpg" - alt="mod_ssl - The Apache Interface to SSLeay" + alt="mod_ssl - The Apache Interface to OpenSSL" border="0" - width="546" height="294"></a> + width="504" height="231"></a> </td> </tr> <tr> @@ -151,9 +171,9 @@ H4 { <table> <tr> <td> - Ralf S. Engelschall<br> - <font size="-1">rse@engelschall.com</font><br> - <font size="-1">www.engelschall.com</font><br> + <tt>Ralf S. Engelschall</tt><br> + <tt>rse@engelschall.com</tt><br> + <tt>www.engelschall.com</tt><br> </td> <td> @@ -196,6 +216,9 @@ if (document.images) { border="0" ></a><br>Overview </td> + <td> + <img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="30" height="1" align="bottom" border="0"> + </td> </tr> </table> </td> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.html index f362f7e10d8..cdb28cb9c85 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -333,7 +333,7 @@ provide. <tr id="D"><td colspan="3"><b>Sioux 1.x compatibility:</b></td></tr> <tr id="H"><td><code>SSL_CertFile</code> <em>file</em></td><td><code>SSLCertificateFile</code> <em>file</em></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_KeyFile</code> <em>file</em></td><td><code>SSLCertificateKeyFile</code> <em>file</em></td><td>renamed</td></tr> -<tr id="H"><td><code>SSL_CipherSuite</code> <em>arg</em></td><td><code>SSLCipherList</code> <em>arg</em></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_CipherSuite</code> <em>arg</em></td><td><code>SSLCipherSuite</code> <em>arg</em></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_X509VerifyDir</code> <em>arg</em></td><td><code>SSLCACertificatePath</code> <em>arg</em></td><td>renamed</td></tr> <tr id="H"><td><code>SSL_Log</code> <em>file</em></td><td><code>SSLLogFile</code> <em>file</em></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_Connect</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renamed</td></tr> @@ -347,6 +347,9 @@ provide. <tr id="D"><td><code>SSL_X509VerifyPolicy</code> <em>arg</em></td><td>-</td><td>functionality not supported</td></tr> <tr id="H"><td><code>SSL_LogX509Attributes</code> <em>arg</em></td><td>-</td><td>functionality not supported</td></tr> <tr id="D"><td colspan="3"><b>Stronghold 2.x compatibility:</b></td></tr> +<tr id="H"><td><code>StrongholdAccelerator</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr> +<tr id="H"><td><code>StrongholdKey</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr> +<tr id="H"><td><code>StrongholdLicenseFile</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr> <tr id="H"><td><code>SSLFlag</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renamed</td></tr> <tr id="D"><td><code>SSLSessionLockFile</code> <em>file</em></td><td><code>SSLMutex</code> <em>file</em></td><td>renamed</td></tr> <tr id="H"><td><code>SSLCipherList</code> <em>spec</em></td><td><code>SSLCipherSuite</code> <em>spec</em></td><td>renamed</td></tr> @@ -396,6 +399,8 @@ href="#table2">Table 2</a>. <tr id="D"><td><code>SSL_SERVER_CERTIFICATE</code></td><td><code>SSL_SERVER_CERT</code></td><td>renamed</td></tr> <tr id="H"><td><code>SSL_SERVER_CERT_START</code></td><td><code>SSL_SERVER_V_START</code></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_SERVER_CERT_END</code></td><td><code>SSL_SERVER_V_END</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_SERVER_CERT_SERIAL</code></td><td><code>SSL_SERVER_M_SERIAL</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_SERVER_SIGNATURE_ALGORITHM</code></td><td><code>SSL_SERVER_A_SIG</code></td><td>renamed</td></tr> <tr id="H"><td><code>SSL_SERVER_DN</code></td><td><code>SSL_SERVER_S_DN</code></td><td>renamed</td></tr> <tr id="H"><td><code>SSL_SERVER_CN</code></td><td><code>SSL_SERVER_S_DN_CN</code></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_SERVER_EMAIL</code></td><td><code>SSL_SERVER_S_DN_Email</code></td><td>renamed</td></tr> @@ -415,6 +420,8 @@ href="#table2">Table 2</a>. <tr id="H"><td><code>SSL_CLIENT_CERTIFICATE</code></td><td><code>SSL_CLIENT_CERT</code></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_CLIENT_CERT_START</code></td><td><code>SSL_CLIENT_V_START</code></td><td>renamed</td></tr> <tr id="H"><td><code>SSL_CLIENT_CERT_END</code></td><td><code>SSL_CLIENT_V_END</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_CLIENT_CERT_SERIAL</code></td><td><code>SSL_CLIENT_M_SERIAL</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_CLIENT_SIGNATURE_ALGORITHM</code></td><td><code>SSL_CLIENT_A_SIG</code></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_CLIENT_DN</code></td><td><code>SSL_CLIENT_S_DN</code></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_CLIENT_CN</code></td><td><code>SSL_CLIENT_S_DN_CN</code></td><td>renamed</td></tr> <tr id="H"><td><code>SSL_CLIENT_EMAIL</code></td><td><code>SSL_CLIENT_S_DN_Email</code></td><td>renamed</td></tr> @@ -431,9 +438,14 @@ href="#table2">Table 2</a>. <tr id="H"><td><code>SSL_CLIENT_IC</code></td><td><code>SSL_CLIENT_I_DN_C</code></td><td>renamed</td></tr> <tr id="D"><td><code>SSL_CLIENT_ISP</code></td><td><code>SSL_CLIENT_I_DN_SP</code></td><td>renamed</td></tr> <tr id="H"><td><code>SSL_CLIENT_IL</code></td><td><code>SSL_CLIENT_I_DN_L</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_EXPORT</code></td><td><code>SSL_CIPHER_EXPORT</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_KEYSIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_SECKEYSIZE</code></td><td><code>SSL_CIPHER_USEKEYSIZE</code></td><td>renamed</td></tr> +<tr id="H"><td><code>SSL_SSLEAY_VERSION</code></td><td><code>SSL_VERSION_LIBRARY</code></td><td>renamed</td></tr> +<tr id="D"><td><code>SSL_STRONG_CRYPTO</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id="D"><td><code>SSL_SERVER_KEY_EXP</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id="H"><td><code>SSL_SERVER_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> -<tr id="D"><td><code>SSL_SERVER_SIGNATURE_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> +<tr id="D"><td><code>SSL_SERVER_KEY_SIZE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id="H"><td><code>SSL_SERVER_SESSIONDIR</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id="D"><td><code>SSL_SERVER_CERTIFICATELOGDIR</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id="H"><td><code>SSL_SERVER_CERTFILE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> @@ -442,7 +454,6 @@ href="#table2">Table 2</a>. <tr id="D"><td><code>SSL_CLIENT_KEY_EXP</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id="H"><td><code>SSL_CLIENT_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id="D"><td><code>SSL_CLIENT_KEY_SIZE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> -<tr id="H"><td><code>SSL_CLIENT_SIGNATURE_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> </table></td> </tr></table> </td></tr></table> @@ -544,8 +555,8 @@ if (document.images) { <td> <table width="598"> <tr> <td align="left"><font face="Arial,Helvetica"> - <a href="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</a> 2.2, User Manual<br> - The Apache Interface to SSLeay + <a href="http://www.modssl.org/">mod_ssl</a> 2.4, User Manual<br> + The Apache Interface to OpenSSL </font> </td> <td align="right"><font face="Arial,Helvetica"> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.wml index 512f239b7cb..33bd4ea3ba5 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_compat.wml @@ -102,7 +102,7 @@ provide. <tr id=D><td colspan=3><b>Sioux 1.x compatibility:</b></td></tr> <tr id=H><td><code>SSL_CertFile</code> <em>file</em></td><td><code>SSLCertificateFile</code> <em>file</em></td><td>renamed</td></tr> <tr id=D><td><code>SSL_KeyFile</code> <em>file</em></td><td><code>SSLCertificateKeyFile</code> <em>file</em></td><td>renamed</td></tr> -<tr id=H><td><code>SSL_CipherSuite</code> <em>arg</em></td><td><code>SSLCipherList</code> <em>arg</em></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_CipherSuite</code> <em>arg</em></td><td><code>SSLCipherSuite</code> <em>arg</em></td><td>renamed</td></tr> <tr id=D><td><code>SSL_X509VerifyDir</code> <em>arg</em></td><td><code>SSLCACertificatePath</code> <em>arg</em></td><td>renamed</td></tr> <tr id=H><td><code>SSL_Log</code> <em>file</em></td><td><code>SSLLogFile</code> <em>file</em></td><td>renamed</td></tr> <tr id=D><td><code>SSL_Connect</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renamed</td></tr> @@ -117,6 +117,9 @@ provide. <tr id=H><td><code>SSL_LogX509Attributes</code> <em>arg</em></td><td>-</td><td>functionality not supported</td></tr> <tr id=D><td colspan=3><b>Stronghold 2.x compatibility:</b></td></tr> +<tr id=H><td><code>StrongholdAccelerator</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr> +<tr id=H><td><code>StrongholdKey</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr> +<tr id=H><td><code>StrongholdLicenseFile</code> <em>dir</em></td><td>-</td><td>functionality not supported</td></tr> <tr id=H><td><code>SSLFlag</code> <em>flag</em></td><td><code>SSLEngine</code> <em>flag</em></td><td>renamed</td></tr> <tr id=D><td><code>SSLSessionLockFile</code> <em>file</em></td><td><code>SSLMutex</code> <em>file</em></td><td>renamed</td></tr> <tr id=H><td><code>SSLCipherList</code> <em>spec</em></td><td><code>SSLCipherSuite</code> <em>spec</em></td><td>renamed</td></tr> @@ -162,6 +165,8 @@ href="#table2">Table 2</a>. <tr id=D><td><code>SSL_SERVER_CERTIFICATE</code></td><td><code>SSL_SERVER_CERT</code></td><td>renamed</td></tr> <tr id=H><td><code>SSL_SERVER_CERT_START</code></td><td><code>SSL_SERVER_V_START</code></td><td>renamed</td></tr> <tr id=D><td><code>SSL_SERVER_CERT_END</code></td><td><code>SSL_SERVER_V_END</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_SERVER_CERT_SERIAL</code></td><td><code>SSL_SERVER_M_SERIAL</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_SERVER_SIGNATURE_ALGORITHM</code></td><td><code>SSL_SERVER_A_SIG</code></td><td>renamed</td></tr> <tr id=H><td><code>SSL_SERVER_DN</code></td><td><code>SSL_SERVER_S_DN</code></td><td>renamed</td></tr> <tr id=H><td><code>SSL_SERVER_CN</code></td><td><code>SSL_SERVER_S_DN_CN</code></td><td>renamed</td></tr> <tr id=D><td><code>SSL_SERVER_EMAIL</code></td><td><code>SSL_SERVER_S_DN_Email</code></td><td>renamed</td></tr> @@ -181,6 +186,8 @@ href="#table2">Table 2</a>. <tr id=H><td><code>SSL_CLIENT_CERTIFICATE</code></td><td><code>SSL_CLIENT_CERT</code></td><td>renamed</td></tr> <tr id=D><td><code>SSL_CLIENT_CERT_START</code></td><td><code>SSL_CLIENT_V_START</code></td><td>renamed</td></tr> <tr id=H><td><code>SSL_CLIENT_CERT_END</code></td><td><code>SSL_CLIENT_V_END</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_CLIENT_CERT_SERIAL</code></td><td><code>SSL_CLIENT_M_SERIAL</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_CLIENT_SIGNATURE_ALGORITHM</code></td><td><code>SSL_CLIENT_A_SIG</code></td><td>renamed</td></tr> <tr id=D><td><code>SSL_CLIENT_DN</code></td><td><code>SSL_CLIENT_S_DN</code></td><td>renamed</td></tr> <tr id=D><td><code>SSL_CLIENT_CN</code></td><td><code>SSL_CLIENT_S_DN_CN</code></td><td>renamed</td></tr> <tr id=H><td><code>SSL_CLIENT_EMAIL</code></td><td><code>SSL_CLIENT_S_DN_Email</code></td><td>renamed</td></tr> @@ -197,9 +204,14 @@ href="#table2">Table 2</a>. <tr id=H><td><code>SSL_CLIENT_IC</code></td><td><code>SSL_CLIENT_I_DN_C</code></td><td>renamed</td></tr> <tr id=D><td><code>SSL_CLIENT_ISP</code></td><td><code>SSL_CLIENT_I_DN_SP</code></td><td>renamed</td></tr> <tr id=H><td><code>SSL_CLIENT_IL</code></td><td><code>SSL_CLIENT_I_DN_L</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_EXPORT</code></td><td><code>SSL_CIPHER_EXPORT</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_KEYSIZE</code></td><td><code>SSL_CIPHER_ALGKEYSIZE</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_SECKEYSIZE</code></td><td><code>SSL_CIPHER_USEKEYSIZE</code></td><td>renamed</td></tr> +<tr id=H><td><code>SSL_SSLEAY_VERSION</code></td><td><code>SSL_VERSION_LIBRARY</code></td><td>renamed</td></tr> +<tr id=D><td><code>SSL_STRONG_CRYPTO</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id=D><td><code>SSL_SERVER_KEY_EXP</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id=H><td><code>SSL_SERVER_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> -<tr id=D><td><code>SSL_SERVER_SIGNATURE_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> +<tr id=D><td><code>SSL_SERVER_KEY_SIZE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id=H><td><code>SSL_SERVER_SESSIONDIR</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id=D><td><code>SSL_SERVER_CERTIFICATELOGDIR</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id=H><td><code>SSL_SERVER_CERTFILE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> @@ -208,7 +220,6 @@ href="#table2">Table 2</a>. <tr id=D><td><code>SSL_CLIENT_KEY_EXP</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id=H><td><code>SSL_CLIENT_KEY_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> <tr id=D><td><code>SSL_CLIENT_KEY_SIZE</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> -<tr id=H><td><code>SSL_CLIENT_SIGNATURE_ALGORITHM</code></td><td><code>-</code></td><td>Not supported by mod_ssl</td></tr> </table> </float> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover.wml index c1166016469..360dbaab1d2 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover.wml @@ -6,19 +6,31 @@ <table cellspacing=0 cellpadding=0 border=0> <tr> <td> + <table cellspacing=0 cellpadding=0 border=0> + <tr> + <td> <img - src="ssl_cover_title.gif" + src="ssl_cover_title.jpg" alt="User Manual" > + </td> + </tr> + <tr> + <td align=right> + <font face="Arial,Helvetica">mod_ssl version 2.4</font> + </td> + </tr> + </table> + <br> </td> </tr> <tr> <td> <a - href="http://www.engelschall.com" + href="http://www.modssl.org/" ><img src="ssl_cover_logo.jpg" - alt="mod_ssl - The Apache Interface to SSLeay" + alt="mod_ssl - The Apache Interface to OpenSSL" border=0 ></a> </td> @@ -28,9 +40,9 @@ <table> <tr> <td> - Ralf S. Engelschall<br> - <font size=-1>rse@engelschall.com</font><br> - <font size=-1>www.engelschall.com</font><br> + <tt>Ralf S. Engelschall</tt><br> + <tt>rse@engelschall.com</tt><br> + <tt>www.engelschall.com</tt><br> </td> <td> @@ -43,6 +55,9 @@ alt="next page" ><br>Overview </td> + <td> + <space width=30> + </td> </tr> </table> </td> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover_logo.jpg b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover_logo.jpg Binary files differindex af92da6127e..3fcfeb4b237 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover_logo.jpg +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover_logo.jpg diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover_title.gif b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover_title.gif Binary files differdeleted file mode 100644 index 3b1291fa4e4..00000000000 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_cover_title.gif +++ /dev/null diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.html index 355cf43dda4..7d08eb79059 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -254,8 +254,8 @@ corresponding answers following the popular USENET tradition. Most of these questions occured on the Newsgroup <a href="news:comp.infosystems.www.servers.unix"> <code>comp.infosystems.www.servers.unix</code></a> or the mod_ssl Support -Mailing List <a href="mailto:sw-mod-ssl@engelschall.com"> -<code>sw-mod-ssl@engelschall.com</code></a>. They are collected at this place +Mailing List <a href="mailto:modssl-users@modssl.org"> +<code>modssl-users@modssl.org</code></a>. They are collected at this place to avoid answering the same questions over and over. <p> Please read this chapter at least once when installing mod_ssl or at least @@ -279,40 +279,51 @@ author. <td> <font face="Arial,Helvetica" size="-1"> <a href="#ToC1"><strong>About the module</strong></a><br> - <a href="#ToC2"><strong>Apache-SSL vs. mod_ssl: difference?</strong></a><br> - <a href="#ToC3"><strong>Should Apache-SSL be avoided?</strong></a><br> - <a href="#ToC4"><strong>Which Apache-SSL version is the base?</strong></a><br> - <a href="#ToC5"><strong>Why starting with version 2.0.0?</strong></a><br> - <a href="#ToC6"><strong>mod_ssl/Apache versions?</strong></a><br> - <a href="#ToC7"><strong>mod_ssl and Year 2000?</strong></a><br> - <a href="#ToC8"><strong>mod_ssl and Wassenaar Arrangement?</strong></a><br> - <a href="#ToC9"><strong>About Configuration</strong></a><br> - <a href="#ToC10"><strong>HTTP and HTTPS on same machine?</strong></a><br> - <a href="#ToC11"><strong>Where is the HTTPS port?</strong></a><br> - <a href="#ToC12"><strong>How to test HTTPS manually?</strong></a><br> - <a href="#ToC13"><strong>Why does my browser hang?</strong></a><br> - <a href="#ToC14"><strong>How to switch with relative hyperlinks?</strong></a><br> - <a href="#ToC15"><strong>About Certificates</strong></a><br> - <a href="#ToC16"><strong>What are Keys, CSRs and Certs?</strong></a><br> - <a href="#ToC17"><strong>Difference on startup?</strong></a><br> - <a href="#ToC18"><strong>How to create a dummy cert?</strong></a><br> - <a href="#ToC19"><strong>How to create a real cert?</strong></a><br> - <a href="#ToC20"><strong>How to create my own CA?</strong></a><br> - <a href="#ToC21"><strong>How to change a pass phrase?</strong></a><br> - <a href="#ToC22"><strong>How to remove a pass phrase?</strong></a><br> - <a href="#ToC23"><strong>How to verify a key/cert pair?</strong></a><br> - <a href="#ToC24"><strong>Why does a 2048-bit key not work?</strong></a><br> - <a href="#ToC25"><strong>Why is client auth broken?</strong></a><br> - <a href="#ToC26"><strong>About SSL Protocol</strong></a><br> - <a href="#ToC27"><strong>Why has the server a higher load?</strong></a><br> - <a href="#ToC28"><strong>Which ciphers are supported?</strong></a><br> - <a href="#ToC29"><strong>HTTPS and name-based vhosts</strong></a><br> - <a href="#ToC30"><strong>The lock icon in Netscape locks very late</strong></a><br> - <a href="#ToC31"><strong>About Support</strong></a><br> - <a href="#ToC32"><strong>Resources in case of problems?</strong></a><br> - <a href="#ToC33"><strong>Support in case of problems?</strong></a><br> - <a href="#ToC34"><strong>How to write a problem report?</strong></a><br> - <a href="#ToC35"><strong>How to get a backtrace?</strong></a><br> + <a href="#ToC2"><strong>What is the history of mod_ssl?</strong></a><br> + <a href="#ToC3"><strong>Apache-SSL vs. mod_ssl: differences?</strong></a><br> + <a href="#ToC4"><strong>mod_ssl/Apache versions?</strong></a><br> + <a href="#ToC5"><strong>mod_ssl and Year 2000?</strong></a><br> + <a href="#ToC6"><strong>mod_ssl and Wassenaar Arrangement?</strong></a><br> + <a href="#ToC7"><strong>About Installation</strong></a><br> + <a href="#ToC8"><strong>Core dumps for HTTPS requests?</strong></a><br> + <a href="#ToC9"><strong>Core dumps for Apache+mod_ssl+PHP3?</strong></a><br> + <a href="#ToC10"><strong>Undefined symbols on startup?</strong></a><br> + <a href="#ToC11"><strong>Permission problem on SSLMutex</strong></a><br> + <a href="#ToC12"><strong>shared memory and process size?</strong></a><br> + <a href="#ToC13"><strong>About Configuration</strong></a><br> + <a href="#ToC14"><strong>HTTP and HTTPS with a single server?</strong></a><br> + <a href="#ToC15"><strong>Where is the HTTPS port?</strong></a><br> + <a href="#ToC16"><strong>How to test HTTPS manually?</strong></a><br> + <a href="#ToC17"><strong>Why does my connection hang?</strong></a><br> + <a href="#ToC18"><strong>How to switch with relative hyperlinks?</strong></a><br> + <a href="#ToC19"><strong>About Certificates</strong></a><br> + <a href="#ToC20"><strong>What are Keys, CSRs and Certs?</strong></a><br> + <a href="#ToC21"><strong>Difference on startup?</strong></a><br> + <a href="#ToC22"><strong>How to create a dummy cert?</strong></a><br> + <a href="#ToC23"><strong>How to create a real cert?</strong></a><br> + <a href="#ToC24"><strong>How to create my own CA?</strong></a><br> + <a href="#ToC25"><strong>How to change a pass phrase?</strong></a><br> + <a href="#ToC26"><strong>How to remove a pass phrase?</strong></a><br> + <a href="#ToC27"><strong>How to verify a key/cert pair?</strong></a><br> + <a href="#ToC28"><strong>Bad Certificate Error?</strong></a><br> + <a href="#ToC29"><strong>Why does a 2048-bit key not work?</strong></a><br> + <a href="#ToC30"><strong>Why is client auth broken?</strong></a><br> + <a href="#ToC31"><strong>How to convert from PEM to DER?</strong></a><br> + <a href="#ToC32"><strong>Verisign and the magic getca program?</strong></a><br> + <a href="#ToC33"><strong>Global IDs or SGC?</strong></a><br> + <a href="#ToC34"><strong>About SSL Protocol</strong></a><br> + <a href="#ToC35"><strong>Why has the server a higher load?</strong></a><br> + <a href="#ToC36"><strong>Which ciphers are supported?</strong></a><br> + <a href="#ToC37"><strong>HTTPS and name-based vhosts</strong></a><br> + <a href="#ToC38"><strong>The lock icon in Netscape locks very late</strong></a><br> + <a href="#ToC39"><strong>Why do I get I/O errors with my MSIE clients?</strong></a><br> + <a href="#ToC40"><strong>Why do I get I/O errors with my NS clients?</strong></a><br> + <a href="#ToC41"><strong>About Support</strong></a><br> + <a href="#ToC42"><strong>Resources in case of problems?</strong></a><br> + <a href="#ToC43"><strong>Support in case of problems?</strong></a><br> + <a href="#ToC44"><strong>How to write a problem report?</strong></a><br> + <a href="#ToC45"><strong>I got a core dump, can you help me?</strong></a><br> + <a href="#ToC46"><strong>How to get a backtrace?</strong></a><br> </font> </td> </tr> @@ -325,218 +336,85 @@ author. <ul> <p> <li><a name="ToC2"></a> - <a name="apssl-diff"></a> - <strong id="faq">What are the differences between mod_ssl and Apache-SSL, from where it is derived?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#apssl-diff"><b>L</b></a>] - <p> - This cannot be answered in short, because there are too much changes (see - the <code>CHANGES</code> and <code>CHANGES.20</code> files in the mod_ssl - distribution for detailed information). Most of them are internal changes, - cleanups and re-organizations of the source code. But the user visible - changes are mainly the following: - <p> - <ul> - <li><em>mod_ssl provides a complete documentation</em> (this User Manual) - where all configuration directives, environment variables, and other - things are documented while Apache-SSL had no such documentation - although it existed for over three years when mod_ssl was split from - it (in April 1998). Additionally mod_ssl provides answers to often - occuring frequently asked questions (this list) in the - Apache/SSL/SSLeay area. For instance mod_ssl gives detailed hints - about how to setup a CA, how to create real a server Certificate, etc. - And the mod_ssl User Manual provides a compact introduction to the - complex SSL area itself. Because here are the typical hurdles located - every user stumbles over. - <p> - <li><em>mod_ssl comes with clean and documented source code</em> with the - intent that only this way the user is able to re-view it for - backdoors, security holes, etc. This is considered important for - security-related software. It was always incomprehensible to the - author of mod_ssl how Apache-SSL could exist for over three years - while both the source code and the source patches were provided in an - undocumented and partly unreadable format. For the mod_ssl package - the source codes follows the Apache coding style, is logically - ordered to follow the API phases and even the patches to the - Apache source tree are annotated with descriptions to give the - user a chance to re-view and understand them. - <p> - <li><em>mod_ssl uses a generic Extended API</em> to achieve - its functionality. This means instead of patching in - SSL/crypto-related code into the Apache kernel a clean and well - separated Extended API is patched in. This way the SSL and - cryptography code is <em>only</em> present inside the SSL module - itself (i.e. inside the <code>src/modules/ssl/</code> subtree only). - The benefit from this is a clean separation and API-conforming SSL - solution (which means for instance no direct SSL-references from the - kernel, no kludges and hacks to get called, etc). - <p> - <li><em>mod_ssl supports Dynamic Shared Object (DSO) building</em> - as a direct consequence from using the Extended API. In short DSO - support means maximum flexibility under run-time, i.e. you don't have - to decide under compile-time whether to build or not to build SSL into - the Apache httpd executable. Instead you can just load mod_ssl through - mod_so's <code>LoadModule</code> directive <em>on demand</em>. This - is especially interesting for two cases: Vendor package maintainers - receive the power they need for creating flexible packages and power - users receive the ability to run more than one Apache (non-SSL-aware - and SSL-aware) instance from a single Apache installation while still - saving RAM. - <p> - <li><em>mod_ssl is ported to the Win32 platform</em>, - as it's the case for Apache and SSLeay. This way mod_ssl follows the - evolution of these packages and provides the always requested support - also for this nasty platform. As for the Unix/DSO case under Win32 - mod_ssl is well-integrated into Apache through a stand-alone DLL which - can be loaded through mod_so's <code>LoadModule</code> directive. - <p> - <li><em>mod_ssl can be really easily applied to the Apache source tree</em> because - it provides a full-featured and automated configuration environment - for this task while Apache-SSL forced the user to fiddle with the - <code>patch</code> and <code>cp</code> tools theirself. Just - because security is not for amateurs hasn't to mean that user - friendliness is not important. So it's a must to assist the user - in applying the SSL-stuff to vanilla Apache sources. For this - mod_ssl integrates also very-well into the new Apache 1.3 - Autoconf-style Interface (APACI). Additionally mod_ssl's - configuration mechanism supports the usage of RSAref, arbitrary - locations for SSLeay, etc. - <p> - <li><em>mod_ssl fixes a lot of bugs and inconsistencies</em> which - existed in Apache-SSL. For Apache experts here are a few impressions: - Apache-SSL wrote directly to <code>stderr</code> instead of the Apache - error logfile; it messed up it's error messages with the SSLeay error - messages; it directly patched the <code>SERVER_BASEVERSION</code> - define instead of using the Apache 1.3 conforming - <code>ap_add_version_component</code> function; it used the unsafe - <code>sprintf</code> function instead of the robust - <code>ap_snprintf</code>; it incorrectly spawned and killed the - <code>gcache</code> auxiliary program and it totally failed to pass the - ``<code>gcc -Wall -Wshadow -Wpointer-arith -Wcast-align - -Wmissing-prototypes -Wmissing-declarations -Wnested-externs - -Winline</code>'' test (while Apache already passes it) because of - unclean code. - <p> - Additionally Apache-SSL didn't provide a way to easily apply it to - the Apache source tree (semi-manual editing and patching was - required); it didn't seamlessly integrate into the new Apache 1.3 - Autoconf-style Interface (APACI) at configuration time; it didn't - automatically recognize the difference between an installed SSLeay and - an out-of-the-source-only SSLeay; it didn't provide integration into - the APACI installation process (<code>make install</code>); it used - numbers 0 to 2 instead of reasonable names for the argument of - <code>SSLVerifyClient</code> just because internally an - <code>enum</code> was used and for the provided - <code>%{version}c</code> construct of CustomLog it used the results - "2", "3" under SSLeay 0.8 while under SSLeay 0.9 the results were - "SSL2", "SSL3", etc. pp. - <p> - <li><em>mod_ssl adds new functionalities which were missing in - Apache-SSL</em>. A few selected points which give you an impression - follow: - <ul> - <li>mod_ssl provides a real dedicated SSL log file controlled by log - level and the additional features that messages logged at the - `error' level are automatically duplicated to the general Apache - error log file. And occuring system and SSLeay error messages are - automatically appended to mod_ssl messages. Additionally mod_ssl - annotates deep-level SSLeay messages with more high-level hints. - <li>mod_ssl provides a completely new and enhanced handling - of encrypted private key files. First the private keys are kept in - a permanent memory pool (as SSLeay already does internally), so - Apache now survives server restarts without falling down. Second - the pass phrase dialog is a lot more user friendly and advanced: - It uses a pass phrase reuse-algorithm to minimize the dialog, it - recognizes wrong pass phrases and allows retries (but with a - backoff time delay), etc. And additionally a minimal interface is - provided to plug-in an external program for providing the pass - phrase for special batch security situations. - <li>mod_ssl provides the <code>SSLCACertificateReqFile</code> - directive which can be used to configure a different (from - <code>SSLCACertificateFile</code>) set of CA Certificates for the - SSLv3 feature used by the clients to load CA Certificates from the - server for speeding up server authentication. - <li>mod_ssl replaced the ``gcache'' stuff of Apache-SSL (used for - caching SSL sessions) with a more robust DBM-based solution, - because the controlling of an external program cannot be done very - reliable from within Apache. Additionally a "mutex" is now used to - synchronize the inter-process access to this cache. - <li>mod_ssl provides support for the SSLeay+RSAref couple, i.e. - mod_ssl supports the building with RSAref. - <li>mod_ssl provides a new SSLRequire directive which can be used - to implement more granular access control based on arbitrary - complex boolean expression. - <li>mod_ssl adds support for HTTPS to the Apache Proxy Module - (mod_proxy). - <li>mod_ssl is the first Open Source version of an SSL - extension to Apache which supports the Win32 platform. - <li>etc.pp. - </ul> - </ul> - <p> - When you're still really interested in more hard-core details walk through - the entries in the <code>CHANGES</code> and <code>CHANGES.20</code> files - in the mod_ssl distribution. + <a name="history"></a> + <strong id="faq">What is the history of mod_ssl?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#history"><b>L</b></a>] + <p> + The mod_ssl v1 package was initially created in April 1998 by <a + href="mailto:rse@engelschall.com">Ralf S. Engelschall</a> via porting <a + href="mailto:ben@algroup.co.uk">Ben Laurie</a>'s <a + href="http://www.apache-ssl.org/">Apache-SSL</a> 1.17 source patches for + Apache 1.2.6 to Apache 1.3b6. Because of conflicts with Ben + Laurie's development cycle it then was re-assembled from scratch for + Apache 1.3.0 by merging the old mod_ssl 1.x with the newer Apache-SSL + 1.18. From this point on mod_ssl lived its own life as mod_ssl v2. The + first publically released version was mod_ssl 2.0.0 from August 10th, + 1998. As of this writing (August 1999) the current mod_ssl version is 2.4.0. + <p> + After one year of very active development with over 1000 working hours and + over 40 releases mod_ssl reached it's current state. The result is an + already very clean source base implementing a very rich functionality. + The code size increased by a factor of 4 to currently a total of over + 10.000 lines of ANSI C consisting of approx. 70% code and 30% code + documentation. From the original Apache-SSL code currently approx. 5% is + remaining only. <p> <li><a name="ToC3"></a> - <a name="apssl-avoid"></a> - <strong id="faq">Ok, does this mean I should avoid using Apache-SSL from now on?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#apssl-avoid"><b>L</b></a>] - <p> - <strong>No</strong>, it just means that you <em>can</em> use mod_ssl. - Beside the well-known flaws Apache-SSL works great. Ben Laurie did and - still does a great job in maintaining it. The big difference is just that - Ben Laurie's goals are different from Ralf S. Engelschall's goals. So, as - long as you don't get bothered by inconsistencies and other flaws you - don't have to upgrade. Instead you should decide yourself if you already - feel comfortable or not. If yes, stay with Apache-SSL - if not, move to - mod_ssl or (even better) one of the commercial SSL solutions for Apache. - Or in other words: No solution is better than another in general. Which - one you should use depends mainly on your personal requirements. + <a name="apssl-diff"></a> + <strong id="faq">What are the functional differences between mod_ssl and Apache-SSL, from where +it is originally derived?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#apssl-diff"><b>L</b></a>] + <p> + This neither can be answered in short (there were too much code changes) + nor can be answered at all by the author (there would be immediately flame + wars with no reasonable results at the end). But as you easily can guess + from the 5% of remaining Apache-SSL code, lot's of differences exists, + although user-visible backward compatibility exists for most things. + <p> + When you really want a detailed comparison you've to read the entries in + the large <code>CHANGES</code> file you can find in the mod_ssl + distribution. Usually this is too much hard-core. So I recommend you to + either believe in the opinion and recommendations of other users (the + simplest approach) or do a comparison yourself (the most reasonable + approach). For this grab distributions of mod_ssl (from <a + href="http://www.modssl.org/">http://www.modssl.org</a>) and Apache-SSL + (from <a href="http://www.apache-ssl.org/">http://www.apache-ssl.org</a>), + install both packages, read their documentation and try them out yourself. + Then choose the one which pleases you most. + <p> + A few final hints to direct your comparison: quality of documentation + ("can you easily find answers and are they sufficient?"), quality of + source code ("is the source code reviewable so you can make sure there + aren't any trapdoors or inherent security risks because of bad programming + style?"), easy and clean installation ("can the SSL functionality easily + added to an Apache source tree without manual editing or patching?"), + clean integration into Apache ("is the SSL functionality encapsulated and + cleanly separated from the remaining Apache functionality?"), support for + Dynamic Shared Object (DSO) facility ("can the SSL functionality built as + a separate DSO for maximum flexibility?"), Win32 port ("is the SSL + functionality available also under the Win32 platform?"), amount and + quality of functionality ("is the provided SSL functionality and control + possibilities sufficient for your situation?"), quality of problem tracing + ("is it possible for you to easily trace down the problems via logfiles, + etc?"), etc. pp. <p> <li><a name="ToC4"></a> - <a name="apssl-baseversion"></a> - <strong id="faq">On which Apache-SSL version is mod_ssl actually based?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#apssl-baseversion"><b>L</b></a>] - <p> - The mod_ssl package was initially created by porting the Apache-SSL 1.17 - stuff from Apache 1.2.6 to Apache 1.3b6 in April 1998. Because of - conflicts with Ben Laurie's development cycle it then was re-assembled - from scratch for Apache 1.3.0 by merging the old mod_ssl with the newer - Apache-SSL 1.18. From this point mod_ssl lived its own life and changes - with Apache-SSL releases were merged after they were released. In other - words: mod_ssl is based on the latest Apache-SSL and always will contain - all useful changes which will occur with Apache-SSL in the future. -<p> -<li><a name="ToC5"></a> - <a name="why200"></a> - <strong id="faq">Why is mod_ssl's version starting with 2.0.0?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#why200"><b>L</b></a>] - <p> - Because initially the mod_ssl project was intended as a contribution to - the Apache-SSL project from Ben Laurie. The idea was that mod_ssl formed - Apache-SSL 2.0.0. But after Ralf S. Engelschall and Ben Laurie couldn't - find a reasonable compromise in merging mod_ssl with Apache-SSL, the stuff - was released as a new package named ``mod_ssl''. But to still indicate - that it's some ``second generation'' stuff, the first mod_ssl version was - named 2.0.0. -<p> -<li><a name="ToC6"></a> <a name="what-version"></a> <strong id="faq">How do I know which mod_ssl version is for which Apache version?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#what-version"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#what-version"><b>L</b></a>] <p> That's trivial: mod_ssl uses version strings of the syntax <em><mod_ssl-version></em>-<em><apache-version></em>, for - instance <code>2.2.0-1.3.4</code>. This directly indicates that it's - mod_ssl version 2.2.0 for Apache version 1.3.4. And this also means you + instance <code>2.4.0-1.3.9</code>. This directly indicates that it's + mod_ssl version 2.4.0 for Apache version 1.3.9. And this also means you <em>only</em> can apply this mod_ssl version to exactly this Apache version (unless you use the <code>--force</code> option to mod_ssl's <code>configure</code> command ;-). <p> -<li><a name="ToC7"></a> +<li><a name="ToC5"></a> <a name="y2k"></a> <strong id="faq">Is mod_ssl Year 2000 compliant?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#y2k"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#y2k"><b>L</b></a>] <p> Yes, mod_ssl is Year 2000 compliant. <p> @@ -552,27 +430,27 @@ author. Additionally according to a <a href="http://www.apache.org/docs/misc/FAQ.html#year2000">Year 2000 statement</a> from the Apache Group, the Apache webserver is Year 2000 - compliant, too. But whether SSLeay or the underlaying Operating System + compliant, too. But whether OpenSSL or the underlaying Operating System (either a Unix or Win32 platform) is Year 2000 compliant is a different question which cannot be answered here. <p> -<li><a name="ToC8"></a> +<li><a name="ToC6"></a> <a name="wassenaar"></a> <strong id="faq">What about mod_ssl and the Wassenaar Arrangement?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#wassenaar"><b>L</b></a>] - <p> - First, let us explain what <i>Wassenaar</i> and it's <i>Arrangement on - Export Controls for Conventional Arms and Dual-Use Goods and - Technologies</i> is: This is a international regime, established 1995, to - control trade in conventional arms and dual-use goods and technology. It - replaced the previous <i>CoCom</i> regime. 33 countries are signatories: - Argentina, Australia, Austria, Belgium, Bulgaria, Canada, Czech Republic, - Denmark, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Japan, - Luxembourg, Netherlands, New Zealand, Norway, Poland, Portugal, Republic - of Korea, Romania, Russian Federation, Slovak Republic, Spain, Sweden, - Switzerland, Turkey, Ukraine, United Kingdom and United States. For more - details look at <a - href="http://www.wassenaar.org/">http://www.wassenaar.org/</a>. + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#wassenaar"><b>L</b></a>] + <p> + First, let us explain what <i>Wassenaar</i> and it's <i>Arrangement on + Export Controls for Conventional Arms and Dual-Use Goods and + Technologies</i> is: This is a international regime, established 1995, to + control trade in conventional arms and dual-use goods and technology. It + replaced the previous <i>CoCom</i> regime. 33 countries are signatories: + Argentina, Australia, Austria, Belgium, Bulgaria, Canada, Czech Republic, + Denmark, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Japan, + Luxembourg, Netherlands, New Zealand, Norway, Poland, Portugal, Republic + of Korea, Romania, Russian Federation, Slovak Republic, Spain, Sweden, + Switzerland, Turkey, Ukraine, United Kingdom and United States. For more + details look at <a + href="http://www.wassenaar.org/">http://www.wassenaar.org/</a>. <p> In short: The aim of the Wassenaar Arrangement is to prevent the build up of military capabilities that threaten regional and international security @@ -581,17 +459,17 @@ author. civilian applications. However, the Wassenaar Arrangement also provides an exemption from export controls for mass-market software and free software. <p> - In the current Wassenaar ``<i>List of Dual Use Goods and Technologies And - Munitions</i>'', under ``<i>GENERAL SOFTWARE NOTE</i>'' (GSN) it says - ``<i>The Lists do not control "software" which is either: 1. [...] 2. "in - the public domain".</i>'' And under ``<i>DEFINITIONS OF TERMS USED IN - THESE LISTS</i>'' one can find the definition: ``<i>"In the public - domain": This means "technology" or "software" which has been made - available without restrictions upon its further dissemination. N.B. - Copyright restrictions do not remove "technology" or "software" from being - "in the public domain".</i>'' - <p> - So, both mod_ssl and SSLeay are ``in the public domain'' for the purposes + In the current Wassenaar ``<i>List of Dual Use Goods and Technologies And + Munitions</i>'', under ``<i>GENERAL SOFTWARE NOTE</i>'' (GSN) it says + ``<i>The Lists do not control "software" which is either: 1. [...] 2. "in + the public domain".</i>'' And under ``<i>DEFINITIONS OF TERMS USED IN + THESE LISTS</i>'' one can find the definition: ``<i>"In the public + domain": This means "technology" or "software" which has been made + available without restrictions upon its further dissemination. N.B. + Copyright restrictions do not remove "technology" or "software" from being + "in the public domain".</i>'' + <p> + So, both mod_ssl and OpenSSL are ``in the public domain'' for the purposes of the Wassenaar Agreement and its ``<i>List of Dual Use Goods and Technologies And Munitions List</i>''. <p> @@ -606,40 +484,110 @@ author. for their countries. Remember that mod_ssl is created in Germany and distributed from Switzerland. <p> - So, mod_ssl and SSLeay are not affected by the Wassenaar Agreement. + So, mod_ssl and OpenSSL are not affected by the Wassenaar Agreement. </ul> <p> <br> -<H2><a name="ToC9">About Configuration</a></H2> +<H2><a name="ToC7">About Installation</a></H2> <ul> <p> +<li><a name="ToC8"></a> + <a name="core-dbm"></a> + <strong id="faq">When I access my website the first time via HTTPS I get a core dump?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#core-dbm"><b>L</b></a>] + <p> + There can be a lot of reasons why a core dump can occur, of course. + Ranging from buggy third-party modules, over buggy vendor libraries up to + a buggy mod_ssl version. But the above situation is often caused by old or + broken vendor DBM libraries. To solve it either build mod_ssl with the + built-in SDBM library (specify <tt>--enable-rule=SSL_SDBM</tt> at the + APACI command line) or switch from ``<tt>SSLSessioCache dbm:</tt>'' to the + newer ``<tt>SSLSessioCache shm:</tt>'' variant (after you've rebuilt + Apache with MM, of course). +<p> +<li><a name="ToC9"></a> + <a name="core-php3"></a> + <strong id="faq">My Apache dumps core when I add both mod_ssl and PHP3?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#core-php3"><b>L</b></a>] + <p> + Make sure you add mod_ssl to the Apache source tree first and then do a + fresh configuration and installation of PHP3. For SSL support EAPI patches + are required which have to change internal Apache structures. PHP3 needs + to know about these in order to work correctly. Always make sure that + <tt>-DEAPI</tt> is contained in the compiler flags when PHP3 is build. +<p> <li><a name="ToC10"></a> - <a name="https-parallel"></a> - <strong id="faq">I want to run HTTP and HTTPS on the same machine. Is that possible?</strong></strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#https-parallel"><b>L</b></a>] - <p> - Yes, there are two ways to do this: run two server instances, or run both - services from the same server instance. Unless there is a good reason to - run two (like using a different product for HTTP and HTTPS), it's usually - most simples to run a single instance where you enable SSL only for those - virtual hosts that need it. If you wish to run two server instances you - must make sure that they each only try to bind to their allowed ports - (normally port 80 for HTTP and 443 for HTTPS). + <a name="dso-sym"></a> + <strong id="faq">When I startup Apache I get errors about undefined symbols like ap_global_ctx?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#dso-sym"><b>L</b></a>] + <p> + This actually means you installed mod_ssl as a DSO, but without rebuilding + Apache with EAPI. Because EAPI is a requirement for mod_ssl, you need an + extra patched Apache (containing the EAPI patches) and you have to build + this Apache with EAPI enabled (explicitly specify + <tt>--enable-rule=EAPI</tt> at the APACI command line). <p> <li><a name="ToC11"></a> + <a name="mutex-perm"></a> + <strong id="faq">When I startup Apache I get permission errors related to SSLMutex?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#mutex-perm"><b>L</b></a>] + <p> + When you receive entries like ``<code>mod_ssl: Child could not open + SSLMutex lockfile /opt/apache/logs/ssl_mutex.18332 (System error follows) + [...] System: Permission denied (errno: 13)</code>'' this is usually + caused by to restrictive permissions on the <i>parent</i> directories. + Make sure that all parent directories (here <code>/opt</code>, + <code>/opt/apache</code> and <code>/opt/apache/logs</code>) have the x-bit + set at least for the UID under which Apache's children are running (see + the <code>User</code> directive of Apache). +<p> +<li><a name="ToC12"></a> + <a name="mm"></a> + <strong id="faq">When I use the MM library and the shared memory cache each process grows +1.5MB according to `top' although I specified 512000 as the cache size?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#mm"><b>L</b></a>] + <p> + The additional 1MB are caused by the global shared memory pool EAPI + allocates for all modules and which is not used by mod_ssl for + various reasons. So the actually allocated shared memory is always + 1MB more than what you specify on <code>SSLSessionCache</code>. + But don't be confused by the display of `top': although is + indicates that <i>each</i> process grow, this is not reality, of + course. Instead the additional memory consumption is shared by + all processes, i.e. the 1.5MB are allocated only once per Apache + instance and not once per Apache server process. +</ul> +<p> +<br> +<H2><a name="ToC13">About Configuration</a></H2> +<ul> +<p> +<li><a name="ToC14"></a> + <a name="https-parallel"></a> + <strong id="faq">Is it possible to provide HTTP and HTTPS with a single server?</strong></strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#https-parallel"><b>L</b></a>] + <p> + Yes, HTTP and HTTPS use different server ports, so there is no direct + conflict between them. Either run two separate server instances (one binds + to port 80, the other to port 443) or even use Apache's elegant virtual + hosting facility where you can easily create two virtual servers which + Apache dispatches: one responding to port 80 and speaking HTTP and one + responding to port 443 speaking HTTPS. +<p> +<li><a name="ToC15"></a> <a name="https-port"></a> <strong id="faq">I know that HTTP is on port 80, but where is HTTPS?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#https-port"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#https-port"><b>L</b></a>] <p> You can run HTTPS on any port, but the standards specify port 443, which is where any HTTPS compliant browser will look by default. You can force your browser to look on a different port by specifying it in the URL like this (for port 666): <code>https://secure.server.dom:666/</code> <p> -<li><a name="ToC12"></a> +<li><a name="ToC16"></a> <a name="https-test"></a> <strong id="faq">How can I speak HTTPS manually for testing purposes?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#https-test"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#https-test"><b>L</b></a>] <p> While you usually just use <p> @@ -648,10 +596,10 @@ author. <p> for simple testing the HTTP protocol of Apache, it's not such easy for HTTPS because of the SSL protocol between TCP and HTTP. But with the - help of SSLeay's <code>s_client</code> program you can do a similar + help of OpenSSL's <code>s_client</code> command you can do a similar check even for HTTPS: <p> - <code><b>$ s_client -connect localhost:443 -state -debug</b></code><br> + <code><b>$ openssl s_client -connect localhost:443 -state -debug</b></code><br> <code><b>GET / HTTP/1.0</b></code> <p> Before the actual HTTP response you receive detailed information about the @@ -665,25 +613,23 @@ author. <code><b>$ curl http://localhost/</b></code><br> <code><b>$ curl https://localhost/</b></code><br> <p> -<li><a name="ToC13"></a> +<li><a name="ToC17"></a> <a name="hang"></a> - <strong id="faq">Why does my browser hang when I connect to my SSL-aware Apache server?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#hang"><b>L</b></a>] - <p> - Because you used an URL of the form ``<code>http://</code>'' instead of - ``<code>https:</code>''. Really! Also, if you see: ``<code>SSL_Accept - failed error:140760EB:SSL routines: SSL23_GET_CLIENT_HELLO:unknown - protocol</code>'' in your Apache error logfile, it's for the same reason. - This also happens the other way round, i.e. when you try to use - ``<code>https://</code>'' on a server that doesn't support SSL (on this - port). Make sure you are connecting to a virtual server that supports - SSL, which is probably the IP associated with your hostname, not localhost - (127.0.0.1). + <strong id="faq">Why does the connection hang when I connect to my SSL-aware Apache server?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#hang"><b>L</b></a>] + <p> + Because you connected with HTTP to the HTTPS port, i.e. you used an URL of + the form ``<code>http://</code>'' instead of ``<code>https://</code>''. + This also happens the other way round when you connect via HTTPS to a HTTP + port, i.e. when you try to use ``<code>https://</code>'' on a server that + doesn't support SSL (on this port). Make sure you are connecting to a + virtual server that supports SSL, which is probably the IP associated with + your hostname, not localhost (127.0.0.1). <p> -<li><a name="ToC14"></a> +<li><a name="ToC18"></a> <a name="relative-links"></a> <strong id="faq">How can I use relative hyperlinks to switch between HTTP and HTTPS?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#relative-links"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#relative-links"><b>L</b></a>] <p> Usually you have to use fully-qualified hyperlinks because you have to change the URL scheme. But with the help of some URL @@ -701,13 +647,13 @@ author. </ul> <p> <br> -<H2><a name="ToC15">About Certificates</a></H2> +<H2><a name="ToC19">About Certificates</a></H2> <ul> <p> -<li><a name="ToC16"></a> +<li><a name="ToC20"></a> <a name="what-is"></a> <strong id="faq">What are RSA Private Keys, CSRs and Certificates?</strong></strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#what-is"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#what-is"><b>L</b></a>] <p> The RSA private key file is a digital file that you can use to decrypt messages sent to you. It has a public component which you distribute (via @@ -722,10 +668,10 @@ author. See the <a href="ssl_intro.html">Introduction</a> chapter for a general description of the SSL protocol. <p> -<li><a name="ToC17"></a> +<li><a name="ToC21"></a> <a name="startup"></a> <strong id="faq">Seems like there is a difference on startup between the original Apache and an SSL-aware Apache?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#startup"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#startup"><b>L</b></a>] <p> Yes, in general, starting Apache with a built-in mod_ssl is just like starting an unencumbered Apache, except for the fact that when you have a @@ -738,10 +684,10 @@ author. below under ``How can I get rid of the pass-phrase dialog at Apache startup time?''. <p> -<li><a name="ToC18"></a> +<li><a name="ToC22"></a> <a name="cert-dummy"></a> <strong id="faq">How can I create a dummy SSL server Certificate for testing purposes?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#cert-dummy"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#cert-dummy"><b>L</b></a>] <p> A Certificate does not have to be signed by a public CA. You can use your private key to sign the Certificate which contains your public key. You @@ -760,44 +706,48 @@ author. BUT REMEMBER: YOU REALLY HAVE TO CREATE A REAL CERTIFICATE FOR THE LONG RUN! HOW THIS IS DONE IS DESCRIBED IN THE NEXT ANSWER. <p> -<li><a name="ToC19"></a> +<li><a name="ToC23"></a> <a name="cert-real"></a> <strong id="faq">Ok, I've got my server installed and want to create a real SSL server Certificate for it. How do I do it?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#cert-real"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#cert-real"><b>L</b></a>] <p> Here is a step-by-step description: <p> <ol> - <li>Make sure SSLeay is really installed and in your <code>PATH</code>. + <li>Make sure OpenSSL is really installed and in your <code>PATH</code>. But some commands even work ok when you just run the - ``<code>ssleay</code>'' program from within the SSLeay source tree as - ``<code>./apps/ssleay</code>''. + ``<code>openssl</code>'' program from within the OpenSSL source tree as + ``<code>./apps/openssl</code>''. <p> <li>Create a RSA private key for your Apache server (will be Triple-DES encrypted and PEM formatted): <p> - <code><strong>$ ssleay genrsa -des3 -out server.key 1024</strong></code> + <code><strong>$ openssl genrsa -des3 -out server.key 1024</strong></code> <p> Please backup this <code>server.key</code> file and remember the pass-phrase you had to enter at a secure location. You can see the details of this RSA private key via the command: <p> - <code><strong>$ ssleay rsa -noout -text -in server.key</strong></code> + <code><strong>$ openssl rsa -noout -text -in server.key</strong></code> <p> And you could create a decrypted PEM version (not recommended) of this RSA private key via: <p> - <code><strong>$ ssleay rsa -in server.key -out server.key.unsecure</strong></code> + <code><strong>$ openssl rsa -in server.key -out server.key.unsecure</strong></code> <p> - <li>Create a Certificate Signing Request (CSR) for the server RSA private + <li>Create a Certificate Signing Request (CSR) with the server RSA private key (output will be PEM formatted): <p> - <code><strong>$ ssleay req -new -days 365 -key server.key -out server.csr</strong></code> + <code><strong>$ openssl req -new -key server.key -out server.csr</strong></code> <p> + Make sure you enter the FQDN ("Fully Qualified Domain Name") of the + server when OpenSSL prompts you for the "CommonName", i.e. when you + generate a CSR for a website which will be later accessed via + <code>https://www.foo.dom/</code>, enter "www.foo.dom" here. You can see the details of this CSR via the command <p> - <code><strong>$ ssleay req -noout -text -in server.csr</strong></code> + <code><strong>$ openssl req -noout -text -in server.csr</strong></code> <p> <li>You now have to send this Certificate Signing Request (CSR) to a Certifying Authority (CA) for signing. The result is then a real @@ -840,7 +790,7 @@ server Certificate for it. How do I do it?</strong> your CA yourself. You can see the details of the received Certificate via the command: <p> - <code><strong>$ ssleay x509 -noout -text -in server.crt</strong></code> + <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code> <p> <li>Now you have two files: <code>server.key</code> and <code>server.crt</code>. These now can be used as following inside your @@ -852,75 +802,76 @@ server Certificate for it. How do I do it?</strong> The <code>server.csr</code> file is no longer needed. </ol> <p> -<li><a name="ToC20"></a> +<li><a name="ToC24"></a> <a name="cert-ownca"></a> <strong id="faq">How can I create and use my own Certificate Authority (CA)?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#cert-ownca"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#cert-ownca"><b>L</b></a>] <p> - The short answer is to use the <code>CA.sh</code> script provided by SSLeay. - The long and manual answer is this: + The short answer is to use the <code>CA.sh</code> or <code>CA.pl</code> + script provided by OpenSSL. The long and manual answer is this: <p> <ol> - <li> Create a RSA private key for your CA + <li>Create a RSA private key for your CA (will be Triple-DES encrypted and PEM formatted): <p> - <code><strong>$ ssleay genrsa -des3 -out ca.key 1024</strong></code> + <code><strong>$ openssl genrsa -des3 -out ca.key 1024</strong></code> <p> Please backup this <code>ca.key</code> file and remember the pass-phrase you currently entered at a secure location. You can see the details of this RSA private key via the command <p> - <code><strong>$ ssleay rsa -noout -text -in ca.key</strong></code> + <code><strong>$ openssl rsa -noout -text -in ca.key</strong></code> <p> And you can create a decrypted PEM version (not recommended) of this private key via: <p> - <code><strong>$ ssleay rsa -in ca.key -out ca.key.unsecure</strong></code> + <code><strong>$ openssl rsa -in ca.key -out ca.key.unsecure</strong></code> <p> <li>Create a self-signed CA Certificate (X509 structure) - for the RSA key of the CA (output will be PEM formatted): + with the RSA key of the CA (output will be PEM formatted): <p> - <code><strong>$ ssleay req -new -x509 -days 365 -key ca.key -out ca.crt</strong></code> + <code><strong>$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt</strong></code> <p> You can see the details of this Certificate via the command: <p> - <code><strong>$ ssleay x509 -noout -text -in ca.crt</strong></code> + <code><strong>$ openssl x509 -noout -text -in ca.crt</strong></code> <p> <li>Prepare a script for signing which is needed because - the ``<code>ssleay ca</code>'' command has some strange requirements - and the default SSLeay config doesn't allow one easily to use - ``<code>ssleay ca</code>'' directly. So a script named + the ``<code>openssl ca</code>'' command has some strange requirements + and the default OpenSSL config doesn't allow one easily to use + ``<code>openssl ca</code>'' directly. So a script named <code>sign.sh</code> is distributed with the mod_ssl distribution (subdir <code>pkg.contrib/</code>). Use this script for signing. <p> - <li>Now you can use this CA to sign CSR's in order to create real - SSL Certificates for use inside an Apache webserver: + <li>Now you can use this CA to sign server CSR's in order to create real + SSL Certificates for use inside an Apache webserver (assuming + you already have a <code>server.csr</code> at hand): <p> <code><strong>$ ./sign.sh server.csr</strong></code> <p> - This signs the CSR and results in a <code>server.crt</code> file. + This signs the server CSR and results in a <code>server.crt</code> file. </ol> <p> -<li><a name="ToC21"></a> +<li><a name="ToC25"></a> <a name="change-passphrase"></a> <strong id="faq">How can I change the pass-phrase on my private key file?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#change-passphrase"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#change-passphrase"><b>L</b></a>] <p> You simply have to read it with the old pass-phrase and write it again by specifying the new pass-phrase. You can accomplish this with the following commands: <p> - <code><strong>$ ssleay rsa -des3 -in server.key -out server.key.new</strong></code><br> + <code><strong>$ openssl rsa -des3 -in server.key -out server.key.new</strong></code><br> <code><strong>$ mv server.key.new server.key</strong></code><br> <p> Here you're asked two times for a PEM pass-phrase. At the first prompt enter the old pass-phrase and at the second prompt enter the new pass-phrase. <p> -<li><a name="ToC22"></a> +<li><a name="ToC26"></a> <a name="remove-passphrase"></a> <strong id="faq">How can I get rid of the pass-phrase dialog at Apache startup time?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#remove-passphrase"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#remove-passphrase"><b>L</b></a>] <p> The reason why this dialog pops up at startup and every re-start is that the RSA private key inside your server.key file is stored in @@ -933,7 +884,7 @@ server Certificate for it. How do I do it?</strong> preserving the original file): <p> <code><strong>$ cp server.key server.key.org</strong></code><br> - <code><strong>$ ssleay rsa -in server.key.org -out server.key</strong></code> + <code><strong>$ openssl rsa -in server.key.org -out server.key</strong></code> <p> <li>Make sure the server.key file is now only readable by root: <p> @@ -947,11 +898,15 @@ server Certificate for it. How do I do it?</strong> file are really such that only root or the web server user can read it (preferably get your web server to start as root but run as another server, and have the key readable only by root). + <p> + As an alternative approach you can use the ``<code>SSLPassPhraseDialog + exec:/path/to/program</code>'' facility. But keep in mind that this is + neither more nor less secure, of course. <p> -<li><a name="ToC23"></a> +<li><a name="ToC27"></a> <a name="verify-key"></a> <strong id="faq">How do I verify that a private key matches its Certificate?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#verify-key"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#verify-key"><b>L</b></a>] <p> The private key contains a series of numbers. Two of those numbers form the "public key", the others are part of your "private key". The "public @@ -961,27 +916,39 @@ server Certificate for it. How do I do it?</strong> compare the numbers. To view the Certificate and the key run the commands: <p> - <code><strong>$ ssleay x509 -noout -text -in server.crt</strong></code><br> - <code><strong>$ ssleay rsa -noout -text -in server.key</strong></code> + <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br> + <code><strong>$ openssl rsa -noout -text -in server.key</strong></code> <p> The `modulus' and the `public exponent' portions in the key and the Certificate must match. But since the public exponent is usually 65537 and it's bothering comparing long modulus you can use the following approach: <p> - <code><strong>$ ssleay x509 -noout -modulus -in server.crt | ssleay md5</strong></code><br> - <code><strong>$ ssleay rsa -noout -modulus -in server.key | ssleay md5</strong></code> + <code><strong>$ openssl x509 -noout -modulus -in server.crt | openssl md5</strong></code><br> + <code><strong>$ openssl rsa -noout -modulus -in server.key | openssl md5</strong></code> <p> And then compare these really shorter numbers. With overwhelming probability they will differ if the keys are different. BTW, if I want to check to which key or certificate a particular CSR belongs you can compute <p> - <code><strong>$ ssleay req -noout -modulus -in server.csr | ssleay md5</strong></code> + <code><strong>$ openssl req -noout -modulus -in server.csr | openssl md5</strong></code> <p> -<li><a name="ToC24"></a> - <a name="keysize"></a> +<li><a name="ToC28"></a> + <a name="keysize1"></a> + <strong id="faq">What does it mean when my connections fail with an "alert bad certificate" +error?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#keysize1"><b>L</b></a>] + <p> + Usually when you see errors like ``<tt>OpenSSL: error:14094412: SSL + routines:SSL3_READ_BYTES:sslv3 alert bad certificate</tt>'' in the SSL + logfile, this means that the browser was unable to handle the server + certificate/private-key which perhaps contain a RSA-key not equal to 1024 + bits. For instance Netscape Navigator 3.x is one of those browsers. +<p> +<li><a name="ToC29"></a> + <a name="keysize2"></a> <strong id="faq">Why does my 2048-bit private key not work?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#keysize"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#keysize2"><b>L</b></a>] <p> The private key sizes for SSL must be either 512 or 1024 for compatibility with certain web browsers. A keysize of 1024 bits is recommended because @@ -989,43 +956,85 @@ server Certificate for it. How do I do it?</strong> Navigator and Microsoft Internet Explorer, and with other browsers that use RSA's BSAFE cryptography toolkit. <p> -<li><a name="ToC25"></a> +<li><a name="ToC30"></a> <a name="hash-symlinks"></a> <strong id="faq">Why is client authentication broken after upgrading from SSLeay version 0.8 to 0.9?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#hash-symlinks"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#hash-symlinks"><b>L</b></a>] <p> The CA certificates under the path you configured with <code>SSLCACertificatePath</code> are found by SSLeay through hash - symlinks. These hash values are generated by the `<code>ssleay x509 -noout + symlinks. These hash values are generated by the `<code>openssl x509 -noout -hash</code>' command. But the algorithm used to calculate the hash for a certificate has changed between SSLeay 0.8 and 0.9. So you have to remove all old hash symlinks and re-create new ones after upgrading. Use the <code>Makefile</code> mod_ssl placed into this directory. +<p> +<li><a name="ToC31"></a> + <a name="pem-to-der"></a> + <strong id="faq">How can I convert a certificate from PEM to DER format?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#pem-to-der"><b>L</b></a>] + <p> + The default certificate format for SSLeay/OpenSSL is PEM, which actually + is Base64 encoded DER with header and footer lines. For some applications + (e.g. Microsoft Internet Explorer) you need the certificate in plain DER + format. You can convert a PEM file <code>cert.pem</code> into the + corresponding DER file <code>cert.der</code> with the following command: + <code><strong>$ openssl x509 -in cert.pem -out cert.der -outform DER</strong></code> +<p> +<li><a name="ToC32"></a> + <a name="verisign-getca"></a> + <strong id="faq">I try to install a Verisign certificate. Why can't I find neither the +<code>getca</code> nor <code>getverisign</code> programs Verisign mentions?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#verisign-getca"><b>L</b></a>] + <p> + This is because Verisign has never provided specific instructions + for Apache+mod_ssl. Rather they tell you what you should do + if you were using C2Net's Stronghold (a commercial Apache + based server with SSL support). The only thing you have to do + is to save the certificate into a file and give the name of + that file to the <code>SSLCertificateFile</code> directive. + Remember that you need to give the key file in as well (see + <code>SSLCertificateKeyFile</code> directive). For a better + CA-related overview on SSL certifiate fiddling you can look at <a + href="http://www.thawte.com/certs/server/keygen/mod_ssl.html"> + Thawte's mod_ssl instructions</a>. +<p> +<li><a name="ToC33"></a> + <a name="gid"></a> + <strong id="faq">Can I use the Server Gated Cryptography (SGC) facility (aka Verisign Global +ID) also with mod_ssl?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#gid"><b>L</b></a>] + <p> + Yes, mod_ssl since version 2.1 supports the SGC facility. You don't have + to configure anything special for this, just use a Global ID as your + server certificate. The <i>step up</i> of the clients are then + automatically handled by mod_ssl under run-time. For details please read + the <tt>README.GlobalID</tt> document in the mod_ssl distribution. </ul> <p> <br> -<H2><a name="ToC26">About SSL Protocol</a></H2> +<H2><a name="ToC34">About SSL Protocol</a></H2> <ul> <p> -<li><a name="ToC27"></a> +<li><a name="ToC35"></a> <a name="load"></a> <strong id="faq">Why has my webserver a higher load now that I run SSL there?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#load"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#load"><b>L</b></a>] <p> Because SSL uses strong cryptographic encryption and this needs a lot of number crunching. And because when you request a webpage via HTTPS even the images are transfered encrypted. So, when you have a lot of HTTPS traffic the load increases. <p> -<li><a name="ToC28"></a> +<li><a name="ToC36"></a> <a name="ciphers"></a> <strong id="faq">What SSL Ciphers are supported by mod_ssl?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#ciphers"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#ciphers"><b>L</b></a>] <p> Usually just all SSL ciphers which are supported by the - version of SSLeay in use (can depend on the way you built - SSLeay). Typically this at least includes the following: + version of OpenSSL in use (can depend on the way you built + OpenSSL). Typically this at least includes the following: <p> <ul> <li>RC4 with MD5 @@ -1040,12 +1049,12 @@ SSLeay version 0.8 to 0.9?</strong> To determine the actual list of supported ciphers you can run the following command: <p> - <code><strong>$ ssleay ciphers -v</strong></code><br> + <code><strong>$ openssl ciphers -v</strong></code><br> <p> -<li><a name="ToC29"></a> +<li><a name="ToC37"></a> <a name="vhosts"></a> <strong id="faq">Why can't I use SSL with name-based/non-IP-based virtual hosts?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#vhosts"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#vhosts"><b>L</b></a>] <p> The reason is very technical. Actually it's some sort of a chicken and egg problem: The SSL protocol layer stays below the HTTP protocol layer @@ -1059,12 +1068,12 @@ SSLeay version 0.8 to 0.9?</strong> handshake is finished. But the information is already needed at the SSL handshake phase. Bingo! <p> -<li><a name="ToC30"></a> +<li><a name="ToC38"></a> <a name="lock-icon"></a> <strong id="faq">When I use Basic Authentication over HTTPS the lock icon in Netscape browsers still show the unlocked state when the dialog pops up. Does this mean the username/password is still transmitted unencrypted?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#lock-icon"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#lock-icon"><b>L</b></a>] <p> No, the username/password is already transmitted encrypted. The icon in Netscape browsers is just not really synchronized with the SSL/TLS layer @@ -1075,45 +1084,76 @@ username/password is still transmitted unencrypted?</strong> communication takes place in HTTPS the SSL/TLS layer has already done the handshake phase and switched to encrypted communication. So, don't get confused by this icon. +<p> +<li><a name="ToC39"></a> + <a name="io-ie"></a> + <strong id="faq">When I connect via HTTPS to an Apache+mod_ssl server with Microsoft Internet +Explorer (MSIE) I sometimes get I/O errors and the message "bad data from the +server". What's the reason?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#io-ie"><b>L</b></a>] + <p> + The reason is that MSIE's SSL implementation has some subtle bugs related + to the HTTP keep-alive facility and the SSL close notify alerts on socket + connection close. You've to work-around this by forcing Apache+mod_ssl to + not use keep-alive connections and not sending the SSL close notify + messages to MSIE clients. This can be done by using the following + directive in your SSL-aware virtual host section: + <pre> + SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown + </pre> +<p> +<li><a name="ToC40"></a> + <a name="io-ns"></a> + <strong id="faq">When I connect via HTTPS to an Apache+mod_ssl server with Netscape Navigator I +get I/O errors and the message "Netscape has encountered bad data from the +server" What's the reason?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#io-ns"><b>L</b></a>] + <p> + The problem usually is that you had created a new server certificate with + the same DN, but you had told your browser to accept forever the old + server certificate. Once you clear the entry in your browser for the old + certificate, everything usually will work fine. Netscape's SSL + implementation is correct, so when you encounter I/O errors with Netscape + Navigator it is most of the time caused by the configured certificates. </ul> <p> <br> -<H2><a name="ToC31">About Support</a></H2> +<H2><a name="ToC41">About Support</a></H2> <ul> <p> -<li><a name="ToC32"></a> +<li><a name="ToC42"></a> <a name="resources"></a> <strong id="faq">What information resources are available in case of mod_ssl problems?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#resources"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#resources"><b>L</b></a>] <p> The following information resources are available. In case of problems you should search here first. <p> <ol> <li><em>Answers in the User Manual's F.A.Q. List (this)</em><br> - <a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html"> - http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html</a><br> + <a href="http://www.modssl.org/docs/2.4/ssl_faq.html"> + http://www.modssl.org/docs/2.4/ssl_faq.html</a><br> First look inside the F.A.Q. (this text), perhaps your problem is such popular that it was already answered a lot of times in the past. <p> -<li><em>Postings from the sw-mod-ssl Support Mailing List</em> - <a href="http://www.engelschall.com/sw/mod_ssl/news/list.html"> - http://www.engelschall.com/sw/mod_ssl/news/list.html</a><br> +<li><em>Postings from the modssl-users Support Mailing List</em> + <a href="http://www.modssl.org/news/list.html"> + http://www.modssl.org/news/list.html</a><br> Second search for your problem in one of the existing archives of the - sw-mod-ssl mailing list. Perhaps your problem popped up at least once for + modssl-users mailing list. Perhaps your problem popped up at least once for another user, too. <p> <li><em>Problem Reports in the Bug Database</em> - <a href="http://www.engelschall.com/sw/mod_ssl/bugdb/"> - http://www.engelschall.com/sw/mod_ssl/bugdb/</a><br> + <a href="http://www.modssl.org/support/bugdb/"> + http://www.modssl.org/support/bugdb/</a><br> Third look inside the mod_ssl Bug Database. Perhaps someone else already has reported the problem. </ol> <p> -<li><a name="ToC33"></a> +<li><a name="ToC43"></a> <a name="contact"></a> <strong id="faq">What support contacts are available in case of mod_ssl problems?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#contact"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#contact"><b>L</b></a>] <p> The following lists all support possibilities for mod_ssl, in order of preference, i.e. start in this order and do not pick the support possibility @@ -1121,16 +1161,16 @@ you just like most, please. <p> <ol> <li><em>Write a Problem Report into the Bug Database</em><br> - <a href="http://www.engelschall.com/sw/mod_ssl/bugdb/"> - http://www.engelschall.com/sw/mod_ssl/bugdb/</a><br> + <a href="http://www.modssl.org/support/bugdb/"> + http://www.modssl.org/support/bugdb/</a><br> This is the preferred way of submitting your problem report, because this way it gets filed into the bug database (it cannot be lost) <em>and</em> - send to the sw-mod-ssl mailing list (others see the current problems and + send to the modssl-users mailing list (others see the current problems and learn from answers). <p> -<li><em>Write a Problem Report to the sw-mod-ssl Support Mailing List</em><br> - <a href="mailto:sw-mod-ssl@engelschall.com"> - sw-mod-ssl @ engelschall.com</a><br> +<li><em>Write a Problem Report to the modssl-users Support Mailing List</em><br> + <a href="mailto:modssl-users@modssl.org"> + modssl-users @ modssl.org</a><br> This is the second way of submitting your problem report. You have to subscribe to the list first, but then you can easily discuss your problem with both the author and the whole mod_ssl user community. @@ -1141,35 +1181,35 @@ you just like most, please. This is the last way of submitting your problem report. Please avoid this in your own interest because the author is really a very busy men. Your mail will always be filed to one of his various mail-folders and is - usually not processed as fast as a posting on sw-mod-ssl. + usually not processed as fast as a posting on modssl-users. </ol> <p> -<li><a name="ToC34"></a> +<li><a name="ToC44"></a> <a name="report-details"></a> <strong id="faq">What information and details I've to provide to the author when writing a bug report?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#report-details"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#report-details"><b>L</b></a>] <p> You have to at least always provide the following information: <p> <ul> -<li><em>Apache, mod_ssl and SSLeay version information</em><br> +<li><em>Apache, mod_ssl and OpenSSL version information</em><br> The mod_ssl version you should really know. It's for instance the version number in the distribution tarball. The Apache version can be determined - by running ``<code>httpd -v</code>''. The SSLeay version can be - determined by running ``<code>ssleay version</code>''. Alternatively when + by running ``<code>httpd -v</code>''. The OpenSSL version can be + determined by running ``<code>openssl version</code>''. Alternatively when you have Lynx installed you can run the command ``<code>lynx -mime_header http://localhost/ | grep Server</code>'' to determine all information in a single step. <p> -<li><em>The details on how you built and installed Apache+mod_ssl+SSLeay</em><br> +<li><em>The details on how you built and installed Apache+mod_ssl+OpenSSL</em><br> For this you can provide a logfile of your terminal session which shows the configuration and install steps. Alternatively you can at least provide the author with the APACI `<code>configure</code>'' command line you used (assuming you used APACI, of course). <p> <li><em>In case of core dumps please include a Backtrace</em><br> - In case your Apache+mod_ssl+SSLeay should really dumped core please attach + In case your Apache+mod_ssl+OpenSSL should really dumped core please attach a stack-frame ``backtrace'' (see the next question on how to get it). Without this information the reason for your core dump cannot be found. So you have to provide the backtrace, please. @@ -1182,10 +1222,21 @@ You have to at least always provide the following information: course. </ul> <p> -<li><a name="ToC35"></a> +<li><a name="ToC45"></a> + <a name="core-dumped"></a> + <strong id="faq">I got a core dump, can you help me?</strong> + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#core-dumped"><b>L</b></a>] + <p> + In general no, at least not unless you provide more details about the code + location where Apache dumped core. What is usually always required in + order to help you is a backtrace (see next question). Without this + information it is mostly impossible to find the problem and help you in + fixing it. +<p> +<li><a name="ToC46"></a> <a name="report-backtrace"></a> <strong id="faq">Ok, I got a core dump but how do I get a backtrace to find out the reason for it?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#report-backtrace"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#report-backtrace"><b>L</b></a>] <p> Follow the following steps: <p> @@ -1200,9 +1251,11 @@ Follow the following steps: make sure that the core-dump file can be written. You then should get a <code>/tmp/core</code> or <code>/tmp/httpd.core</code> file. When you don't get this, try to run your server under an UID != 0 (root), because - some kernels don't write (for security reasons) core-dumps for - root-processes. Additionally you can run ``<code>/path/to/httpd -X</code>'' - manually to force Apache not not fork. + most "current" kernels Most "current" kernels do not allow a process to + dump core after it has done a <code>setuid()</code> (unless it does an + <code>exec()</code>) for security reasons (there can be privileged + information left over in memory). Additionally you can run + ``<code>/path/to/httpd -X</code>'' manually to force Apache not not fork. <p> <li>Analyze the core-dump. For this run ``<code>gdb /path/to/httpd /tmp/httpd.core</code>'' or a similar command has to run. In GDB you then @@ -1273,8 +1326,8 @@ if (document.images) { <td> <table width="598"> <tr> <td align="left"><font face="Arial,Helvetica"> - <a href="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</a> 2.2, User Manual<br> - The Apache Interface to SSLeay + <a href="http://www.modssl.org/">mod_ssl</a> 2.4, User Manual<br> + The Apache Interface to OpenSSL </font> </td> <td align="right"><font face="Arial,Helvetica"> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.wml index 73c66bfb4ff..c99863e4017 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_faq.wml @@ -21,8 +21,8 @@ corresponding answers following the popular USENET tradition. Most of these questions occured on the Newsgroup <a href="news:comp.infosystems.www.servers.unix"> <code>comp.infosystems.www.servers.unix</code></a> or the mod_ssl Support -Mailing List <a href="mailto:sw-mod-ssl@engelschall.com"> -<code>sw-mod-ssl@engelschall.com</code></a>. They are collected at this place +Mailing List <a href="mailto:modssl-users@modssl.org"> +<code>modssl-users@modssl.org</code></a>. They are collected at this place to avoid answering the same questions over and over. <p> @@ -69,7 +69,7 @@ author. <a name="<get-var ref>"></a> <strong id="faq">%body</strong>\ - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html#<get-var ref>"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.4/ssl_faq.html#<get-var ref>"><b>L</b></a>] <p> <restore toc> <restore ref> @@ -80,197 +80,66 @@ author. <ul> -<faq ref="apssl-diff" toc="Apache-SSL vs. mod_ssl: difference?"> -What are the differences between mod_ssl and Apache-SSL, from where it is derived? +<faq ref="history" toc="What is the history of mod_ssl?"> +What is the history of mod_ssl? </faq> - This cannot be answered in short, because there are too much changes (see - the <code>CHANGES</code> and <code>CHANGES.20</code> files in the mod_ssl - distribution for detailed information). Most of them are internal changes, - cleanups and re-organizations of the source code. But the user visible - changes are mainly the following: + The mod_ssl v1 package was initially created in April 1998 by <a + href="mailto:rse@engelschall.com">Ralf S. Engelschall</a> via porting <a + href="mailto:ben@algroup.co.uk">Ben Laurie</a>'s <a + href="http://www.apache-ssl.org/">Apache-SSL</a> 1.17 source patches for + Apache 1.2.6 to Apache 1.3b6. Because of conflicts with Ben + Laurie's development cycle it then was re-assembled from scratch for + Apache 1.3.0 by merging the old mod_ssl 1.x with the newer Apache-SSL + 1.18. From this point on mod_ssl lived its own life as mod_ssl v2. The + first publically released version was mod_ssl 2.0.0 from August 10th, + 1998. As of this writing (August 1999) the current mod_ssl version is 2.4.0. <p> - <ul> - <li><em>mod_ssl provides a complete documentation</em> (this User Manual) - where all configuration directives, environment variables, and other - things are documented while Apache-SSL had no such documentation - although it existed for over three years when mod_ssl was split from - it (in April 1998). Additionally mod_ssl provides answers to often - occuring frequently asked questions (this list) in the - Apache/SSL/SSLeay area. For instance mod_ssl gives detailed hints - about how to setup a CA, how to create real a server Certificate, etc. - And the mod_ssl User Manual provides a compact introduction to the - complex SSL area itself. Because here are the typical hurdles located - every user stumbles over. - <p> - <li><em>mod_ssl comes with clean and documented source code</em> with the - intent that only this way the user is able to re-view it for - backdoors, security holes, etc. This is considered important for - security-related software. It was always incomprehensible to the - author of mod_ssl how Apache-SSL could exist for over three years - while both the source code and the source patches were provided in an - undocumented and partly unreadable format. For the mod_ssl package - the source codes follows the Apache coding style, is logically - ordered to follow the API phases and even the patches to the - Apache source tree are annotated with descriptions to give the - user a chance to re-view and understand them. - <p> - <li><em>mod_ssl uses a generic Extended API</em> to achieve - its functionality. This means instead of patching in - SSL/crypto-related code into the Apache kernel a clean and well - separated Extended API is patched in. This way the SSL and - cryptography code is <em>only</em> present inside the SSL module - itself (i.e. inside the <code>src/modules/ssl/</code> subtree only). - The benefit from this is a clean separation and API-conforming SSL - solution (which means for instance no direct SSL-references from the - kernel, no kludges and hacks to get called, etc). - <p> - <li><em>mod_ssl supports Dynamic Shared Object (DSO) building</em> - as a direct consequence from using the Extended API. In short DSO - support means maximum flexibility under run-time, i.e. you don't have - to decide under compile-time whether to build or not to build SSL into - the Apache httpd executable. Instead you can just load mod_ssl through - mod_so's <code>LoadModule</code> directive <em>on demand</em>. This - is especially interesting for two cases: Vendor package maintainers - receive the power they need for creating flexible packages and power - users receive the ability to run more than one Apache (non-SSL-aware - and SSL-aware) instance from a single Apache installation while still - saving RAM. - <p> - <li><em>mod_ssl is ported to the Win32 platform</em>, - as it's the case for Apache and SSLeay. This way mod_ssl follows the - evolution of these packages and provides the always requested support - also for this nasty platform. As for the Unix/DSO case under Win32 - mod_ssl is well-integrated into Apache through a stand-alone DLL which - can be loaded through mod_so's <code>LoadModule</code> directive. - <p> - <li><em>mod_ssl can be really easily applied to the Apache source tree</em> because - it provides a full-featured and automated configuration environment - for this task while Apache-SSL forced the user to fiddle with the - <code>patch</code> and <code>cp</code> tools theirself. Just - because security is not for amateurs hasn't to mean that user - friendliness is not important. So it's a must to assist the user - in applying the SSL-stuff to vanilla Apache sources. For this - mod_ssl integrates also very-well into the new Apache 1.3 - Autoconf-style Interface (APACI). Additionally mod_ssl's - configuration mechanism supports the usage of RSAref, arbitrary - locations for SSLeay, etc. - <p> - <li><em>mod_ssl fixes a lot of bugs and inconsistencies</em> which - existed in Apache-SSL. For Apache experts here are a few impressions: - Apache-SSL wrote directly to <code>stderr</code> instead of the Apache - error logfile; it messed up it's error messages with the SSLeay error - messages; it directly patched the <code>SERVER_BASEVERSION</code> - define instead of using the Apache 1.3 conforming - <code>ap_add_version_component</code> function; it used the unsafe - <code>sprintf</code> function instead of the robust - <code>ap_snprintf</code>; it incorrectly spawned and killed the - <code>gcache</code> auxiliary program and it totally failed to pass the - ``<code>gcc -Wall -Wshadow -Wpointer-arith -Wcast-align - -Wmissing-prototypes -Wmissing-declarations -Wnested-externs - -Winline</code>'' test (while Apache already passes it) because of - unclean code. - <p> - Additionally Apache-SSL didn't provide a way to easily apply it to - the Apache source tree (semi-manual editing and patching was - required); it didn't seamlessly integrate into the new Apache 1.3 - Autoconf-style Interface (APACI) at configuration time; it didn't - automatically recognize the difference between an installed SSLeay and - an out-of-the-source-only SSLeay; it didn't provide integration into - the APACI installation process (<code>make install</code>); it used - numbers 0 to 2 instead of reasonable names for the argument of - <code>SSLVerifyClient</code> just because internally an - <code>enum</code> was used and for the provided - <code>%{version}c</code> construct of CustomLog it used the results - "2", "3" under SSLeay 0.8 while under SSLeay 0.9 the results were - "SSL2", "SSL3", etc. pp. - <p> - <li><em>mod_ssl adds new functionalities which were missing in - Apache-SSL</em>. A few selected points which give you an impression - follow: - <ul> - <li>mod_ssl provides a real dedicated SSL log file controlled by log - level and the additional features that messages logged at the - `error' level are automatically duplicated to the general Apache - error log file. And occuring system and SSLeay error messages are - automatically appended to mod_ssl messages. Additionally mod_ssl - annotates deep-level SSLeay messages with more high-level hints. - <li>mod_ssl provides a completely new and enhanced handling - of encrypted private key files. First the private keys are kept in - a permanent memory pool (as SSLeay already does internally), so - Apache now survives server restarts without falling down. Second - the pass phrase dialog is a lot more user friendly and advanced: - It uses a pass phrase reuse-algorithm to minimize the dialog, it - recognizes wrong pass phrases and allows retries (but with a - backoff time delay), etc. And additionally a minimal interface is - provided to plug-in an external program for providing the pass - phrase for special batch security situations. - <li>mod_ssl provides the <code>SSLCACertificateReqFile</code> - directive which can be used to configure a different (from - <code>SSLCACertificateFile</code>) set of CA Certificates for the - SSLv3 feature used by the clients to load CA Certificates from the - server for speeding up server authentication. - <li>mod_ssl replaced the ``gcache'' stuff of Apache-SSL (used for - caching SSL sessions) with a more robust DBM-based solution, - because the controlling of an external program cannot be done very - reliable from within Apache. Additionally a "mutex" is now used to - synchronize the inter-process access to this cache. - <li>mod_ssl provides support for the SSLeay+RSAref couple, i.e. - mod_ssl supports the building with RSAref. - <li>mod_ssl provides a new SSLRequire directive which can be used - to implement more granular access control based on arbitrary - complex boolean expression. - <li>mod_ssl adds support for HTTPS to the Apache Proxy Module - (mod_proxy). - <li>mod_ssl is the first Open Source version of an SSL - extension to Apache which supports the Win32 platform. - <li>etc.pp. - </ul> - </ul> - <p> - When you're still really interested in more hard-core details walk through - the entries in the <code>CHANGES</code> and <code>CHANGES.20</code> files - in the mod_ssl distribution. - -<faq ref="apssl-avoid" toc="Should Apache-SSL be avoided?"> -Ok, does this mean I should avoid using Apache-SSL from now on? + After one year of very active development with over 1000 working hours and + over 40 releases mod_ssl reached it's current state. The result is an + already very clean source base implementing a very rich functionality. + The code size increased by a factor of 4 to currently a total of over + 10.000 lines of ANSI C consisting of approx. 70% code and 30% code + documentation. From the original Apache-SSL code currently approx. 5% is + remaining only. + +<faq ref="apssl-diff" toc="Apache-SSL vs. mod_ssl: differences?"> +What are the functional differences between mod_ssl and Apache-SSL, from where +it is originally derived? </faq> - <strong>No</strong>, it just means that you <em>can</em> use mod_ssl. - Beside the well-known flaws Apache-SSL works great. Ben Laurie did and - still does a great job in maintaining it. The big difference is just that - Ben Laurie's goals are different from Ralf S. Engelschall's goals. So, as - long as you don't get bothered by inconsistencies and other flaws you - don't have to upgrade. Instead you should decide yourself if you already - feel comfortable or not. If yes, stay with Apache-SSL - if not, move to - mod_ssl or (even better) one of the commercial SSL solutions for Apache. - Or in other words: No solution is better than another in general. Which - one you should use depends mainly on your personal requirements. - -<faq ref="apssl-baseversion" toc="Which Apache-SSL version is the base?"> -On which Apache-SSL version is mod_ssl actually based? -</faq> - - The mod_ssl package was initially created by porting the Apache-SSL 1.17 - stuff from Apache 1.2.6 to Apache 1.3b6 in April 1998. Because of - conflicts with Ben Laurie's development cycle it then was re-assembled - from scratch for Apache 1.3.0 by merging the old mod_ssl with the newer - Apache-SSL 1.18. From this point mod_ssl lived its own life and changes - with Apache-SSL releases were merged after they were released. In other - words: mod_ssl is based on the latest Apache-SSL and always will contain - all useful changes which will occur with Apache-SSL in the future. - -<faq ref="why200" toc="Why starting with version 2.0.0?"> -Why is mod_ssl's version starting with 2.0.0? -</faq> - - Because initially the mod_ssl project was intended as a contribution to - the Apache-SSL project from Ben Laurie. The idea was that mod_ssl formed - Apache-SSL 2.0.0. But after Ralf S. Engelschall and Ben Laurie couldn't - find a reasonable compromise in merging mod_ssl with Apache-SSL, the stuff - was released as a new package named ``mod_ssl''. But to still indicate - that it's some ``second generation'' stuff, the first mod_ssl version was - named 2.0.0. + This neither can be answered in short (there were too much code changes) + nor can be answered at all by the author (there would be immediately flame + wars with no reasonable results at the end). But as you easily can guess + from the 5% of remaining Apache-SSL code, lot's of differences exists, + although user-visible backward compatibility exists for most things. + <p> + When you really want a detailed comparison you've to read the entries in + the large <code>CHANGES</code> file you can find in the mod_ssl + distribution. Usually this is too much hard-core. So I recommend you to + either believe in the opinion and recommendations of other users (the + simplest approach) or do a comparison yourself (the most reasonable + approach). For this grab distributions of mod_ssl (from <a + href="http://www.modssl.org/">http://www.modssl.org</a>) and Apache-SSL + (from <a href="http://www.apache-ssl.org/">http://www.apache-ssl.org</a>), + install both packages, read their documentation and try them out yourself. + Then choose the one which pleases you most. + <p> + A few final hints to direct your comparison: quality of documentation + ("can you easily find answers and are they sufficient?"), quality of + source code ("is the source code reviewable so you can make sure there + aren't any trapdoors or inherent security risks because of bad programming + style?"), easy and clean installation ("can the SSL functionality easily + added to an Apache source tree without manual editing or patching?"), + clean integration into Apache ("is the SSL functionality encapsulated and + cleanly separated from the remaining Apache functionality?"), support for + Dynamic Shared Object (DSO) facility ("can the SSL functionality built as + a separate DSO for maximum flexibility?"), Win32 port ("is the SSL + functionality available also under the Win32 platform?"), amount and + quality of functionality ("is the provided SSL functionality and control + possibilities sufficient for your situation?"), quality of problem tracing + ("is it possible for you to easily trace down the problems via logfiles, + etc?"), etc. pp. <faq ref="what-version" toc="mod_ssl/Apache versions?"> How do I know which mod_ssl version is for which Apache version? @@ -278,8 +147,8 @@ How do I know which mod_ssl version is for which Apache version? That's trivial: mod_ssl uses version strings of the syntax <em><mod_ssl-version></em>-<em><apache-version></em>, for - instance <code>2.2.0-1.3.4</code>. This directly indicates that it's - mod_ssl version 2.2.0 for Apache version 1.3.4. And this also means you + instance <code>2.4.0-1.3.9</code>. This directly indicates that it's + mod_ssl version 2.4.0 for Apache version 1.3.9. And this also means you <em>only</em> can apply this mod_ssl version to exactly this Apache version (unless you use the <code>--force</code> option to mod_ssl's <code>configure</code> command ;-). @@ -304,7 +173,7 @@ Is mod_ssl Year 2000 compliant? Additionally according to a <a href="http://www.apache.org/docs/misc/FAQ.html#year2000">Year 2000 statement</a> from the Apache Group, the Apache webserver is Year 2000 - compliant, too. But whether SSLeay or the underlaying Operating System + compliant, too. But whether OpenSSL or the underlaying Operating System (either a Unix or Win32 platform) is Year 2000 compliant is a different question which cannot be answered here. @@ -312,18 +181,18 @@ Is mod_ssl Year 2000 compliant? What about mod_ssl and the Wassenaar Arrangement? </faq> - First, let us explain what <i>Wassenaar</i> and it's <i>Arrangement on - Export Controls for Conventional Arms and Dual-Use Goods and - Technologies</i> is: This is a international regime, established 1995, to - control trade in conventional arms and dual-use goods and technology. It - replaced the previous <i>CoCom</i> regime. 33 countries are signatories: - Argentina, Australia, Austria, Belgium, Bulgaria, Canada, Czech Republic, - Denmark, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Japan, - Luxembourg, Netherlands, New Zealand, Norway, Poland, Portugal, Republic - of Korea, Romania, Russian Federation, Slovak Republic, Spain, Sweden, - Switzerland, Turkey, Ukraine, United Kingdom and United States. For more - details look at <a - href="http://www.wassenaar.org/">http://www.wassenaar.org/</a>. + First, let us explain what <i>Wassenaar</i> and it's <i>Arrangement on + Export Controls for Conventional Arms and Dual-Use Goods and + Technologies</i> is: This is a international regime, established 1995, to + control trade in conventional arms and dual-use goods and technology. It + replaced the previous <i>CoCom</i> regime. 33 countries are signatories: + Argentina, Australia, Austria, Belgium, Bulgaria, Canada, Czech Republic, + Denmark, Finland, France, Germany, Greece, Hungary, Ireland, Italy, Japan, + Luxembourg, Netherlands, New Zealand, Norway, Poland, Portugal, Republic + of Korea, Romania, Russian Federation, Slovak Republic, Spain, Sweden, + Switzerland, Turkey, Ukraine, United Kingdom and United States. For more + details look at <a + href="http://www.wassenaar.org/">http://www.wassenaar.org/</a>. <p> In short: The aim of the Wassenaar Arrangement is to prevent the build up @@ -334,18 +203,18 @@ What about mod_ssl and the Wassenaar Arrangement? exemption from export controls for mass-market software and free software. <p> - In the current Wassenaar ``<i>List of Dual Use Goods and Technologies And - Munitions</i>'', under ``<i>GENERAL SOFTWARE NOTE</i>'' (GSN) it says - ``<i>The Lists do not control "software" which is either: 1. [...] 2. "in - the public domain".</i>'' And under ``<i>DEFINITIONS OF TERMS USED IN - THESE LISTS</i>'' one can find the definition: ``<i>"In the public - domain": This means "technology" or "software" which has been made - available without restrictions upon its further dissemination. N.B. - Copyright restrictions do not remove "technology" or "software" from being - "in the public domain".</i>'' + In the current Wassenaar ``<i>List of Dual Use Goods and Technologies And + Munitions</i>'', under ``<i>GENERAL SOFTWARE NOTE</i>'' (GSN) it says + ``<i>The Lists do not control "software" which is either: 1. [...] 2. "in + the public domain".</i>'' And under ``<i>DEFINITIONS OF TERMS USED IN + THESE LISTS</i>'' one can find the definition: ``<i>"In the public + domain": This means "technology" or "software" which has been made + available without restrictions upon its further dissemination. N.B. + Copyright restrictions do not remove "technology" or "software" from being + "in the public domain".</i>'' <p> - So, both mod_ssl and SSLeay are ``in the public domain'' for the purposes + So, both mod_ssl and OpenSSL are ``in the public domain'' for the purposes of the Wassenaar Agreement and its ``<i>List of Dual Use Goods and Technologies And Munitions List</i>''. @@ -362,7 +231,76 @@ What about mod_ssl and the Wassenaar Arrangement? distributed from Switzerland. <p> - So, mod_ssl and SSLeay are not affected by the Wassenaar Agreement. + So, mod_ssl and OpenSSL are not affected by the Wassenaar Agreement. + +</ul> + +<p> +<br> +<h2>About Installation</h2> + +<ul> + +<faq ref="core-dbm" toc="Core dumps for HTTPS requests?"> +When I access my website the first time via HTTPS I get a core dump? +</faq> + + There can be a lot of reasons why a core dump can occur, of course. + Ranging from buggy third-party modules, over buggy vendor libraries up to + a buggy mod_ssl version. But the above situation is often caused by old or + broken vendor DBM libraries. To solve it either build mod_ssl with the + built-in SDBM library (specify <tt>--enable-rule=SSL_SDBM</tt> at the + APACI command line) or switch from ``<tt>SSLSessioCache dbm:</tt>'' to the + newer ``<tt>SSLSessioCache shm:</tt>'' variant (after you've rebuilt + Apache with MM, of course). + +<faq ref="core-php3" toc="Core dumps for Apache+mod_ssl+PHP3?"> +My Apache dumps core when I add both mod_ssl and PHP3? +</faq> + + Make sure you add mod_ssl to the Apache source tree first and then do a + fresh configuration and installation of PHP3. For SSL support EAPI patches + are required which have to change internal Apache structures. PHP3 needs + to know about these in order to work correctly. Always make sure that + <tt>-DEAPI</tt> is contained in the compiler flags when PHP3 is build. + +<faq ref="dso-sym" toc="Undefined symbols on startup?"> +When I startup Apache I get errors about undefined symbols like ap_global_ctx? +</faq> + + This actually means you installed mod_ssl as a DSO, but without rebuilding + Apache with EAPI. Because EAPI is a requirement for mod_ssl, you need an + extra patched Apache (containing the EAPI patches) and you have to build + this Apache with EAPI enabled (explicitly specify + <tt>--enable-rule=EAPI</tt> at the APACI command line). + +<faq ref="mutex-perm" toc="Permission problem on SSLMutex"> +When I startup Apache I get permission errors related to SSLMutex? +</faq> + + When you receive entries like ``<code>mod_ssl: Child could not open + SSLMutex lockfile /opt/apache/logs/ssl_mutex.18332 (System error follows) + [...] System: Permission denied (errno: 13)</code>'' this is usually + caused by to restrictive permissions on the <i>parent</i> directories. + Make sure that all parent directories (here <code>/opt</code>, + <code>/opt/apache</code> and <code>/opt/apache/logs</code>) have the x-bit + set at least for the UID under which Apache's children are running (see + the <code>User</code> directive of Apache). + +<faq ref="mm" toc="shared memory and process size?"> +When I use the MM library and the shared memory cache each process grows +1.5MB according to `top' although I specified 512000 as the cache size? +</faq> + + The additional 1MB are caused by the global shared memory pool EAPI + allocates for all modules and which is not used by mod_ssl for + various reasons. So the actually allocated shared memory is always + 1MB more than what you specify on <code>SSLSessionCache</code>. + But don't be confused by the display of `top': although is + indicates that <i>each</i> process grow, this is not reality, of + course. Instead the additional memory consumption is shared by + all processes, i.e. the 1.5MB are allocated only once per Apache + instance and not once per Apache server process. </ul> @@ -372,17 +310,16 @@ What about mod_ssl and the Wassenaar Arrangement? <ul> -<faq ref="https-parallel" toc="HTTP and HTTPS on same machine?"> -I want to run HTTP and HTTPS on the same machine. Is that possible?</strong> +<faq ref="https-parallel" toc="HTTP and HTTPS with a single server?"> +Is it possible to provide HTTP and HTTPS with a single server?</strong> </faq> - Yes, there are two ways to do this: run two server instances, or run both - services from the same server instance. Unless there is a good reason to - run two (like using a different product for HTTP and HTTPS), it's usually - most simples to run a single instance where you enable SSL only for those - virtual hosts that need it. If you wish to run two server instances you - must make sure that they each only try to bind to their allowed ports - (normally port 80 for HTTP and 443 for HTTPS). + Yes, HTTP and HTTPS use different server ports, so there is no direct + conflict between them. Either run two separate server instances (one binds + to port 80, the other to port 443) or even use Apache's elegant virtual + hosting facility where you can easily create two virtual servers which + Apache dispatches: one responding to port 80 and speaking HTTP and one + responding to port 443 speaking HTTPS. <faq ref="https-port" toc="Where is the HTTPS port?"> I know that HTTP is on port 80, but where is HTTPS? @@ -404,10 +341,10 @@ How can I speak HTTPS manually for testing purposes? <p> for simple testing the HTTP protocol of Apache, it's not such easy for HTTPS because of the SSL protocol between TCP and HTTP. But with the - help of SSLeay's <code>s_client</code> program you can do a similar + help of OpenSSL's <code>s_client</code> command you can do a similar check even for HTTPS: <p> - <code><b>$ s_client -connect localhost:443 -state -debug</b></code><br> + <code><b>$ openssl s_client -connect localhost:443 -state -debug</b></code><br> <code><b>GET / HTTP/1.0</b></code> <p> Before the actual HTTP response you receive detailed information about the @@ -421,19 +358,17 @@ How can I speak HTTPS manually for testing purposes? <code><b>$ curl http://localhost/</b></code><br> <code><b>$ curl https://localhost/</b></code><br> -<faq ref="hang" toc="Why does my browser hang?"> -Why does my browser hang when I connect to my SSL-aware Apache server? +<faq ref="hang" toc="Why does my connection hang?"> +Why does the connection hang when I connect to my SSL-aware Apache server? </faq> - Because you used an URL of the form ``<code>http://</code>'' instead of - ``<code>https:</code>''. Really! Also, if you see: ``<code>SSL_Accept - failed error:140760EB:SSL routines: SSL23_GET_CLIENT_HELLO:unknown - protocol</code>'' in your Apache error logfile, it's for the same reason. - This also happens the other way round, i.e. when you try to use - ``<code>https://</code>'' on a server that doesn't support SSL (on this - port). Make sure you are connecting to a virtual server that supports - SSL, which is probably the IP associated with your hostname, not localhost - (127.0.0.1). + Because you connected with HTTP to the HTTPS port, i.e. you used an URL of + the form ``<code>http://</code>'' instead of ``<code>https://</code>''. + This also happens the other way round when you connect via HTTPS to a HTTP + port, i.e. when you try to use ``<code>https://</code>'' on a server that + doesn't support SSL (on this port). Make sure you are connecting to a + virtual server that supports SSL, which is probably the IP associated with + your hostname, not localhost (127.0.0.1). <faq ref="relative-links" toc="How to switch with relative hyperlinks?"> How can I use relative hyperlinks to switch between HTTP and HTTPS? @@ -525,16 +460,16 @@ server Certificate for it. How do I do it? Here is a step-by-step description: <p> <ol> - <li>Make sure SSLeay is really installed and in your <code>PATH</code>. + <li>Make sure OpenSSL is really installed and in your <code>PATH</code>. But some commands even work ok when you just run the - ``<code>ssleay</code>'' program from within the SSLeay source tree as - ``<code>./apps/ssleay</code>''. + ``<code>openssl</code>'' program from within the OpenSSL source tree as + ``<code>./apps/openssl</code>''. <p> <li>Create a RSA private key for your Apache server (will be Triple-DES encrypted and PEM formatted): <p> - <code><strong>$ ssleay genrsa -des3 -out server.key 1024</strong></code> + <code><strong>$ openssl genrsa -des3 -out server.key 1024</strong></code> <p> Please backup this <code>server.key</code> file and remember the @@ -542,27 +477,31 @@ server Certificate for it. How do I do it? You can see the details of this RSA private key via the command: <p> - <code><strong>$ ssleay rsa -noout -text -in server.key</strong></code> + <code><strong>$ openssl rsa -noout -text -in server.key</strong></code> <p> And you could create a decrypted PEM version (not recommended) of this RSA private key via: <p> - <code><strong>$ ssleay rsa -in server.key -out server.key.unsecure</strong></code> + <code><strong>$ openssl rsa -in server.key -out server.key.unsecure</strong></code> <p> - <li>Create a Certificate Signing Request (CSR) for the server RSA private + <li>Create a Certificate Signing Request (CSR) with the server RSA private key (output will be PEM formatted): <p> - <code><strong>$ ssleay req -new -days 365 -key server.key -out server.csr</strong></code> + <code><strong>$ openssl req -new -key server.key -out server.csr</strong></code> <p> + Make sure you enter the FQDN ("Fully Qualified Domain Name") of the + server when OpenSSL prompts you for the "CommonName", i.e. when you + generate a CSR for a website which will be later accessed via + <code>https://www.foo.dom/</code>, enter "www.foo.dom" here. You can see the details of this CSR via the command <p> - <code><strong>$ ssleay req -noout -text -in server.csr</strong></code> + <code><strong>$ openssl req -noout -text -in server.csr</strong></code> <p> <li>You now have to send this Certificate Signing Request (CSR) to @@ -611,7 +550,7 @@ server Certificate for it. How do I do it? You can see the details of the received Certificate via the command: <p> - <code><strong>$ ssleay x509 -noout -text -in server.crt</strong></code> + <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code> <p> <li>Now you have two files: <code>server.key</code> and @@ -630,16 +569,16 @@ server Certificate for it. How do I do it? How can I create and use my own Certificate Authority (CA)? </faq> - The short answer is to use the <code>CA.sh</code> script provided by SSLeay. - The long and manual answer is this: + The short answer is to use the <code>CA.sh</code> or <code>CA.pl</code> + script provided by OpenSSL. The long and manual answer is this: <p> <ol> - <li> Create a RSA private key for your CA + <li>Create a RSA private key for your CA (will be Triple-DES encrypted and PEM formatted): <p> - <code><strong>$ ssleay genrsa -des3 -out ca.key 1024</strong></code> + <code><strong>$ openssl genrsa -des3 -out ca.key 1024</strong></code> <p> Please backup this <code>ca.key</code> file and remember the @@ -647,45 +586,46 @@ How can I create and use my own Certificate Authority (CA)? You can see the details of this RSA private key via the command <p> - <code><strong>$ ssleay rsa -noout -text -in ca.key</strong></code> + <code><strong>$ openssl rsa -noout -text -in ca.key</strong></code> <p> And you can create a decrypted PEM version (not recommended) of this private key via: <p> - <code><strong>$ ssleay rsa -in ca.key -out ca.key.unsecure</strong></code> + <code><strong>$ openssl rsa -in ca.key -out ca.key.unsecure</strong></code> <p> <li>Create a self-signed CA Certificate (X509 structure) - for the RSA key of the CA (output will be PEM formatted): + with the RSA key of the CA (output will be PEM formatted): <p> - <code><strong>$ ssleay req -new -x509 -days 365 -key ca.key -out ca.crt</strong></code> + <code><strong>$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt</strong></code> <p> You can see the details of this Certificate via the command: <p> - <code><strong>$ ssleay x509 -noout -text -in ca.crt</strong></code> + <code><strong>$ openssl x509 -noout -text -in ca.crt</strong></code> <p> <li>Prepare a script for signing which is needed because - the ``<code>ssleay ca</code>'' command has some strange requirements - and the default SSLeay config doesn't allow one easily to use - ``<code>ssleay ca</code>'' directly. So a script named + the ``<code>openssl ca</code>'' command has some strange requirements + and the default OpenSSL config doesn't allow one easily to use + ``<code>openssl ca</code>'' directly. So a script named <code>sign.sh</code> is distributed with the mod_ssl distribution (subdir <code>pkg.contrib/</code>). Use this script for signing. <p> - <li>Now you can use this CA to sign CSR's in order to create real - SSL Certificates for use inside an Apache webserver: + <li>Now you can use this CA to sign server CSR's in order to create real + SSL Certificates for use inside an Apache webserver (assuming + you already have a <code>server.csr</code> at hand): <p> <code><strong>$ ./sign.sh server.csr</strong></code> <p> - This signs the CSR and results in a <code>server.crt</code> file. + This signs the server CSR and results in a <code>server.crt</code> file. </ol> <faq ref="change-passphrase" toc="How to change a pass phrase?"> @@ -697,7 +637,7 @@ How can I change the pass-phrase on my private key file? commands: <p> - <code><strong>$ ssleay rsa -des3 -in server.key -out server.key.new</strong></code><br> + <code><strong>$ openssl rsa -des3 -in server.key -out server.key.new</strong></code><br> <code><strong>$ mv server.key.new server.key</strong></code><br> <p> @@ -722,7 +662,7 @@ How can I get rid of the pass-phrase dialog at Apache startup time? <p> <code><strong>$ cp server.key server.key.org</strong></code><br> - <code><strong>$ ssleay rsa -in server.key.org -out server.key</strong></code> + <code><strong>$ openssl rsa -in server.key.org -out server.key</strong></code> <p> <li>Make sure the server.key file is now only readable by root: @@ -740,6 +680,11 @@ How can I get rid of the pass-phrase dialog at Apache startup time? (preferably get your web server to start as root but run as another server, and have the key readable only by root). + <p> + As an alternative approach you can use the ``<code>SSLPassPhraseDialog + exec:/path/to/program</code>'' facility. But keep in mind that this is + neither more nor less secure, of course. + <faq ref="verify-key" toc="How to verify a key/cert pair?"> How do I verify that a private key matches its Certificate? </faq> @@ -753,8 +698,8 @@ How do I verify that a private key matches its Certificate? commands: <p> - <code><strong>$ ssleay x509 -noout -text -in server.crt</strong></code><br> - <code><strong>$ ssleay rsa -noout -text -in server.key</strong></code> + <code><strong>$ openssl x509 -noout -text -in server.crt</strong></code><br> + <code><strong>$ openssl rsa -noout -text -in server.key</strong></code> <p> The `modulus' and the `public exponent' portions in the key and the @@ -763,8 +708,8 @@ How do I verify that a private key matches its Certificate? approach: <p> - <code><strong>$ ssleay x509 -noout -modulus -in server.crt | ssleay md5</strong></code><br> - <code><strong>$ ssleay rsa -noout -modulus -in server.key | ssleay md5</strong></code> + <code><strong>$ openssl x509 -noout -modulus -in server.crt | openssl md5</strong></code><br> + <code><strong>$ openssl rsa -noout -modulus -in server.key | openssl md5</strong></code> <p> And then compare these really shorter numbers. With overwhelming @@ -772,9 +717,20 @@ How do I verify that a private key matches its Certificate? check to which key or certificate a particular CSR belongs you can compute <p> - <code><strong>$ ssleay req -noout -modulus -in server.csr | ssleay md5</strong></code> + <code><strong>$ openssl req -noout -modulus -in server.csr | openssl md5</strong></code> + +<faq ref="keysize1" toc="Bad Certificate Error?"> +What does it mean when my connections fail with an "alert bad certificate" +error? +</faq> + + Usually when you see errors like ``<tt>OpenSSL: error:14094412: SSL + routines:SSL3_READ_BYTES:sslv3 alert bad certificate</tt>'' in the SSL + logfile, this means that the browser was unable to handle the server + certificate/private-key which perhaps contain a RSA-key not equal to 1024 + bits. For instance Netscape Navigator 3.x is one of those browsers. -<faq ref="keysize" toc="Why does a 2048-bit key not work?"> +<faq ref="keysize2" toc="Why does a 2048-bit key not work?"> Why does my 2048-bit private key not work? </faq> @@ -791,12 +747,52 @@ SSLeay version 0.8 to 0.9? The CA certificates under the path you configured with <code>SSLCACertificatePath</code> are found by SSLeay through hash - symlinks. These hash values are generated by the `<code>ssleay x509 -noout + symlinks. These hash values are generated by the `<code>openssl x509 -noout -hash</code>' command. But the algorithm used to calculate the hash for a certificate has changed between SSLeay 0.8 and 0.9. So you have to remove all old hash symlinks and re-create new ones after upgrading. Use the <code>Makefile</code> mod_ssl placed into this directory. +<faq ref="pem-to-der" toc="How to convert from PEM to DER?"> +How can I convert a certificate from PEM to DER format? +</faq> + + The default certificate format for SSLeay/OpenSSL is PEM, which actually + is Base64 encoded DER with header and footer lines. For some applications + (e.g. Microsoft Internet Explorer) you need the certificate in plain DER + format. You can convert a PEM file <code>cert.pem</code> into the + corresponding DER file <code>cert.der</code> with the following command: + + <code><strong>$ openssl x509 -in cert.pem -out cert.der -outform DER</strong></code> + +<faq ref="verisign-getca" toc="Verisign and the magic getca program?"> +I try to install a Verisign certificate. Why can't I find neither the +<code>getca</code> nor <code>getverisign</code> programs Verisign mentions? +</faq> + + This is because Verisign has never provided specific instructions + for Apache+mod_ssl. Rather they tell you what you should do + if you were using C2Net's Stronghold (a commercial Apache + based server with SSL support). The only thing you have to do + is to save the certificate into a file and give the name of + that file to the <code>SSLCertificateFile</code> directive. + Remember that you need to give the key file in as well (see + <code>SSLCertificateKeyFile</code> directive). For a better + CA-related overview on SSL certifiate fiddling you can look at <a + href="http://www.thawte.com/certs/server/keygen/mod_ssl.html"> + Thawte's mod_ssl instructions</a>. + +<faq ref="gid" toc="Global IDs or SGC?"> +Can I use the Server Gated Cryptography (SGC) facility (aka Verisign Global +ID) also with mod_ssl? +</faq> + + Yes, mod_ssl since version 2.1 supports the SGC facility. You don't have + to configure anything special for this, just use a Global ID as your + server certificate. The <i>step up</i> of the clients are then + automatically handled by mod_ssl under run-time. For details please read + the <tt>README.GlobalID</tt> document in the mod_ssl distribution. + </ul> <p> @@ -819,8 +815,8 @@ What SSL Ciphers are supported by mod_ssl? </faq> Usually just all SSL ciphers which are supported by the - version of SSLeay in use (can depend on the way you built - SSLeay). Typically this at least includes the following: + version of OpenSSL in use (can depend on the way you built + OpenSSL). Typically this at least includes the following: <p> <ul> <li>RC4 with MD5 @@ -835,7 +831,7 @@ What SSL Ciphers are supported by mod_ssl? To determine the actual list of supported ciphers you can run the following command: <p> - <code><strong>$ ssleay ciphers -v</strong></code><br> + <code><strong>$ openssl ciphers -v</strong></code><br> <faq ref="vhosts" toc="HTTPS and name-based vhosts"> Why can't I use SSL with name-based/non-IP-based virtual hosts? @@ -869,6 +865,36 @@ username/password is still transmitted unencrypted? handshake phase and switched to encrypted communication. So, don't get confused by this icon. +<faq ref="io-ie" toc="Why do I get I/O errors with my MSIE clients?"> +When I connect via HTTPS to an Apache+mod_ssl server with Microsoft Internet +Explorer (MSIE) I sometimes get I/O errors and the message "bad data from the +server". What's the reason? +</faq> + + The reason is that MSIE's SSL implementation has some subtle bugs related + to the HTTP keep-alive facility and the SSL close notify alerts on socket + connection close. You've to work-around this by forcing Apache+mod_ssl to + not use keep-alive connections and not sending the SSL close notify + messages to MSIE clients. This can be done by using the following + directive in your SSL-aware virtual host section: + + <pre> + SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown + </pre> + +<faq ref="io-ns" toc="Why do I get I/O errors with my NS clients?"> +When I connect via HTTPS to an Apache+mod_ssl server with Netscape Navigator I +get I/O errors and the message "Netscape has encountered bad data from the +server" What's the reason? +</faq> + + The problem usually is that you had created a new server certificate with + the same DN, but you had told your browser to accept forever the old + server certificate. Once you clear the entry in your browser for the old + certificate, everything usually will work fine. Netscape's SSL + implementation is correct, so when you encounter I/O errors with Netscape + Navigator it is most of the time caused by the configured certificates. + </ul> <p> @@ -887,21 +913,21 @@ In case of problems you should search here first. <p> <ol> <li><em>Answers in the User Manual's F.A.Q. List (this)</em><br> - <a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html"> - http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_faq.html</a><br> + <a href="http://www.modssl.org/docs/2.4/ssl_faq.html"> + http://www.modssl.org/docs/2.4/ssl_faq.html</a><br> First look inside the F.A.Q. (this text), perhaps your problem is such popular that it was already answered a lot of times in the past. <p> -<li><em>Postings from the sw-mod-ssl Support Mailing List</em> - <a href="http://www.engelschall.com/sw/mod_ssl/news/list.html"> - http://www.engelschall.com/sw/mod_ssl/news/list.html</a><br> +<li><em>Postings from the modssl-users Support Mailing List</em> + <a href="http://www.modssl.org/news/list.html"> + http://www.modssl.org/news/list.html</a><br> Second search for your problem in one of the existing archives of the - sw-mod-ssl mailing list. Perhaps your problem popped up at least once for + modssl-users mailing list. Perhaps your problem popped up at least once for another user, too. <p> <li><em>Problem Reports in the Bug Database</em> - <a href="http://www.engelschall.com/sw/mod_ssl/bugdb/"> - http://www.engelschall.com/sw/mod_ssl/bugdb/</a><br> + <a href="http://www.modssl.org/support/bugdb/"> + http://www.modssl.org/support/bugdb/</a><br> Third look inside the mod_ssl Bug Database. Perhaps someone else already has reported the problem. </ol> @@ -917,16 +943,16 @@ you just like most, please. <p> <ol> <li><em>Write a Problem Report into the Bug Database</em><br> - <a href="http://www.engelschall.com/sw/mod_ssl/bugdb/"> - http://www.engelschall.com/sw/mod_ssl/bugdb/</a><br> + <a href="http://www.modssl.org/support/bugdb/"> + http://www.modssl.org/support/bugdb/</a><br> This is the preferred way of submitting your problem report, because this way it gets filed into the bug database (it cannot be lost) <em>and</em> - send to the sw-mod-ssl mailing list (others see the current problems and + send to the modssl-users mailing list (others see the current problems and learn from answers). <p> -<li><em>Write a Problem Report to the sw-mod-ssl Support Mailing List</em><br> - <a href="mailto:sw-mod-ssl@engelschall.com"> - sw-mod-ssl @ engelschall.com</a><br> +<li><em>Write a Problem Report to the modssl-users Support Mailing List</em><br> + <a href="mailto:modssl-users@modssl.org"> + modssl-users @ modssl.org</a><br> This is the second way of submitting your problem report. You have to subscribe to the list first, but then you can easily discuss your problem with both the author and the whole mod_ssl user community. @@ -937,7 +963,7 @@ you just like most, please. This is the last way of submitting your problem report. Please avoid this in your own interest because the author is really a very busy men. Your mail will always be filed to one of his various mail-folders and is - usually not processed as fast as a posting on sw-mod-ssl. + usually not processed as fast as a posting on modssl-users. </ol> <faq ref="report-details" toc="How to write a problem report?"> @@ -949,16 +975,16 @@ You have to at least always provide the following information: <p> <ul> -<li><em>Apache, mod_ssl and SSLeay version information</em><br> +<li><em>Apache, mod_ssl and OpenSSL version information</em><br> The mod_ssl version you should really know. It's for instance the version number in the distribution tarball. The Apache version can be determined - by running ``<code>httpd -v</code>''. The SSLeay version can be - determined by running ``<code>ssleay version</code>''. Alternatively when + by running ``<code>httpd -v</code>''. The OpenSSL version can be + determined by running ``<code>openssl version</code>''. Alternatively when you have Lynx installed you can run the command ``<code>lynx -mime_header http://localhost/ | grep Server</code>'' to determine all information in a single step. <p> -<li><em>The details on how you built and installed Apache+mod_ssl+SSLeay</em><br> +<li><em>The details on how you built and installed Apache+mod_ssl+OpenSSL</em><br> For this you can provide a logfile of your terminal session which shows the configuration and install steps. Alternatively you can at least provide the author with the APACI `<code>configure</code>'' command line @@ -966,7 +992,7 @@ You have to at least always provide the following information: <p> <li><em>In case of core dumps please include a Backtrace</em><br> - In case your Apache+mod_ssl+SSLeay should really dumped core please attach + In case your Apache+mod_ssl+OpenSSL should really dumped core please attach a stack-frame ``backtrace'' (see the next question on how to get it). Without this information the reason for your core dump cannot be found. So you have to provide the backtrace, please. @@ -979,6 +1005,16 @@ You have to at least always provide the following information: course. </ul> +<faq ref="core-dumped" toc="I got a core dump, can you help me?"> +I got a core dump, can you help me? +</faq> + + In general no, at least not unless you provide more details about the code + location where Apache dumped core. What is usually always required in + order to help you is a backtrace (see next question). Without this + information it is mostly impossible to find the problem and help you in + fixing it. + <faq ref="report-backtrace" toc="How to get a backtrace?"> Ok, I got a core dump but how do I get a backtrace to find out the reason for it? </faq> @@ -997,9 +1033,11 @@ Follow the following steps: make sure that the core-dump file can be written. You then should get a <code>/tmp/core</code> or <code>/tmp/httpd.core</code> file. When you don't get this, try to run your server under an UID != 0 (root), because - some kernels don't write (for security reasons) core-dumps for - root-processes. Additionally you can run ``<code>/path/to/httpd -X</code>'' - manually to force Apache not not fork. + most "current" kernels Most "current" kernels do not allow a process to + dump core after it has done a <code>setuid()</code> (unless it does an + <code>exec()</code>) for security reasons (there can be privileged + information left over in memory). Additionally you can run + ``<code>/path/to/httpd -X</code>'' manually to force Apache not not fork. <p> <li>Analyze the core-dump. For this run ``<code>gdb /path/to/httpd /tmp/httpd.core</code>'' or a similar command has to run. In GDB you then diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.html index 16edfa0fd75..ccc3a4643a9 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -110,6 +110,14 @@ H4 { font-variant: normal; font-style: normal; } +#howto { + font-weight: bold; + font-size: 16pt; + line-height: 16pt; + font-family: arial,helvetica; + font-variant: normal; + font-style: normal; +} #term { font-weight: bold; font-size: 16pt; @@ -298,6 +306,10 @@ Unknown <dd>A hash of a message, which can be used to verify that the contents of the message have not been altered in transit. <p> +<dt><DIV id="term">OpenSSL</div> +<dd>The Open Source toolkit for SSL/TLS; + see <a href="http://www.openssl.org/">http://www.openssl.org/</a> +<p> <dt><DIV id="term">Pass Phrase</div> <dd>The word or phrase that protects private key files. It prevents unauthorized users from encrypting them. Usually it's just @@ -330,7 +342,9 @@ Unknown <dd>The context information of an SSL communication. <p> <dt><DIV id="term">SSLeay</div> -<dd>The SSL/TLS implementation library developed by Eric A. Young <eay@cryptsoft.com>. +<dd>The original SSL/TLS implementation library developed by + Eric A. Young <eay@aus.rsa.com>; + see <a href="http://www.ssleay.org/">http://www.ssleay.org/</a> <p> <dt><DIV id="term">Symmetric Cryptography</div> <dd>The study and application of <em>Ciphers</em> that use a single secret key @@ -392,8 +406,8 @@ if (document.images) { <td> <table width="598"> <tr> <td align="left"><font face="Arial,Helvetica"> - <a href="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</a> 2.2, User Manual<br> - The Apache Interface to SSLeay + <a href="http://www.modssl.org/">mod_ssl</a> 2.4, User Manual<br> + The Apache Interface to OpenSSL </font> </td> <td align="right"><font face="Arial,Helvetica"> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.wml index 65eef504770..02841151ae4 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_glossary.wml @@ -91,6 +91,10 @@ realize that what you heard is not what I meant.'' <dd>A hash of a message, which can be used to verify that the contents of the message have not been altered in transit. <p> +<dt><div id="term">OpenSSL</div> +<dd>The Open Source toolkit for SSL/TLS; + see <a href="http://www.openssl.org/">http://www.openssl.org/</a> +<p> <dt><div id="term">Pass Phrase</div> <dd>The word or phrase that protects private key files. It prevents unauthorized users from encrypting them. Usually it's just @@ -123,7 +127,9 @@ realize that what you heard is not what I meant.'' <dd>The context information of an SSL communication. <p> <dt><div id="term">SSLeay</div> -<dd>The SSL/TLS implementation library developed by Eric A. Young <eay@cryptsoft.com>. +<dd>The original SSL/TLS implementation library developed by + Eric A. Young <eay@aus.rsa.com>; + see <a href="http://www.ssleay.org/">http://www.ssleay.org/</a> <p> <dt><div id="term">Symmetric Cryptography</div> <dd>The study and application of <em>Ciphers</em> that use a single secret key diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.html index ccdaefffac5..cd9348df33d 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -282,6 +282,7 @@ coherences. <a href="#ToC7"><strong>simple certificate-based client authentication</strong></a><br> <a href="#ToC8"><strong>selective certificate-based client authentication</strong></a><br> <a href="#ToC9"><strong>particular certificate-based client authentication</strong></a><br> + <a href="#ToC10"><strong>intranet vs. internet authentication</strong></a><br> </font> </td> </tr> @@ -296,7 +297,7 @@ coherences. <li><a name="ToC2"></a> <a name="cipher-sslv2"></a> <strong id="howto">How can I create a real SSLv2-only server?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#cipher-sslv2"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#cipher-sslv2"><b>L</b></a>] <p> The following creates an SSL server which speaks only the SSLv2 protocol and it's ciphers. @@ -339,7 +340,7 @@ SSLCipherSuite SSLv2:+HIGH:+MEDIUM:+LOW:+EXP <li><a name="ToC3"></a> <a name="cipher-strong"></a> <strong id="howto">How can I create an SSL server which accepts strong encryption only?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#cipher-strong"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#cipher-strong"><b>L</b></a>] <p> The following enables only the seven strongest ciphers: <p> @@ -382,7 +383,7 @@ SSLCipherSuite HIGH:MEDIUM <a name="cipher-sgc"></a> <strong id="howto">How can I create an SSL server which accepts strong encryption only, but allows export browsers to upgrade to stronger encryption?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#cipher-sgc"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#cipher-sgc"><b>L</b></a>] <p> This facility is called Server Gated Cryptography (SGC) and details you can find in the <code>README.GlobalID</code> document in the mod_ssl distribution. @@ -420,7 +421,7 @@ to keep the export ciphers. The following does the trick: <td><pre> # allow all ciphers for the inital handshake, # so export browsers can upgrade via SGC facility -SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL <Directory /usr/local/apache/htdocs> # but finally deny all browsers which haven't upgraded SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 @@ -440,7 +441,7 @@ SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 <a name="cipher-perdir"></a> <strong id="howto">How can I create an SSL server which accepts all types of ciphers in general, but requires a strong ciphers for access to a particular URL?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#cipher-perdir"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#cipher-perdir"><b>L</b></a>] <p> Obviously you cannot just use a server-wide <code>SSLCipherSuite</code> which restricts the ciphers to the strong variants. But mod_ssl allows you to @@ -471,7 +472,7 @@ solution is: <tr> <td><pre> # be liberal in general -SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL <Location /strong/area> # but https://hostname/string/area/ and below requires strong ciphers SSLCipherSuite HIGH:MEDIUM @@ -494,7 +495,7 @@ SSLCipherSuite HIGH:MEDIUM <a name="auth-simple"></a> <strong id="howto">How can I authenticate clients based on certificates when I know all my clients?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#auth-simple"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#auth-simple"><b>L</b></a>] <p> When you know your user community (i.e. a closed user group situation), as it's the case for instance in an Intranet, you can use plain certificate @@ -544,7 +545,7 @@ SSLCACertificateFile conf/ssl.crt/ca.crt <a name="auth-selective"></a> <strong id="howto">How can I authenticate my clients for a particular URL based on certificates but still allow arbitrary clients to access the remaining parts of the server?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#auth-selective"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#auth-selective"><b>L</b></a>] <p> For this we again use the per-directory reconfiguration feature of mod_ssl: <p> @@ -592,7 +593,7 @@ SSLVerifyDepth 1 <strong id="howto">How can I authenticate only particular clients for a some URLs based on certificates but still allow arbitrary clients to access the remaining parts of the server?</strong> - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#auth-particular"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#auth-particular"><b>L</b></a>] <p> The key is to check for various ingredients of the client certficate. Usually this means to check the whole or part of the Distinguished Name (DN) of the @@ -636,6 +637,7 @@ SSLCACertificateFile conf/ssl.crt/ca.crt SSLCACertificatePath conf/ssl.crt SSLOptions +FakeBasicAuth SSLRequireSSL +AuthName "Snake Oil Authentication" AuthType Basic AuthUserFile /usr/local/apache/conf/httpd.passwd require valid-user @@ -673,9 +675,9 @@ require valid-user <table border="0" cellspacing="4"> <tr> <td><pre> -/C=DE/L=Munich/O=Snake Oild, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA -/C=US/L=S.F./O=Snake Oild, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA -/C=US/L=L.A./O=Snake Oild, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA +/C=DE/L=Munich/O=Snake Oil, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA +/C=US/L=S.F./O=Snake Oil, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA +/C=US/L=L.A./O=Snake Oil, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA </pre></td> </tr> </table> @@ -732,6 +734,93 @@ SSLRequire %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." and \ <td colspan="5" bgcolor="#cccccc"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="1" align="bottom" border="0"></td> </tr> </table> +<p> +<li><a name="ToC10"></a> + <a name="auth-intranet"></a> + <strong id="howto"> How can +I require HTTPS with strong ciphers and either basic authentication or client +certificates for access to a subarea on the Intranet website for clients +coming from the Internet but still allow plain HTTP access for clients on the +Intranet?</strong> + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#auth-intranet"><b>L</b></a>] + <p> +Let us assume the Intranet can be distinguished through the IP network +192.160.1.0/24 and the subarea on the Intranet website has the URL +<tt>/subarea</tt>. Then configure the following outside your HTTPS virtual +host (so it applies to both HTTPS and HTTP): +<p> +<table border="0" cellpadding="0" cellspacing="0"> + <tr> + <td colspan="2"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="8" align="bottom" border="0"></td> + <td rowspan="3"> <font face="Arial,Helvetica" color="#999999">httpd.conf</font> </td> + <td colspan="2"> </td> + </tr> + <tr> + <td bgcolor="#cccccc" colspan="2"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="1" align="bottom" border="0"></td> + <td bgcolor="#cccccc" colspan="2"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="1" align="bottom" border="0"></td> + </tr> + <tr> + <td bgcolor="#cccccc"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="5" align="bottom" border="0"></td> + <td bgcolor="#ffffff"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="40" height="1" align="bottom" border="0"></td> + <td bgcolor="#ffffff"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="300" height="1" align="bottom" border="0"></td> + <td bgcolor="#cccccc"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="5" align="bottom" border="0"></td> + </tr> + <tr> + <td bgcolor="#cccccc"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="1" align="bottom" border="0"></td> + <td colspan="3" bgcolor="#ffffff"> + <table border="0" cellspacing="4"> + <tr> + <td><pre> +<Directory /usr/local/apache/htdocs> +# Outside the subarea only Intranet access is granted +Order deny,allow +Deny all +Allow 192.160.1.0/24 +</Directory> + +<Directory /usr/local/apache/htdocs/subarea> +# Inside the subarea any Intranet access is allowed +# but from the Internet only HTTPS + Strong-Cipher + Password +# or the alternative HTTPS + Strong-Cipher + Client-Certificate + +# If HTTPS is used, make sure a strong cipher is used. +# Additionally allow client certs as alternative to basic auth. +SSLVerifyClient optional +SSLVerifyDepth 1 +SSLCACertificateFile conf/ssl.crt/company-ca.crt +SSLOptions +FakeBasicAuth +StrictRequire +SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 + +# Force clients from the Internet to use HTTPS +RewriteEngine on +RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.[0-9]+$ +RewriteCond %{HTTPS} !=on +RewriteRule .* - [F] + +# Allow Network Access and/or Basic Auth +Satisfy any + +# Network Access Control +Order deny,allow +Deny all +Allow 192.160.1.0/24 + +# HTTP Basic Authentication +AuthType basic +AuthName "Protected Intranet Area" +AuthUserFile conf/protected.passwd +Require valid-user +</Directory> +</pre></td> + </tr> + </table> + </td> + <td bgcolor="#cccccc"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="1" align="bottom" border="0"></td> + </tr> + <tr> + <td colspan="5" bgcolor="#cccccc"><img src="ssl_template.imgdot-1x1-transp.gif" alt="" width="1" height="1" align="bottom" border="0"></td> + </tr> +</table> </ul> <p> <br> @@ -795,8 +884,8 @@ if (document.images) { <td> <table width="598"> <tr> <td align="left"><font face="Arial,Helvetica"> - <a href="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</a> 2.2, User Manual<br> - The Apache Interface to SSLeay + <a href="http://www.modssl.org/">mod_ssl</a> 2.4, User Manual<br> + The Apache Interface to OpenSSL </font> </td> <td align="right"><font face="Arial,Helvetica"> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.wml index b850ec0b1d2..32f361e78e5 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_howto.wml @@ -63,7 +63,7 @@ coherences. <a name="<get-var ref>"></a> <strong id="howto">%body</strong>\ - [<a href="http://www.engelschall.com/sw/mod_ssl/docs/2.2/ssl_howto.html#<get-var ref>"><b>L</b></a>] + [<a href="http://www.modssl.org/docs/2.2/ssl_howto.html#<get-var ref>"><b>L</b></a>] <p> <restore toc> <restore ref> @@ -132,7 +132,7 @@ to keep the export ciphers. The following does the trick: <config> \# allow all ciphers for the inital handshake, \# so export browsers can upgrade via SGC facility -SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL <Directory /usr/local/apache/htdocs> \# but finally deny all browsers which haven't upgraded SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 @@ -153,7 +153,7 @@ solution is: <p> <config> \# be liberal in general -SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP +SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL <Location /strong/area> \# but https://hostname/string/area/ and below requires strong ciphers SSLCipherSuite HIGH:MEDIUM @@ -232,6 +232,7 @@ SSLCACertificateFile conf/ssl.crt/ca.crt SSLCACertificatePath conf/ssl.crt SSLOptions +FakeBasicAuth SSLRequireSSL +AuthName "Snake Oil Authentication" AuthType Basic AuthUserFile /usr/local/apache/conf/httpd.passwd require valid-user @@ -240,9 +241,9 @@ require valid-user <p> <config file="/usr/local/apache/conf/httpd.passwd"> -/C=DE/L=Munich/O=Snake Oild, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA -/C=US/L=S.F./O=Snake Oild, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA -/C=US/L=L.A./O=Snake Oild, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA +/C=DE/L=Munich/O=Snake Oil, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA +/C=US/L=S.F./O=Snake Oil, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA +/C=US/L=L.A./O=Snake Oil, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA </config> <p> @@ -263,5 +264,61 @@ SSLRequire %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." and \\ </Directory> </config> +<howto ref="auth-intranet" toc="intranet vs. internet authentication"> How can +I require HTTPS with strong ciphers and either basic authentication or client +certificates for access to a subarea on the Intranet website for clients +coming from the Internet but still allow plain HTTP access for clients on the +Intranet? +</howto> + +Let us assume the Intranet can be distinguished through the IP network +192.160.1.0/24 and the subarea on the Intranet website has the URL +<tt>/subarea</tt>. Then configure the following outside your HTTPS virtual +host (so it applies to both HTTPS and HTTP): + +<p> +<config> +<Directory /usr/local/apache/htdocs> +\# Outside the subarea only Intranet access is granted +Order deny,allow +Deny all +Allow 192.160.1.0/24 +</Directory> + +<Directory /usr/local/apache/htdocs/subarea> +\# Inside the subarea any Intranet access is allowed +\# but from the Internet only HTTPS + Strong-Cipher + Password +\# or the alternative HTTPS + Strong-Cipher + Client-Certificate + +\# If HTTPS is used, make sure a strong cipher is used. +\# Additionally allow client certs as alternative to basic auth. +SSLVerifyClient optional +SSLVerifyDepth 1 +SSLCACertificateFile conf/ssl.crt/company-ca.crt +SSLOptions +FakeBasicAuth +StrictRequire +SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128 + +\# Force clients from the Internet to use HTTPS +RewriteEngine on +RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.[0-9]+$ +RewriteCond %{HTTPS} !=on +RewriteRule .* - [F] + +\# Allow Network Access and/or Basic Auth +Satisfy any + +\# Network Access Control +Order deny,allow +Deny all +Allow 192.160.1.0/24 + +\# HTTP Basic Authentication +AuthType basic +AuthName "Protected Intranet Area" +AuthUserFile conf/protected.passwd +Require valid-user +</Directory> +</config> + </ul> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.html index 42a60ac2f78..4011de2ee03 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -110,6 +110,14 @@ H4 { font-variant: normal; font-style: normal; } +#howto { + font-weight: bold; + font-size: 16pt; + line-height: 16pt; + font-family: arial,helvetica; + font-variant: normal; + font-style: normal; +} #term { font-weight: bold; font-size: 16pt; @@ -606,7 +614,7 @@ a protocol session. <td>First SSL protocol for which implementations exists</td> <td>- NS Navigator 1.x/2.x<br> - MS IE 3.x<br> - - Lynx/2.8+SSLeay + - Lynx/2.8+OpenSSL </td> </tr> <tr valign="top"> @@ -615,7 +623,7 @@ a protocol session. <td>Revisions to prevent specific security attacks, add non-RSA ciphers, and support for certificate chains</td> <td>- NS Navigator 2.x/3.x/4.x<br> - MS IE 3.x/4.x<br> - - Lynx/2.8+SSLeay + - Lynx/2.8+OpenSSL </td> </tr> <tr valign="top"> @@ -624,7 +632,7 @@ a protocol session. <td>Revision of SSL 3.0 to update the MAC layer to HMAC, add block padding for block ciphers, message order standardization and more alert messages. </td> -<td>- Lynx/2.8+SSLeay</td> +<td>- Lynx/2.8+OpenSSL</td> </table></td> </tr></table> </td></tr></table> @@ -908,8 +916,8 @@ if (document.images) { <td> <table width="598"> <tr> <td align="left"><font face="Arial,Helvetica"> - <a href="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</a> 2.2, User Manual<br> - The Apache Interface to SSLeay + <a href="http://www.modssl.org/">mod_ssl</a> 2.4, User Manual<br> + The Apache Interface to OpenSSL </font> </td> <td align="right"><font face="Arial,Helvetica"> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.wml index b41545b90ab..6239655e657 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_intro.wml @@ -389,7 +389,7 @@ a protocol session. <td>First SSL protocol for which implementations exists</td> <td>- NS Navigator 1.x/2.x<br> - MS IE 3.x<br> - - Lynx/2.8+SSLeay + - Lynx/2.8+OpenSSL </td> </tr> <tr valign=top> @@ -398,7 +398,7 @@ a protocol session. <td>Revisions to prevent specific security attacks, add non-RSA ciphers, and support for certificate chains</td> <td>- NS Navigator 2.x/3.x/4.x<br> - MS IE 3.x/4.x<br> - - Lynx/2.8+SSLeay + - Lynx/2.8+OpenSSL </td> </tr> <tr valign=top> @@ -407,7 +407,7 @@ a protocol session. <td>Revision of SSL 3.0 to update the MAC layer to HMAC, add block padding for block ciphers, message order standardization and more alert messages. </td> -<td>- Lynx/2.8+SSLeay</td> +<td>- Lynx/2.8+OpenSSL</td> </table> </float> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.html index deae6966c54..9b6c3e0bef6 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -239,7 +239,7 @@ Apache and SSLeay.''</em> <tr> <td align="right"> <font size="-1"> -Tim J. Hudson, SSLeay co-author +Tim J. Hudson, SSLeay F.A.Q. </font> </td> </tr> @@ -255,8 +255,8 @@ HREF="http://www.apache.org/">Apache</A> (v1.3) webserver via the <A HREF="http://www.netscape.com/newsref/std/SSL.html">Secure Socket Layer</A> (SSL v2/v3) and <A HREF="http://www.consensus.com/ietf-tls/">Transport Layer Security</A> (TLS v1) protocols by the help of the excellent SSL/TLS -implementation library <A HREF="http://www.ssleay.org/">SSLeay</A> from <A -HREF="mailto:eay@cryptsoft.com">Eric A. Young</A> and <A +implementation library <A HREF="http://www.openssl.org/">OpenSSL</A> from <A +HREF="mailto:eay@aus.rsa.com">Eric A. Young</A> and <A HREF="mailto:tjh@cryptsoft.com">Tim Hudson</A>. </td> <td> @@ -293,7 +293,7 @@ HREF="mailto:tjh@cryptsoft.com">Tim Hudson</A>. </tr> </table> <p> -The <A HREF="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</A> package was +The <A HREF="http://www.modssl.org/">mod_ssl</A> package was created in April 1998 by <A HREF="mailto:rse@engelschall.com">Ralf S. Engelschall</A> and was originally derived from the <A HREF="http://www.apache-ssl.org/">Apache-SSL</A> package developed by <A @@ -304,13 +304,13 @@ itself. This means, in short, that you are free to use it both for commercial and non-commercial purposes as long as you retain the authors' copyright notices and give the proper credit. <h2>Legalese</h2> -Although the above conditions also apply to Apache and SSLeay in general (both +Although the above conditions also apply to Apache and OpenSSL in general (both are freely available and useable software packages), you should be aware that -especially the cryptographic algorithms used inside SSLeay stay under +especially the cryptographic algorithms used inside OpenSSL stay under certain patents and perhaps import/export/use restrictions in some countries of the world. So whether you can actually use the combination -Apache+mod_ssl+SSLeay in your country depends mainly on your local state laws. -The authors of neither Apache nor mod_ssl nor SSLeay are liable for any +Apache+mod_ssl+OpenSSL in your country depends mainly on your local state laws. +The authors of neither Apache nor mod_ssl nor OpenSSL are liable for any violations you make here. <p> If you're not sure what law details apply to your country you're strongly @@ -319,9 +319,9 @@ module. A lot of hints you can find in the <a href="http://cwis.kub.nl/~frw/people/koops/lawsurvy.htm">International Law Crypto Survey</a> which is a really comprehensive resource on this topic. At least two countries with heavy cryptography restrictions are well known: -In the Unisted States (USA) first it's not allowed to (re-)export mod_ssl -or SSLeay and second it's not allowed to use Apache+mod_ssl+SSLeay (because of -patent issues on the RSA and RC4 algorithms) unless SSLeay is built with RSA +In the United States (USA) first it's not allowed to (re-)export mod_ssl +or OpenSSL and second it's not allowed to use Apache+mod_ssl+OpenSSL (because of +patent issues on the RSA and RC4 algorithms) unless OpenSSL is built with RSA DSI's RSAref package and used for non-commercial purposes only. And inside France it's not allowed to use any cryptography at all when keys with more than 40 bits are used. @@ -353,7 +353,7 @@ CREDIT INFORMATION: This product includes software developed by Ben Laurie for use in the Apache-SSL HTTP server project, software developed by Larry Wall and David MacKenzie for use in the GNU project of the FSF and software developed by Dr. -Stephen N. Henson as a companion to SSLeay. +Stephen N. Henson as a companion to OpenSSL. </font></td> </tr> </table> @@ -391,7 +391,7 @@ Usually this is done by using the APACI command <blockquote> <pre> $ cd apache_1.3.x/ -$ SSL_BASE=/path/to/ssleay ./configure ... --enable-module=ssl +$ SSL_BASE=/path/to/openssl ./configure ... --enable-module=ssl </pre> </blockquote> or by manually editing the <code>SSL_BASE</code> variable, @@ -422,8 +422,8 @@ Building mod_ssl as a DSO is especially interesting to achieve more run-time flexibility, i.e. you can decide whether to use SSL or not at run-time instead of build-time. But notice that building mod_ssl as a DSO requires that your OS/compiler supports building DSOs in the first place, and additionally that -they support linking of a DSO against a static library (SSLeay/libdb). Not all -platform support this. +they support linking of a DSO against a static library (libssl.a, libcrypo.a). +Not all platform support this. <p> <br> <table> @@ -486,8 +486,8 @@ if (document.images) { <td> <table width="598"> <tr> <td align="left"><font face="Arial,Helvetica"> - <a href="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</a> 2.2, User Manual<br> - The Apache Interface to SSLeay + <a href="http://www.modssl.org/">mod_ssl</a> 2.4, User Manual<br> + The Apache Interface to OpenSSL </font> </td> <td align="right"><font face="Arial,Helvetica"> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.wml index 85c0c682287..9b28c7a71f8 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview.wml @@ -4,8 +4,7 @@ <page_prev name="Cover" url="index.html"> <page_next name="Introduction" url="ssl_intro.html"> -<quotation width=300 - author="Tim J. Hudson, SSLeay co-author"> +<quotation width=300 author="Tim J. Hudson, SSLeay F.A.Q."> ``Ralf Engelschall has released an excellent module that integrates Apache and SSLeay.'' @@ -21,8 +20,8 @@ HREF="http://www.apache.org/">Apache</A> (v1.3) webserver via the <A HREF="http://www.netscape.com/newsref/std/SSL.html">Secure Socket Layer</A> (SSL v2/v3) and <A HREF="http://www.consensus.com/ietf-tls/">Transport Layer Security</A> (TLS v1) protocols by the help of the excellent SSL/TLS -implementation library <A HREF="http://www.ssleay.org/">SSLeay</A> from <A -HREF="mailto:eay@cryptsoft.com">Eric A. Young</A> and <A +implementation library <A HREF="http://www.openssl.org/">OpenSSL</A> from <A +HREF="mailto:eay@aus.rsa.com">Eric A. Young</A> and <A HREF="mailto:tjh@cryptsoft.com">Tim Hudson</A>. </td> @@ -65,7 +64,7 @@ HREF="mailto:tjh@cryptsoft.com">Tim Hudson</A>. </table> <p> -The <A HREF="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</A> package was +The <A HREF="http://www.modssl.org/">mod_ssl</A> package was created in April 1998 by <A HREF="mailto:rse@engelschall.com">Ralf S. Engelschall</A> and was originally derived from the <A HREF="http://www.apache-ssl.org/">Apache-SSL</A> package developed by <A @@ -78,13 +77,13 @@ notices and give the proper credit. <h2>Legalese</h2> -Although the above conditions also apply to Apache and SSLeay in general (both +Although the above conditions also apply to Apache and OpenSSL in general (both are freely available and useable software packages), you should be aware that -especially the cryptographic algorithms used inside SSLeay stay under +especially the cryptographic algorithms used inside OpenSSL stay under certain patents and perhaps import/export/use restrictions in some countries of the world. So whether you can actually use the combination -Apache+mod_ssl+SSLeay in your country depends mainly on your local state laws. -The authors of neither Apache nor mod_ssl nor SSLeay are liable for any +Apache+mod_ssl+OpenSSL in your country depends mainly on your local state laws. +The authors of neither Apache nor mod_ssl nor OpenSSL are liable for any violations you make here. <p> @@ -94,9 +93,9 @@ module. A lot of hints you can find in the <a href="http://cwis.kub.nl/~frw/people/koops/lawsurvy.htm">International Law Crypto Survey</a> which is a really comprehensive resource on this topic. At least two countries with heavy cryptography restrictions are well known: -In the Unisted States (USA) first it's not allowed to (re-)export mod_ssl -or SSLeay and second it's not allowed to use Apache+mod_ssl+SSLeay (because of -patent issues on the RSA and RC4 algorithms) unless SSLeay is built with RSA +In the United States (USA) first it's not allowed to (re-)export mod_ssl +or OpenSSL and second it's not allowed to use Apache+mod_ssl+OpenSSL (because of +patent issues on the RSA and RC4 algorithms) unless OpenSSL is built with RSA DSI's RSAref package and used for non-commercial purposes only. And inside France it's not allowed to use any cryptography at all when keys with more than 40 bits are used. @@ -125,7 +124,7 @@ CREDIT INFORMATION: This product includes software developed by Ben Laurie for use in the Apache-SSL HTTP server project, software developed by Larry Wall and David MacKenzie for use in the GNU project of the FSF and software developed by Dr. -Stephen N. Henson as a companion to SSLeay. +Stephen N. Henson as a companion to OpenSSL. </font> </box> @@ -158,7 +157,7 @@ Usually this is done by using the APACI command <blockquote> <pre> $ cd apache_1.3.x/ -$ SSL_BASE=/path/to/ssleay ./configure ... --enable-module=ssl +$ SSL_BASE=/path/to/openssl ./configure ... --enable-module=ssl </pre> </blockquote> @@ -196,6 +195,6 @@ Building mod_ssl as a DSO is especially interesting to achieve more run-time flexibility, i.e. you can decide whether to use SSL or not at run-time instead of build-time. But notice that building mod_ssl as a DSO requires that your OS/compiler supports building DSOs in the first place, and additionally that -they support linking of a DSO against a static library (SSLeay/libdb). Not all -platform support this. +they support linking of a DSO against a static library (libssl.a, libcrypo.a). +Not all platform support this. diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview_fig1.gif b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview_fig1.gif Binary files differindex 80e0e4fff03..7d18de05817 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview_fig1.gif +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_overview_fig1.gif diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.html b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.html index 5f2b4507c4b..9ca35b63905 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.html @@ -22,7 +22,7 @@ software must display the following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." 4. The name "mod_ssl" must not be used to endorse or promote products derived from this software without prior written @@ -32,7 +32,7 @@ following acknowledgment: "This product includes software developed by Ralf S. Engelschall <rse@engelschall.com> for use in the - mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + mod_ssl project (http://www.modssl.org/)." THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -292,18 +292,21 @@ virtual host''), which can occur inside the server config files both outside <a href="#ToC9"><strong>SSLCipherSuite</strong></a><br> <a href="#ToC10"><strong>SSLCertificateFile</strong></a><br> <a href="#ToC11"><strong>SSLCertificateKeyFile</strong></a><br> - <a href="#ToC12"><strong>SSLCACertificatePath</strong></a><br> - <a href="#ToC13"><strong>SSLCACertificateFile</strong></a><br> - <a href="#ToC14"><strong>SSLVerifyClient</strong></a><br> - <a href="#ToC15"><strong>SSLVerifyDepth</strong></a><br> - <a href="#ToC16"><strong>SSLLog</strong></a><br> - <a href="#ToC17"><strong>SSLLogLevel</strong></a><br> - <a href="#ToC18"><strong>SSLOptions</strong></a><br> - <a href="#ToC19"><strong>SSLRequireSSL</strong></a><br> - <a href="#ToC20"><strong>SSLRequire</strong></a><br> -<a href="#ToC21"><strong>Additional Features</strong></a><br> - <a href="#ToC22"><strong>Environment Variables</strong></a><br> - <a href="#ToC23"><strong>Custom Log Formats</strong></a><br> + <a href="#ToC12"><strong>SSLCertificateChainFile</strong></a><br> + <a href="#ToC13"><strong>SSLCACertificatePath</strong></a><br> + <a href="#ToC14"><strong>SSLCACertificateFile</strong></a><br> + <a href="#ToC15"><strong>SSLCARevocationPath</strong></a><br> + <a href="#ToC16"><strong>SSLCARevocationFile</strong></a><br> + <a href="#ToC17"><strong>SSLVerifyClient</strong></a><br> + <a href="#ToC18"><strong>SSLVerifyDepth</strong></a><br> + <a href="#ToC19"><strong>SSLLog</strong></a><br> + <a href="#ToC20"><strong>SSLLogLevel</strong></a><br> + <a href="#ToC21"><strong>SSLOptions</strong></a><br> + <a href="#ToC22"><strong>SSLRequireSSL</strong></a><br> + <a href="#ToC23"><strong>SSLRequire</strong></a><br> +<a href="#ToC24"><strong>Additional Features</strong></a><br> + <a href="#ToC25"><strong>Environment Variables</strong></a><br> + <a href="#ToC26"><strong>Custom Log Formats</strong></a><br> </font> </td> </tr> @@ -314,7 +317,7 @@ virtual host''), which can occur inside the server config files both outside </table> <p> And third <em>Per-Directory Directives</em> (i.e. those with context ``server -config, virtual host, directory, .htaccess''), which can occur mostly +config, virtual host, directory, .htaccess''), which can pretty much occur everywhere. Especially both inside the server config files and the per-directory <code>.htaccess</code> files. The three classes are subsets of each other, i.e. directives from the per-directory class can also be used in @@ -325,9 +328,9 @@ Additional directives and environment variables provided by mod_ssl (via on-the-fly mapping) for backward compatiblity to other Apache SSL solutions are documented in the <a href="ssl_compat.html">Compatibility</a> chapter. <H1><a name="ToC1">Configuration Directives</a></H1> -The most visible and error-prone things of mod_ssl are the configuration -directives it provides. So we document them in great detail here to assist you -in setting up the best possible configuration of your SSL-aware webserver. +The most visible and error-prone things of mod_ssl are its configuration +directives. So we document them in great detail here to assist you in setting +up the best possible configuration of your SSL-aware webserver. <!-- SSLPassPhraseDialog --------------------------------------------> <p> <br> @@ -416,13 +419,12 @@ which can be configured by <em>type</em>: is not compromised by an attacker, and only when these checks were passed successfully it provides the Pass Phrase. <p> - Both these security checks and the way the Pass Phrase is determined can - be as complex as one could think about it. mod_ssl just defines the - interface: an executable program which provides the Pass Phrase on - <code>stdout</code>. Nothing more or less! So, when you're really - paranoid about security, here is your interface. Anything else has to be - left as an exercise to the administrator because local security - requirements are too different. + Both these security checks, and the way the Pass Phrase is determined, can + be as complex as you like. Mod_ssl just defines the interface: an + executable program which provides the Pass Phrase on <code>stdout</code>. + Nothing more or less! So, if you're really paranoid about security, here + is your interface. Anything else has to be left as an exercise to the + administrator, because local security requirements are so different. <p> The reuse-algorithm above is used here, too. In other words: The external program is called only once per unique Pass Phrase. @@ -502,18 +504,21 @@ The following Mutex <em>types</em> are available: <p> <li><code>file:/path/to/mutex</code> <p> - This is the portable and always provided Mutex variant where a physical - (lock-)file is used as the Mutex. Always use a local disk filesystem for - <code>/path/to/mutex</code> and never a file residing on a NFS- or - AFS-filesystem. Notice: Internally the Process ID (PID) of the Apache - parent process is automatically appended to <code>/path/to/mutex</code> to - make it unique, so you don't have to care about conflicts yourself. + This is the portable and (under Unix) always provided Mutex variant where + a physical (lock-)file is used as the Mutex. Always use a local disk + filesystem for <code>/path/to/mutex</code> and never a file residing on a + NFS- or AFS-filesystem. Note: Internally, the Process ID (PID) of the + Apache parent process is automatically appended to + <code>/path/to/mutex</code> to make it unique, so you don't have to worry + about conflicts yourself. Notice that this type of mutex is not available + under the Win32 environment. There you <i>have</i> to use the semaphore + mutex. <p> <li><code>sem</code> <p> This is the most elegant but also most non-portable Mutex variant where a SysV IPC Semaphore (under Unix) and a Windows Mutex (under Win32) is used - when possible. It is only available when the underlaying platform + when possible. It is only available when the underlying platform supports it. </ul> <p> @@ -575,7 +580,7 @@ SSLMutex file:/usr/local/apache/logs/ssl_mutex </table> <p> This configures one or more sources for seeding the Pseudo Random Number -Generator (PRNG) in SSLeay at startup time (<em>context</em> is +Generator (PRNG) in OpenSSL at startup time (<em>context</em> is <code>startup</code>) and/or just before a new SSL connection is established (<em>context</em> is <code>connect</code>). This directive can only be used in the global server context because the PRNG is a global facility. @@ -596,26 +601,47 @@ The following <em>source</em> variants are available: <li><code>file:/path/to/source</code> <p> This variant uses an external file <code>/path/to/source</code> as the - source for seeding the PRNG. When <em>bytes</em> is specified only the - first <em>bytes</em> number of bytes of the file form the entropy. When - <em>bytes</em> is not specified the whole file forms the entropy. Use this - especially at startup time, for instance with an available - <code>/dev/random</code> and/or <code>/dev/urandom</code> devices (which - usually exist on modern Unix derivates like FreeBSD and Linux). + source for seeding the PRNG. When <em>bytes</em> is specified, only the + first <em>bytes</em> number of bytes of the file form the entropy (and + <em>bytes</em> is given to <code>/path/to/source</code> as the first + argument). When <em>bytes</em> is not specified the whole file forms the + entropy (and <code>0</code> is given to <code>/path/to/source</code> as + the first argument). Use this especially at startup time, for instance + with an available <code>/dev/random</code> and/or + <code>/dev/urandom</code> devices (which usually exist on modern Unix + derivates like FreeBSD and Linux). + <p> + <em>But be careful</em>: Usually <code>/dev/random</code> provides only as + much entropy data as it actually has, i.e. when you request 512 bytes of + entropy, but the device currently has only 100 bytes available two things + can happen: On some platforms you receive only the 100 bytes while on + other platforms the read blocks until enough bytes are available (which + can take a long time). Here using an existing <code>/dev/urandom</code> is + better, because it never blocks and actually gives the amount of requested + data. The drawback is just that the quality of the received data may not + be the best. + <p> + On some platforms like FreeBSD one can even control how the entropy is + actually generated, i.e. by which system interrupts. More details one can + find under <i>rndcontrol(8)</i> on those platforms. Alternatively, when + your system lacks such a random device, you can use tool like <a + href="http://www.lothar.com/tech/crypto/">EGD</a> (Entropy Gathering + Daemon) and run it's client program with the + <code>exec:/path/to/program/</code> variant (see below). <p> <li><code>exec:/path/to/program</code> <p> This variant uses an external executable <code>/path/to/program</code> as - the source for seeding the PRNG. When <em>bytes</em> is specified only the - first <em>bytes</em> number of bytes of it's <code>stdout</code> contents - form the entropy. When <em>bytes</em> is not specified the whole data - produced on <code>stdout</code> form the entropy. Use this only at startup - time when you need a very strong seeding with the help of an external - program (for instance as in the example above with the + the source for seeding the PRNG. When <em>bytes</em> is specified, only the + first <em>bytes</em> number of bytes of its <code>stdout</code> contents + form the entropy. When <em>bytes</em> is not specified, the entirety of + the data produced on <code>stdout</code> form the entropy. Use this only + at startup time when you need a very strong seeding with the help of an + external program (for instance as in the example above with the <code>truerand</code> utility you can find in the mod_ssl distribution - which is based on the AT&T <em>truerand</em> library). Using this at + which is based on the AT&T <em>truerand</em> library). Using this in the connection context slows down the server too dramatically, of course. - So usually you should avoid using external programs at this context. + So usually you should avoid using external programs in that context. </ul> <p> Example: @@ -682,12 +708,12 @@ SSLRandomSeed connect file:/dev/urandom 1024 <p> This configures the storage type of the global/inter-process SSL Session Cache. This cache is an optional facility which speeds up parallel request -processing. Because for requests to the same server process (via HTTP -keep-alive) SSLeay already caches the SSL session information locally. But -because modern clients request inlined images and other data via parallel -requests (usually up to four parallel requests are common) those requests are -served by <em>different</em> pre-forked server processes. Here an -inter-process cache helps to avoid unneccessary session handshakes. +processing. For requests to the same server process (via HTTP keep-alive), +OpenSSL already caches the SSL session information locally. But because modern +clients request inlined images and other data via parallel requests (usually +up to four parallel requests are common) those requests are served by +<em>different</em> pre-forked server processes. Here an inter-process cache +helps to avoid unneccessary session handshakes. <p> The following two storage <em>type</em>s are currently supported: <ul> @@ -700,15 +726,25 @@ The following two storage <em>type</em>s are currently supported: <li><code>dbm:/path/to/datafile</code> <p> This makes use of a DBM hashfile on the local disk to synchronize the - local SSLeay memory caches of the server processes. The little more amount - of I/O on the server results in a visible request speedup for your - clients. So it's recommended to use this storage. + local OpenSSL memory caches of the server processes. The slight increase + in I/O on the server results in a visible request speedup for your + clients, so this type of storage is generally recommended. +<p> +<li><code>shm:/path/to/datafile</code>[<code>(</code><i>size</i><code>)</code>] + <p> + This makes use of a high-performance hash table (approx. <i>size</i> bytes + in size) inside a shared memory segment in RAM (established via + <code>/path/to/datafile</code>) to synchronize the local OpenSSL memory + caches of the server processes. This storage type is not available on all + platforms. See the mod_ssl <code>INSTALL</code> document for details on + how to build Apache+EAPI with shared memory support. </ul> <p> -Example: +Examples: <blockquote> <pre> SSLSessionCache dbm:/usr/local/apache/logs/ssl_gcache_data +SSLSessionCache shm:/usr/local/apache/logs/ssl_gcache_data(512000) </pre> </blockquote> <!-- SSLSessionCacheTimeout -----------------------------------------> @@ -762,7 +798,7 @@ SSLSessionCache dbm:/usr/local/apache/logs/ssl_gcache_data </table> <p> This directive sets the timeout in seconds for the information stored in the -global/inter-process SSL Session Cache and the SSLeay internal memory cache. +global/inter-process SSL Session Cache and the OpenSSL internal memory cache. It can be set as low as 15 for testing, but should be set to higher values like 300 in real life. <p> @@ -824,7 +860,7 @@ SSLSessionCacheTimeout 600 <p> This directive toggles the usage of the SSL/TLS Protocol Engine. This is usually used inside a <VirtualHost> section to enable SSL/TLS for a -particular virtual host. Per default the SSL/TLS Protocol Engine is disabled +particular virtual host. By default the SSL/TLS Protocol Engine is disabled for both the main server and all configured virtual hosts. <p> Example: @@ -850,7 +886,7 @@ SSLEngine on <tr><td> <font face="Arial,Helvetica"><b>Name:</b></font></a> </td><td> <b>SSLProtocol</b></td></tr> <tr><td> -<font face="Arial,Helvetica"><b>Description:</b></font></a> </td><td> Configure useable SSL protocol flavors</td></tr> +<font face="Arial,Helvetica"><b>Description:</b></font></a> </td><td> Configure usable SSL protocol flavors</td></tr> <tr><td><a href="../directive-dict.html#Syntax" rel="Help" @@ -887,22 +923,22 @@ SSLEngine on </table> <p> This directive can be used to control the SSL protocol flavors mod_ssl should -use when establishing it's server environment. Clients then can only connect +use when establishing its server environment. Clients then can only connect with one of the provided protocols. <p> The available (case-insensitive) <em>protocol</em>s are: <ul> <li><code>SSLv2</code> <p> - This is the Secure Sockets Layer (SSL) protocol, version 2.0. It is the - original SSL protocol as designed by Netscape Corporation. + This is the Secure Sockets Layer (SSL) protocol, version 2.0. It is the + original SSL protocol as designed by Netscape Corporation. <p> <li><code>SSLv3</code> <p> - This is the Secure Sockets Layer (SSL) protocol, version 3.0. It is the - successor to SSLv2 and the currently (as of February 1999) de-facto - standardized SSL protocol from Netscape Corporation. It's supported by - mostly all popular browsers. + This is the Secure Sockets Layer (SSL) protocol, version 3.0. It is the + successor to SSLv2 and the currently (as of February 1999) de-facto + standardized SSL protocol from Netscape Corporation. It's supported by + almost all popular browsers. <p> <li><code>TLSv1</code> <p> @@ -976,7 +1012,7 @@ SSLProtocol all -SSLv2 </table> <p> This complex directive uses a colon-separated <em>cipher-spec</em> string -consisting of SSLeay cipher specifications to configure the Cipher Suite the +consisting of OpenSSL cipher specifications to configure the Cipher Suite the client is permitted to negotiate in the SSL handshake phase. Notice that this directive can be used both in per-server and per-directory context. In per-server context it applies to the standard SSL handshake when a connection @@ -1008,7 +1044,7 @@ specify the preference and order for the ciphers (see <a href="#table1">Table <div align="center"> <a name="table1"></a> <table width="600" cellspacing="0" cellpadding="1" border="0"> -<caption align="bottom" id="sf">Table 1: SSLeay Cipher Specification Tags</caption> +<caption align="bottom" id="sf">Table 1: OpenSSL Cipher Specification Tags</caption> <tr><td bgcolor="#cccccc"> <table width="598" cellpadding="5" cellspacing="0" border="0"> <tr><td valign="top" align="center" bgcolor="#ffffff"><table border="0" cellspacing="0" cellpadding="2" width="598"> @@ -1063,7 +1099,7 @@ the <em>cipher-spec</em>. Available prefixes are: <li><code>-</code>: remove cipher from list (can be added later again) <li><code>!</code>: kill cipher from list completely (can <b>not</b> be added later again) </ul> -A simpler way to look at all of this is to use the ``<code>ssleay ciphers +A simpler way to look at all of this is to use the ``<code>openssl ciphers -v</code>'' command which provides a nice way to successively create the correct <em>cipher-spec</em> string. The default <em>cipher-spec</em> string is ``<code>ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP</code>'' which @@ -1074,7 +1110,7 @@ security ciphers. Finally <em>pull</em> all SSLv2 and export ciphers to the end of the list. <blockquote> <pre> -$ ssleay ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP' +$ openssl ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP' NULL-SHA SSLv3 Kx=RSA Au=RSA Enc=None Mac=SHA1 NULL-MD5 SSLv3 Kx=RSA Au=RSA Enc=None Mac=MD5 EDH-RSA-DES-CBC3-SHA SSLv3 Kx=DH Au=RSA Enc=3DES(168) Mac=SHA1 @@ -1188,9 +1224,11 @@ SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW </table> <p> This directive points to the PEM-encoded Certificate file for the server and -optionally also to the corresponding RSA Private Key file for it (contained -in the same file). If the contained Private Key is encrypted the Pass Phrase -dialog is forced at startup time. +optionally also to the corresponding RSA or DSA Private Key file for it +(contained in the same file). If the contained Private Key is encrypted the +Pass Phrase dialog is forced at startup time. This directive can be used up to +two times (referencing different filenames) when both a RSA and a DSA based +server certificate is used in parallel. <p> Example: <blockquote> @@ -1212,7 +1250,7 @@ SSLCertificateFile /usr/local/apache/conf/ssl.crt/server.crt <tr><td> <font face="Arial,Helvetica"><b>Name:</b></font></a> </td><td> <b>SSLCertificateKeyFile</b></td></tr> <tr><td> -<font face="Arial,Helvetica"><b>Description:</b></font></a> </td><td> Server PEM-encoded RSA Private Key file</td></tr> +<font face="Arial,Helvetica"><b>Description:</b></font></a> </td><td> Server PEM-encoded Private Key file</td></tr> <tr><td><a href="../directive-dict.html#Syntax" rel="Help" @@ -1253,10 +1291,12 @@ the Private Key is not combined with the Certificate in the <code>SSLCertificateFile</code>, use this additional directive to point to the file with the stand-alone Private Key. When <code>SSLCertificateFile</code> is used and the file contains both the Certificate and the Private Key this -directive need not be used. But we strongly dissuade from this practice. -Instead it is recommended to separate the Certificate and the Private Key. If +directive need not be used. But we strongly discourage this practice. +Instead we recommend you to separate the Certificate and the Private Key. If the contained Private Key is encrypted, the Pass Phrase dialog is forced at -startup time. +startup time. This directive can be used up to two times (referencing +different filenames) when both a RSA and a DSA based private key is used in +parallel. <p> Example: <blockquote> @@ -1264,11 +1304,85 @@ Example: SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/server.key </pre> </blockquote> +<!-- SSLCertificateChainFile ----------------------------------------> +<p> +<br> +<a name="SSLCertificateChainFile"></a> +<H2><a name="ToC12">SSLCertificateChainFile</a></H2> +<table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> +<tr> +<td> +<table bgcolor="white" width="600" cellspacing="0" cellpadding="5" border="0"> +<tr> +<td><table cellspacing="0" cellpadding="1" border="0"> +<tr><td> +<font face="Arial,Helvetica"><b>Name:</b></font></a> </td><td> <b>SSLCertificateChainFile</b></td></tr> +<tr><td> +<font face="Arial,Helvetica"><b>Description:</b></font></a> </td><td> File of PEM-encoded Server CA Certificates</td></tr> +<tr><td><a + href="../directive-dict.html#Syntax" + rel="Help" +><font face="Arial,Helvetica"><b>Syntax:</b></font></a> </td><td> <code>SSLCertificateChainFile</code> <em>filename</em></td></tr> +<tr><td><a + href="../directive-dict.html#Default" + rel="Help" +><font face="Arial,Helvetica"><b>Default:</b></font></a> </td><td> <em>None</em></td></tr> +<tr><td><a + href="../directive-dict.html#Context" + rel="Help" +><font face="Arial,Helvetica"><b>Context:</b></font></a> </td><td> server config, virtual host</td></tr> +<tr><td><a + href="../directive-dict.html#Override" + rel="Help" +><font face="Arial,Helvetica"><b>Override:</b></font></a> </td><td> <em>Not applicable</em></td></tr> +<tr><td><a + href="../directive-dict.html#Status" + rel="Help" +><font face="Arial,Helvetica"><b>Status:</b></font></a> </td><td> Extension</td></tr> +<tr><td><a + href="../directive-dict.html#Module" + rel="Help" +><font face="Arial,Helvetica"><b>Module:</b></font></a> </td><td> mod_ssl</td></tr> +<tr><td><a + href="../directive-dict.html#Compatibility" + rel="Help" +><font face="Arial,Helvetica"><b>Compatibility:</b></font></a> </td><td> mod_ssl 2.3.6 </td></tr> +</table></td> +</tr> +</table> +</td> +</tr> +</table> +<p> +This directive sets the optional <em>all-in-one</em> file where you can +assemble the certificates of Certification Authorities (CA) which form the +certificate chain of the server certificate. This starts with the issuing CA +certificate of of the server certificate and can range up to the root CA +certificate. Such a file is simply the concatenation of the various +PEM-encoded CA Certificate files, usually in certificate chain order. +<p> +This should be used alternatively and/or additionally to <a +href="#SSLCACertificatePath">SSLCACertificatePath</a> for explicitly +constructing the server certificate chain which is sent to the browser in +addition to the server certificate. It is especially useful to avoid conflicts +with CA certificates when using client authentication. Because although +placing a CA certificate of the server certificate chain into <a +href="#SSLCACertificatePath">SSLCACertificatePath</a> has the same effect for +the certificate chain construction, it has the side-effect that client +certificates issued by this same CA certificate are also accepted on client +authentication. That's usually not one expect. +<p> +Example: +<blockquote> +<pre> +SSLCertificateChainFile /usr/local/apache/conf/ssl.crt/ca.crt +</pre> +</blockquote> <!-- SSLCACertificatePath -------------------------------------------> <p> <br> <a name="SSLCACertificatePath"></a> -<H2><a name="ToC12">SSLCACertificatePath</a></H2> +<H2><a name="ToC13">SSLCACertificatePath</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1319,8 +1433,8 @@ Certification Authorities (CAs) whose clients you deal with. These are used to verify the client certificate on Client Authentication. <p> The files in this directory have to be PEM-encoded and are accessed through -hash filenames. So usually you have not only to place the Certificate files -there. Additionally you have to create symbolic links named +hash filenames. So usually you can't just place the Certificate files +there: you also have to create symbolic links named <i>hash-value</i><tt>.N</tt>. And you should always make sure this directory contains the appropriate symbolic links. Use the <code>Makefile</code> which comes with mod_ssl to accomplish this task. @@ -1335,7 +1449,7 @@ SSLCACertificatePath /usr/local/apache/conf/ssl.crt/ <p> <br> <a name="SSLCACertificateFile"></a> -<H2><a name="ToC13">SSLCACertificateFile</a></H2> +<H2><a name="ToC14">SSLCACertificateFile</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1394,11 +1508,141 @@ Example: SSLCACertificateFile /usr/local/apache/conf/ssl.crt/ca-bundle-client.crt </pre> </blockquote> +<!-- SSLCARevocationPath --------------------------------------------> +<p> +<br> +<a name="SSLCARevocationPath"></a> +<H2><a name="ToC15">SSLCARevocationPath</a></H2> +<table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> +<tr> +<td> +<table bgcolor="white" width="600" cellspacing="0" cellpadding="5" border="0"> +<tr> +<td><table cellspacing="0" cellpadding="1" border="0"> +<tr><td> +<font face="Arial,Helvetica"><b>Name:</b></font></a> </td><td> <b>SSLCARevocationPath</b></td></tr> +<tr><td> +<font face="Arial,Helvetica"><b>Description:</b></font></a> </td><td> Directory of PEM-encoded CA CRLs for Client Auth.</td></tr> +<tr><td><a + href="../directive-dict.html#Syntax" + rel="Help" +><font face="Arial,Helvetica"><b>Syntax:</b></font></a> </td><td> <code>SSLCARevocationPath</code> <em>directory</em></td></tr> +<tr><td><a + href="../directive-dict.html#Default" + rel="Help" +><font face="Arial,Helvetica"><b>Default:</b></font></a> </td><td> <em>None</em></td></tr> +<tr><td><a + href="../directive-dict.html#Context" + rel="Help" +><font face="Arial,Helvetica"><b>Context:</b></font></a> </td><td> server config, virtual host</td></tr> +<tr><td><a + href="../directive-dict.html#Override" + rel="Help" +><font face="Arial,Helvetica"><b>Override:</b></font></a> </td><td> <em>Not applicable</em></td></tr> +<tr><td><a + href="../directive-dict.html#Status" + rel="Help" +><font face="Arial,Helvetica"><b>Status:</b></font></a> </td><td> Extension</td></tr> +<tr><td><a + href="../directive-dict.html#Module" + rel="Help" +><font face="Arial,Helvetica"><b>Module:</b></font></a> </td><td> mod_ssl</td></tr> +<tr><td><a + href="../directive-dict.html#Compatibility" + rel="Help" +><font face="Arial,Helvetica"><b>Compatibility:</b></font></a> </td><td> mod_ssl 2.3 </td></tr> +</table></td> +</tr> +</table> +</td> +</tr> +</table> +<p> +This directive sets the directory where you keep the Certificate Revocation +Lists (CRL) of Certification Authorities (CAs) whose clients you deal with. +These are used to revoke the client certificate on Client Authentication. +<p> +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you have not only to place the CRL files there. +Additionally you have to create symbolic links named +<i>hash-value</i><tt>.rN</tt>. And you should always make sure this directory +contains the appropriate symbolic links. Use the <code>Makefile</code> which +comes with mod_ssl to accomplish this task. +<p> +Example: +<blockquote> +<pre> +SSLCARevocationPath /usr/local/apache/conf/ssl.crl/ +</pre> +</blockquote> +<!-- SSLCARevocationFile --------------------------------------------> +<p> +<br> +<a name="SSLCARevocationFile"></a> +<H2><a name="ToC16">SSLCARevocationFile</a></H2> +<table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> +<tr> +<td> +<table bgcolor="white" width="600" cellspacing="0" cellpadding="5" border="0"> +<tr> +<td><table cellspacing="0" cellpadding="1" border="0"> +<tr><td> +<font face="Arial,Helvetica"><b>Name:</b></font></a> </td><td> <b>SSLCARevocationFile</b></td></tr> +<tr><td> +<font face="Arial,Helvetica"><b>Description:</b></font></a> </td><td> File of concatenated PEM-encoded CA CRLs for Client Auth.</td></tr> +<tr><td><a + href="../directive-dict.html#Syntax" + rel="Help" +><font face="Arial,Helvetica"><b>Syntax:</b></font></a> </td><td> <code>SSLCARevocationFile</code> <em>filename</em></td></tr> +<tr><td><a + href="../directive-dict.html#Default" + rel="Help" +><font face="Arial,Helvetica"><b>Default:</b></font></a> </td><td> <em>None</em></td></tr> +<tr><td><a + href="../directive-dict.html#Context" + rel="Help" +><font face="Arial,Helvetica"><b>Context:</b></font></a> </td><td> server config, virtual host</td></tr> +<tr><td><a + href="../directive-dict.html#Override" + rel="Help" +><font face="Arial,Helvetica"><b>Override:</b></font></a> </td><td> <em>Not applicable</em></td></tr> +<tr><td><a + href="../directive-dict.html#Status" + rel="Help" +><font face="Arial,Helvetica"><b>Status:</b></font></a> </td><td> Extension</td></tr> +<tr><td><a + href="../directive-dict.html#Module" + rel="Help" +><font face="Arial,Helvetica"><b>Module:</b></font></a> </td><td> mod_ssl</td></tr> +<tr><td><a + href="../directive-dict.html#Compatibility" + rel="Help" +><font face="Arial,Helvetica"><b>Compatibility:</b></font></a> </td><td> mod_ssl 2.3 </td></tr> +</table></td> +</tr> +</table> +</td> +</tr> +</table> +<p> +This directive sets the <em>all-in-one</em> file where you can assemble the +Certificate Revocation Lists (CRL) of Certification Authorities (CA) whose +<em>clients</em> you deal with. These are used for Client Authentication. +Such a file is simply the concatenation of the various PEM-encoded CRL +files, in order of preference. This can be used alternatively and/or +additionally to <a href="#SSLCARevocationPath">SSLCARevocationPath</a>. +<p> +Example: +<blockquote> +<pre> +SSLCARevocationFile /usr/local/apache/conf/ssl.crl/ca-bundle-client.crl +</pre> +</blockquote> <!-- SSLVerifyClient -------------------------------------------------> <p> <br> <a name="SSLVerifyClient"></a> -<H2><a name="ToC14">SSLVerifyClient</a></H2> +<H2><a name="ToC17">SSLVerifyClient</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1462,10 +1706,10 @@ The following levels are available for <em>level</em>: the client <em>has to</em> present a valid Certificate <li><strong>optional_no_ca</strong>: the client may present a valid Certificate<br> - but has not to be (successfully) verifyable. + but it need not to be (successfully) verifiable. </ul> In practice only levels <strong>none</strong> and <strong>require</strong> are -really interesting. Because level <strong>optional</strong> doesn't work with +really interesting, because level <strong>optional</strong> doesn't work with all browsers and level <strong>optional_no_ca</strong> is actually against the idea of authentication (but can be used to establish SSL test pages, etc.) <p> @@ -1479,7 +1723,7 @@ SSLVerifyClient require <p> <br> <a name="SSLVerifyDepth"></a> -<H2><a name="ToC15">SSLVerifyDepth</a></H2> +<H2><a name="ToC18">SSLVerifyDepth</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1551,7 +1795,7 @@ SSLVerifyDepth 10 <p> <br> <a name="SSLLog"></a> -<H2><a name="ToC16">SSLLog</a></H2> +<H2><a name="ToC19">SSLLog</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1618,7 +1862,7 @@ SSLLog /usr/local/apache/logs/ssl_engine_log <p> <br> <a name="SSLLogLevel"></a> -<H2><a name="ToC17">SSLLogLevel</a></H2> +<H2><a name="ToC20">SSLLogLevel</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1687,7 +1931,7 @@ higher levels include lower levels): processing steps. <p> <li><code>trace</code><br> - log also tace messages, i.e. messages which show minor processing steps. + log also trace messages, i.e. messages which show minor processing steps. <p> <li><code>debug</code><br> log also debugging messages, i.e. messages which show development and @@ -1704,7 +1948,7 @@ SSLLogLevel warn <p> <br> <a name="SSLOptions"></a> -<H2><a name="ToC18">SSLOptions</a></H2> +<H2><a name="ToC21">SSLOptions</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1765,8 +2009,8 @@ The available <em>option</em>s are: <p> When this option is enabled, additional CGI/SSI environment variables are created for backward compatibility to other Apache SSL solutions. Look in - the <a href="ssl_compat.html">Compatibility</a> chapter for details on the - actually generated variables. + the <a href="ssl_compat.html">Compatibility</a> chapter for details + on the particular variables generated. <p> <li><code>ExportCertData</code> <p> @@ -1784,12 +2028,37 @@ The available <em>option</em>s are: Client X509 Certificate is translated into a HTTP Basic Authorization username. This means that the standard Apache authentication methods can be used for access control. The user name is just the Subject of the - Client's X509 Certificate (can be determined by running SSLeay's - <code>ssleay x509</code> command: <code>ssleay x509 -noout -subject -in + Client's X509 Certificate (can be determined by running OpenSSL's + <code>openssl x509</code> command: <code>openssl x509 -noout -subject -in </code><em>certificate</em><code>.crt</code>). Note that no password is obtained from the user. Every entry in the user file needs this password: ``<code>xxj31ZMTZzkVA</code>'', which is the encrypted version of the word ``<code>password</code>''. +<p> +<li><code>StrictRequire</code> + <p> + This <i>forces</i> forbidden access when <code>SSLRequireSSL</code> or + <code>SSLRequire</code> successfully decided that access should be + forbidden. Usually the default is that in the case where a ``<code>Satisfy + any</code>'' directive is used, and other access restrictions are passed, + denial of access due to <code>SSLRequireSSL</code> or + <code>SSLRequire</code> is overridden (because that's how the Apache + <tt>Satisfy</tt> mechanism should work.) But for strict access restriction + you can use <code>SSLRequireSSL</code> and/or <code>SSLRequire</code> in + combination with an ``<code>SSLOptions +StrictRequire</code>''. Then an + additional ``<code>Satisfy Any</code>'' has no chance once mod_ssl has + decided to deny access. +<p> +<li><code>OptRenegotiate</code> + <p> + This enables optimized SSL connection renegotiation handling when SSL + directives are used in per-directory context. By default a strict + scheme is enabled where <i>every</i> per-directory reconfiguration of + SSL parameters causes a <i>full</i> SSL renegotiation handshake. When this + option is used mod_ssl tries to avoid unnecessary handshakes by doing more + granular (but still safe) parameter checks. Nevertheless these granular + checks sometimes maybe not what the user expects, so enable this on a + per-directory basis only, please. </ul> <p> Example: @@ -1802,7 +2071,7 @@ SSLOptions +FakeBasicAuth -CompatEnvVars <p> <br> <a name="SSLRequireSSL"></a> -<H2><a name="ToC19">SSLRequireSSL</a></H2> +<H2><a name="ToC22">SSLRequireSSL</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1864,7 +2133,7 @@ SSLRequireSSL <p> <br> <a name="SSLRequire"></a> -<H2><a name="ToC20">SSLRequire</a></H2> +<H2><a name="ToC23">SSLRequire</a></H2> <table cellspacing="0" cellpadding="1" bgcolor="#cccccc" border="0"> <tr> <td> @@ -1961,10 +2230,10 @@ are available: regular expression, etc. </ul> Notice that <em>expression</em> is first parsed into an internal machine -representation and then evaluated in a second step. Actually in Global and +representation and then evaluated in a second step. Actually, in Global and Per-Server Class context <em>expression</em> is parsed at startup time and -at runtime the machine representation is executed only. For Per-Directory -context this is different: Here <em>expression</em> has to be parsed and +at runtime only the machine representation is executed. For Per-Directory +context this is different: here <em>expression</em> has to be parsed and immediately executed for every request. <p> Example: @@ -2005,13 +2274,13 @@ REQUEST_FILENAME <pre> HTTPS SSL_CLIENT_M_VERSION SSL_SERVER_M_VERSION SSL_CLIENT_M_SERIAL SSL_SERVER_M_SERIAL -SSL_VERSION_LIBRARY SSL_CLIENT_V_START SSL_SERVER_V_START -SSL_VERSION_INTERFACE SSL_CLIENT_V_END SSL_SERVER_V_END +SSL_PROTOCOL SSL_CLIENT_V_START SSL_SERVER_V_START +SSL_SESSION_ID SSL_CLIENT_V_END SSL_SERVER_V_END SSL_CIPHER SSL_CLIENT_S_DN SSL_SERVER_S_DN -SSL_CIPHER_USEKEYSIZE SSL_CLIENT_S_DN_C SSL_SERVER_S_DN_C -SSL_CIPHER_ALGKEYSIZE SSL_CLIENT_S_DN_SP SSL_SERVER_S_DN_SP - SSL_CLIENT_S_DN_L SSL_SERVER_S_DN_L - SSL_CLIENT_S_DN_O SSL_SERVER_S_DN_O +SSL_CIPHER_ALGKEYSIZE SSL_CLIENT_S_DN_C SSL_SERVER_S_DN_C +SSL_CIPHER_USEKEYSIZE SSL_CLIENT_S_DN_SP SSL_SERVER_S_DN_SP +SSL_VERSION_LIBRARY SSL_CLIENT_S_DN_L SSL_SERVER_S_DN_L +SSL_VERSION_INTERFACE SSL_CLIENT_S_DN_O SSL_SERVER_S_DN_O SSL_CLIENT_S_DN_OU SSL_SERVER_S_DN_OU SSL_CLIENT_S_DN_CN SSL_SERVER_S_DN_CN SSL_CLIENT_S_DN_Email SSL_SERVER_S_DN_Email @@ -2034,8 +2303,8 @@ SSL_CIPHER_ALGKEYSIZE SSL_CLIENT_S_DN_SP SSL_SERVER_S_DN_SP <br> <br> <p> -<H1><a name="ToC21">Additional Features</a></H1> -<H2><a name="ToC22">Environment Variables</a></H2> +<H1><a name="ToC24">Additional Features</a></H1> +<H2><a name="ToC25">Environment Variables</a></H2> This module provides a lot of SSL information as additional environment variables to the SSI and CGI namespace. The generated variables are listed in <a href="#table4">Table 4</a>. For backward compatibility the information can @@ -2057,11 +2326,12 @@ compatibility variables. </tr> <tr id="D"><td><code>HTTPS</code></td> <td>flag</td> <td>HTTPS is being used.</td></tr> <tr id="H"><td><code>SSL_PROTOCOL</code></td> <td>string</td> <td>The SSL protocol version (SSLv2, SSLv3, TLSv1)</td></tr> +<tr id="H"><td><code>SSL_SESSION_ID</code></td> <td>string</td> <td>The hex-encoded SSL session id</td></tr> <tr id="D"><td><code>SSL_CIPHER</code></td> <td>string</td> <td>The cipher specification name</td></tr> <tr id="H"><td><code>SSL_CIPHER_USEKEYSIZE</code></td> <td>number</td> <td>Number of cipher bits (actually used)</td></tr> <tr id="D"><td><code>SSL_CIPHER_ALGKEYSIZE</code></td> <td>number</td> <td>Number of cipher bits (possible)</td></tr> <tr id="H"><td><code>SSL_VERSION_INTERFACE</code></td> <td>string</td> <td>The mod_ssl program version</td></tr> -<tr id="D"><td><code>SSL_VERSION_LIBRARY</code></td> <td>string</td> <td>The SSLeay program version</td></tr> +<tr id="D"><td><code>SSL_VERSION_LIBRARY</code></td> <td>string</td> <td>The OpenSSL program version</td></tr> <tr id="H"><td><code>SSL_CLIENT_M_VERSION</code></td> <td>string</td> <td>The version of the client certificate</td></tr> <tr id="D"><td><code>SSL_CLIENT_M_SERIAL</code></td> <td>string</td> <td>The serial of the client certificate</td></tr> <tr id="H"><td><code>SSL_CLIENT_S_DN</code></td> <td>string</td> <td>Subject DN in client's certificate</td></tr> @@ -2089,7 +2359,7 @@ compatibility variables. </div> <p> <br> -<H2><a name="ToC23">Custom Log Formats</a></H2> +<H2><a name="ToC26">Custom Log Formats</a></H2> When mod_ssl is built into Apache or at least loaded (under DSO situation) additional functions exist for the <a href="../mod_log_config.html#formats">Custom Log Format</a> of <a @@ -2172,8 +2442,8 @@ if (document.images) { <td> <table width="598"> <tr> <td align="left"><font face="Arial,Helvetica"> - <a href="http://www.engelschall.com/sw/mod_ssl/">mod_ssl</a> 2.2, User Manual<br> - The Apache Interface to SSLeay + <a href="http://www.modssl.org/">mod_ssl</a> 2.4, User Manual<br> + The Apache Interface to OpenSSL </font> </td> <td align="right"><font face="Arial,Helvetica"> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.wml b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.wml index f06b9f3966c..8276e824690 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.wml +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_ssl/ssl_reference.wml @@ -65,8 +65,8 @@ virtual host''), which can occur inside the server config files both outside <p> And third <em>Per-Directory Directives</em> (i.e. those with context ``server -config, virtual host, directory, .htaccess''), which can occur mostly -everywhere. Especially both inside the server config files and the +config, virtual host, directory, .htaccess''), which can pretty much occur +everywhere. Especially both inside the server config files and the per-directory <code>.htaccess</code> files. The three classes are subsets of each other, i.e. directives from the per-directory class can also be used in the per-server and global context, and directives from the per-server class @@ -80,9 +80,9 @@ are documented in the <a href="ssl_compat.html">Compatibility</a> chapter. <h1>Configuration Directives</h1> -The most visible and error-prone things of mod_ssl are the configuration -directives it provides. So we document them in great detail here to assist you -in setting up the best possible configuration of your SSL-aware webserver. +The most visible and error-prone things of mod_ssl are its configuration +directives. So we document them in great detail here to assist you in setting +up the best possible configuration of your SSL-aware webserver. <!-- SSLPassPhraseDialog --------------------------------------------> @@ -142,13 +142,12 @@ which can be configured by <em>type</em>: is not compromised by an attacker, and only when these checks were passed successfully it provides the Pass Phrase. <p> - Both these security checks and the way the Pass Phrase is determined can - be as complex as one could think about it. mod_ssl just defines the - interface: an executable program which provides the Pass Phrase on - <code>stdout</code>. Nothing more or less! So, when you're really - paranoid about security, here is your interface. Anything else has to be - left as an exercise to the administrator because local security - requirements are too different. + Both these security checks, and the way the Pass Phrase is determined, can + be as complex as you like. Mod_ssl just defines the interface: an + executable program which provides the Pass Phrase on <code>stdout</code>. + Nothing more or less! So, if you're really paranoid about security, here + is your interface. Anything else has to be left as an exercise to the + administrator, because local security requirements are so different. <p> The reuse-algorithm above is used here, too. In other words: The external program is called only once per unique Pass Phrase. @@ -201,18 +200,21 @@ The following Mutex <em>types</em> are available: <p> <li><code>file:/path/to/mutex</code> <p> - This is the portable and always provided Mutex variant where a physical - (lock-)file is used as the Mutex. Always use a local disk filesystem for - <code>/path/to/mutex</code> and never a file residing on a NFS- or - AFS-filesystem. Notice: Internally the Process ID (PID) of the Apache - parent process is automatically appended to <code>/path/to/mutex</code> to - make it unique, so you don't have to care about conflicts yourself. + This is the portable and (under Unix) always provided Mutex variant where + a physical (lock-)file is used as the Mutex. Always use a local disk + filesystem for <code>/path/to/mutex</code> and never a file residing on a + NFS- or AFS-filesystem. Note: Internally, the Process ID (PID) of the + Apache parent process is automatically appended to + <code>/path/to/mutex</code> to make it unique, so you don't have to worry + about conflicts yourself. Notice that this type of mutex is not available + under the Win32 environment. There you <i>have</i> to use the semaphore + mutex. <p> <li><code>sem</code> <p> This is the most elegant but also most non-portable Mutex variant where a SysV IPC Semaphore (under Unix) and a Windows Mutex (under Win32) is used - when possible. It is only available when the underlaying platform + when possible. It is only available when the underlying platform supports it. </ul> @@ -245,7 +247,7 @@ SSLMutex file:/usr/local/apache/logs/ssl_mutex <p> This configures one or more sources for seeding the Pseudo Random Number -Generator (PRNG) in SSLeay at startup time (<em>context</em> is +Generator (PRNG) in OpenSSL at startup time (<em>context</em> is <code>startup</code>) and/or just before a new SSL connection is established (<em>context</em> is <code>connect</code>). This directive can only be used in the global server context because the PRNG is a global facility. @@ -268,26 +270,47 @@ The following <em>source</em> variants are available: <li><code>file:/path/to/source</code> <p> This variant uses an external file <code>/path/to/source</code> as the - source for seeding the PRNG. When <em>bytes</em> is specified only the - first <em>bytes</em> number of bytes of the file form the entropy. When - <em>bytes</em> is not specified the whole file forms the entropy. Use this - especially at startup time, for instance with an available - <code>/dev/random</code> and/or <code>/dev/urandom</code> devices (which - usually exist on modern Unix derivates like FreeBSD and Linux). + source for seeding the PRNG. When <em>bytes</em> is specified, only the + first <em>bytes</em> number of bytes of the file form the entropy (and + <em>bytes</em> is given to <code>/path/to/source</code> as the first + argument). When <em>bytes</em> is not specified the whole file forms the + entropy (and <code>0</code> is given to <code>/path/to/source</code> as + the first argument). Use this especially at startup time, for instance + with an available <code>/dev/random</code> and/or + <code>/dev/urandom</code> devices (which usually exist on modern Unix + derivates like FreeBSD and Linux). + <p> + <em>But be careful</em>: Usually <code>/dev/random</code> provides only as + much entropy data as it actually has, i.e. when you request 512 bytes of + entropy, but the device currently has only 100 bytes available two things + can happen: On some platforms you receive only the 100 bytes while on + other platforms the read blocks until enough bytes are available (which + can take a long time). Here using an existing <code>/dev/urandom</code> is + better, because it never blocks and actually gives the amount of requested + data. The drawback is just that the quality of the received data may not + be the best. + <p> + On some platforms like FreeBSD one can even control how the entropy is + actually generated, i.e. by which system interrupts. More details one can + find under <i>rndcontrol(8)</i> on those platforms. Alternatively, when + your system lacks such a random device, you can use tool like <a + href="http://www.lothar.com/tech/crypto/">EGD</a> (Entropy Gathering + Daemon) and run it's client program with the + <code>exec:/path/to/program/</code> variant (see below). <p> <li><code>exec:/path/to/program</code> <p> This variant uses an external executable <code>/path/to/program</code> as - the source for seeding the PRNG. When <em>bytes</em> is specified only the - first <em>bytes</em> number of bytes of it's <code>stdout</code> contents - form the entropy. When <em>bytes</em> is not specified the whole data - produced on <code>stdout</code> form the entropy. Use this only at startup - time when you need a very strong seeding with the help of an external - program (for instance as in the example above with the + the source for seeding the PRNG. When <em>bytes</em> is specified, only the + first <em>bytes</em> number of bytes of its <code>stdout</code> contents + form the entropy. When <em>bytes</em> is not specified, the entirety of + the data produced on <code>stdout</code> form the entropy. Use this only + at startup time when you need a very strong seeding with the help of an + external program (for instance as in the example above with the <code>truerand</code> utility you can find in the mod_ssl distribution - which is based on the AT&T <em>truerand</em> library). Using this at + which is based on the AT&T <em>truerand</em> library). Using this in the connection context slows down the server too dramatically, of course. - So usually you should avoid using external programs at this context. + So usually you should avoid using external programs in that context. </ul> <p> @@ -325,12 +348,12 @@ SSLRandomSeed connect file:/dev/urandom 1024 <p> This configures the storage type of the global/inter-process SSL Session Cache. This cache is an optional facility which speeds up parallel request -processing. Because for requests to the same server process (via HTTP -keep-alive) SSLeay already caches the SSL session information locally. But -because modern clients request inlined images and other data via parallel -requests (usually up to four parallel requests are common) those requests are -served by <em>different</em> pre-forked server processes. Here an -inter-process cache helps to avoid unneccessary session handshakes. +processing. For requests to the same server process (via HTTP keep-alive), +OpenSSL already caches the SSL session information locally. But because modern +clients request inlined images and other data via parallel requests (usually +up to four parallel requests are common) those requests are served by +<em>different</em> pre-forked server processes. Here an inter-process cache +helps to avoid unneccessary session handshakes. <p> The following two storage <em>type</em>s are currently supported: @@ -345,16 +368,26 @@ The following two storage <em>type</em>s are currently supported: <li><code>dbm:/path/to/datafile</code> <p> This makes use of a DBM hashfile on the local disk to synchronize the - local SSLeay memory caches of the server processes. The little more amount - of I/O on the server results in a visible request speedup for your - clients. So it's recommended to use this storage. + local OpenSSL memory caches of the server processes. The slight increase + in I/O on the server results in a visible request speedup for your + clients, so this type of storage is generally recommended. +<p> +<li><code>shm:/path/to/datafile</code>[<code>(</code><i>size</i><code>)</code>] + <p> + This makes use of a high-performance hash table (approx. <i>size</i> bytes + in size) inside a shared memory segment in RAM (established via + <code>/path/to/datafile</code>) to synchronize the local OpenSSL memory + caches of the server processes. This storage type is not available on all + platforms. See the mod_ssl <code>INSTALL</code> document for details on + how to build Apache+EAPI with shared memory support. </ul> <p> -Example: +Examples: <blockquote> <pre> SSLSessionCache dbm:/usr/local/apache/logs/ssl_gcache_data +SSLSessionCache shm:/usr/local/apache/logs/ssl_gcache_data(512000) </pre> </blockquote> @@ -378,7 +411,7 @@ SSLSessionCache dbm:/usr/local/apache/logs/ssl_gcache_data <p> This directive sets the timeout in seconds for the information stored in the -global/inter-process SSL Session Cache and the SSLeay internal memory cache. +global/inter-process SSL Session Cache and the OpenSSL internal memory cache. It can be set as low as 15 for testing, but should be set to higher values like 300 in real life. @@ -411,7 +444,7 @@ SSLSessionCacheTimeout 600 <p> This directive toggles the usage of the SSL/TLS Protocol Engine. This is usually used inside a <VirtualHost> section to enable SSL/TLS for a -particular virtual host. Per default the SSL/TLS Protocol Engine is disabled +particular virtual host. By default the SSL/TLS Protocol Engine is disabled for both the main server and all configured virtual hosts. <p> @@ -435,7 +468,7 @@ SSLEngine on <directive name="SSLProtocol" - description="Configure useable SSL protocol flavors" + description="Configure usable SSL protocol flavors" syntax="<code>SSLProtocol</code> [+-]<em>protocol</em> ..." default="<code>SSLProtocol all</code>" context="server config, virtual host" @@ -445,7 +478,7 @@ SSLEngine on <p> This directive can be used to control the SSL protocol flavors mod_ssl should -use when establishing it's server environment. Clients then can only connect +use when establishing its server environment. Clients then can only connect with one of the provided protocols. <p> @@ -454,15 +487,15 @@ The available (case-insensitive) <em>protocol</em>s are: <ul> <li><code>SSLv2</code> <p> - This is the Secure Sockets Layer (SSL) protocol, version 2.0. It is the - original SSL protocol as designed by Netscape Corporation. + This is the Secure Sockets Layer (SSL) protocol, version 2.0. It is the + original SSL protocol as designed by Netscape Corporation. <p> <li><code>SSLv3</code> <p> - This is the Secure Sockets Layer (SSL) protocol, version 3.0. It is the - successor to SSLv2 and the currently (as of February 1999) de-facto - standardized SSL protocol from Netscape Corporation. It's supported by - mostly all popular browsers. + This is the Secure Sockets Layer (SSL) protocol, version 3.0. It is the + successor to SSLv2 and the currently (as of February 1999) de-facto + standardized SSL protocol from Netscape Corporation. It's supported by + almost all popular browsers. <p> <li><code>TLSv1</code> <p> @@ -507,7 +540,7 @@ SSLProtocol all -SSLv2 <p> This complex directive uses a colon-separated <em>cipher-spec</em> string -consisting of SSLeay cipher specifications to configure the Cipher Suite the +consisting of OpenSSL cipher specifications to configure the Cipher Suite the client is permitted to negotiate in the SSL handshake phase. Notice that this directive can be used both in per-server and per-directory context. In per-server context it applies to the standard SSL handshake when a connection @@ -540,7 +573,7 @@ specify the preference and order for the ciphers (see <a href="#table1">Table 1</a>). <p> -<float name="table1" caption="Table 1: SSLeay Cipher Specification Tags"> +<float name="table1" caption="Table 1: OpenSSL Cipher Specification Tags"> <table border="0" cellspacing="0" cellpadding="2" width=598> <tr id=D><td><b>Tag</b></td> <td><b>Description</b></td> @@ -600,7 +633,7 @@ the <em>cipher-spec</em>. Available prefixes are: <li><code>!</code>: kill cipher from list completely (can <b>not</b> be added later again) </ul> -A simpler way to look at all of this is to use the ``<code>ssleay ciphers +A simpler way to look at all of this is to use the ``<code>openssl ciphers -v</code>'' command which provides a nice way to successively create the correct <em>cipher-spec</em> string. The default <em>cipher-spec</em> string is ``<code>ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP</code>'' which @@ -612,7 +645,7 @@ end of the list. <blockquote> <pre> -$ ssleay ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP' +$ openssl ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP' NULL-SHA SSLv3 Kx=RSA Au=RSA Enc=None Mac=SHA1 NULL-MD5 SSLv3 Kx=RSA Au=RSA Enc=None Mac=MD5 EDH-RSA-DES-CBC3-SHA SSLv3 Kx=DH Au=RSA Enc=3DES(168) Mac=SHA1 @@ -695,9 +728,11 @@ SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW <p> This directive points to the PEM-encoded Certificate file for the server and -optionally also to the corresponding RSA Private Key file for it (contained -in the same file). If the contained Private Key is encrypted the Pass Phrase -dialog is forced at startup time. +optionally also to the corresponding RSA or DSA Private Key file for it +(contained in the same file). If the contained Private Key is encrypted the +Pass Phrase dialog is forced at startup time. This directive can be used up to +two times (referencing different filenames) when both a RSA and a DSA based +server certificate is used in parallel. <p> Example: @@ -717,7 +752,7 @@ SSLCertificateFile /usr/local/apache/conf/ssl.crt/server.crt <directive name="SSLCertificateKeyFile" - description="Server PEM-encoded RSA Private Key file" + description="Server PEM-encoded Private Key file" syntax="<code>SSLCertificateKeyFile</code> <em>filename</em>" default="<em>None</em>" context="server config, virtual host" @@ -731,10 +766,12 @@ the Private Key is not combined with the Certificate in the <code>SSLCertificateFile</code>, use this additional directive to point to the file with the stand-alone Private Key. When <code>SSLCertificateFile</code> is used and the file contains both the Certificate and the Private Key this -directive need not be used. But we strongly dissuade from this practice. -Instead it is recommended to separate the Certificate and the Private Key. If +directive need not be used. But we strongly discourage this practice. +Instead we recommend you to separate the Certificate and the Private Key. If the contained Private Key is encrypted, the Pass Phrase dialog is forced at -startup time. +startup time. This directive can be used up to two times (referencing +different filenames) when both a RSA and a DSA based private key is used in +parallel. <p> Example: @@ -745,6 +782,52 @@ SSLCertificateKeyFile /usr/local/apache/conf/ssl.key/server.key </blockquote> +<!-- SSLCertificateChainFile ----------------------------------------> + +<p> +<br> +<a name="SSLCertificateChainFile"></a> +<h2>SSLCertificateChainFile</h2> + +<directive + name="SSLCertificateChainFile" + description="File of PEM-encoded Server CA Certificates" + syntax="<code>SSLCertificateChainFile</code> <em>filename</em>" + default="<em>None</em>" + context="server config, virtual host" + override="<em>Not applicable</em>" + compat="mod_ssl 2.3.6" +> + +<p> +This directive sets the optional <em>all-in-one</em> file where you can +assemble the certificates of Certification Authorities (CA) which form the +certificate chain of the server certificate. This starts with the issuing CA +certificate of of the server certificate and can range up to the root CA +certificate. Such a file is simply the concatenation of the various +PEM-encoded CA Certificate files, usually in certificate chain order. + +<p> +This should be used alternatively and/or additionally to <a +href="#SSLCACertificatePath">SSLCACertificatePath</a> for explicitly +constructing the server certificate chain which is sent to the browser in +addition to the server certificate. It is especially useful to avoid conflicts +with CA certificates when using client authentication. Because although +placing a CA certificate of the server certificate chain into <a +href="#SSLCACertificatePath">SSLCACertificatePath</a> has the same effect for +the certificate chain construction, it has the side-effect that client +certificates issued by this same CA certificate are also accepted on client +authentication. That's usually not one expect. + +<p> +Example: +<blockquote> +<pre> +SSLCertificateChainFile /usr/local/apache/conf/ssl.crt/ca.crt +</pre> +</blockquote> + + <!-- SSLCACertificatePath -------------------------------------------> <p> @@ -769,8 +852,8 @@ verify the client certificate on Client Authentication. <p> The files in this directory have to be PEM-encoded and are accessed through -hash filenames. So usually you have not only to place the Certificate files -there. Additionally you have to create symbolic links named +hash filenames. So usually you can't just place the Certificate files +there: you also have to create symbolic links named <i>hash-value</i><tt>.N</tt>. And you should always make sure this directory contains the appropriate symbolic links. Use the <code>Makefile</code> which comes with mod_ssl to accomplish this task. @@ -818,6 +901,79 @@ SSLCACertificateFile /usr/local/apache/conf/ssl.crt/ca-bundle-client.crt </blockquote> +<!-- SSLCARevocationPath --------------------------------------------> + +<p> +<br> +<a name="SSLCARevocationPath"></a> +<h2>SSLCARevocationPath</h2> + +<directive + name="SSLCARevocationPath" + description="Directory of PEM-encoded CA CRLs for Client Auth." + syntax="<code>SSLCARevocationPath</code> <em>directory</em>" + default="<em>None</em>" + context="server config, virtual host" + override="<em>Not applicable</em>" + compat="mod_ssl 2.3" +> + +<p> +This directive sets the directory where you keep the Certificate Revocation +Lists (CRL) of Certification Authorities (CAs) whose clients you deal with. +These are used to revoke the client certificate on Client Authentication. + +<p> +The files in this directory have to be PEM-encoded and are accessed through +hash filenames. So usually you have not only to place the CRL files there. +Additionally you have to create symbolic links named +<i>hash-value</i><tt>.rN</tt>. And you should always make sure this directory +contains the appropriate symbolic links. Use the <code>Makefile</code> which +comes with mod_ssl to accomplish this task. + +<p> +Example: +<blockquote> +<pre> +SSLCARevocationPath /usr/local/apache/conf/ssl.crl/ +</pre> +</blockquote> + + +<!-- SSLCARevocationFile --------------------------------------------> + +<p> +<br> +<a name="SSLCARevocationFile"></a> +<h2>SSLCARevocationFile</h2> + +<directive + name="SSLCARevocationFile" + description="File of concatenated PEM-encoded CA CRLs for Client Auth." + syntax="<code>SSLCARevocationFile</code> <em>filename</em>" + default="<em>None</em>" + context="server config, virtual host" + override="<em>Not applicable</em>" + compat="mod_ssl 2.3" +> + +<p> +This directive sets the <em>all-in-one</em> file where you can assemble the +Certificate Revocation Lists (CRL) of Certification Authorities (CA) whose +<em>clients</em> you deal with. These are used for Client Authentication. +Such a file is simply the concatenation of the various PEM-encoded CRL +files, in order of preference. This can be used alternatively and/or +additionally to <a href="#SSLCARevocationPath">SSLCARevocationPath</a>. + +<p> +Example: +<blockquote> +<pre> +SSLCARevocationFile /usr/local/apache/conf/ssl.crl/ca-bundle-client.crl +</pre> +</blockquote> + + <!-- SSLVerifyClient -------------------------------------------------> <p> @@ -856,11 +1012,11 @@ The following levels are available for <em>level</em>: the client <em>has to</em> present a valid Certificate <li><strong>optional_no_ca</strong>: the client may present a valid Certificate<br> - but has not to be (successfully) verifyable. + but it need not to be (successfully) verifiable. </ul> In practice only levels <strong>none</strong> and <strong>require</strong> are -really interesting. Because level <strong>optional</strong> doesn't work with +really interesting, because level <strong>optional</strong> doesn't work with all browsers and level <strong>optional_no_ca</strong> is actually against the idea of authentication (but can be used to establish SSL test pages, etc.) @@ -997,7 +1153,7 @@ higher levels include lower levels): processing steps. <p> <li><code>trace</code><br> - log also tace messages, i.e. messages which show minor processing steps. + log also trace messages, i.e. messages which show minor processing steps. <p> <li><code>debug</code><br> log also debugging messages, i.e. messages which show development and @@ -1048,8 +1204,8 @@ The available <em>option</em>s are: <p> When this option is enabled, additional CGI/SSI environment variables are created for backward compatibility to other Apache SSL solutions. Look in - the <a href="ssl_compat.html">Compatibility</a> chapter for details on the - actually generated variables. + the <a href="ssl_compat.html">Compatibility</a> chapter for details + on the particular variables generated. <p> <li><code>ExportCertData</code> <p> @@ -1067,12 +1223,37 @@ The available <em>option</em>s are: Client X509 Certificate is translated into a HTTP Basic Authorization username. This means that the standard Apache authentication methods can be used for access control. The user name is just the Subject of the - Client's X509 Certificate (can be determined by running SSLeay's - <code>ssleay x509</code> command: <code>ssleay x509 -noout -subject -in + Client's X509 Certificate (can be determined by running OpenSSL's + <code>openssl x509</code> command: <code>openssl x509 -noout -subject -in </code><em>certificate</em><code>.crt</code>). Note that no password is obtained from the user. Every entry in the user file needs this password: ``<code>xxj31ZMTZzkVA</code>'', which is the encrypted version of the word ``<code>password</code>''. +<p> +<li><code>StrictRequire</code> + <p> + This <i>forces</i> forbidden access when <code>SSLRequireSSL</code> or + <code>SSLRequire</code> successfully decided that access should be + forbidden. Usually the default is that in the case where a ``<code>Satisfy + any</code>'' directive is used, and other access restrictions are passed, + denial of access due to <code>SSLRequireSSL</code> or + <code>SSLRequire</code> is overridden (because that's how the Apache + <tt>Satisfy</tt> mechanism should work.) But for strict access restriction + you can use <code>SSLRequireSSL</code> and/or <code>SSLRequire</code> in + combination with an ``<code>SSLOptions +StrictRequire</code>''. Then an + additional ``<code>Satisfy Any</code>'' has no chance once mod_ssl has + decided to deny access. +<p> +<li><code>OptRenegotiate</code> + <p> + This enables optimized SSL connection renegotiation handling when SSL + directives are used in per-directory context. By default a strict + scheme is enabled where <i>every</i> per-directory reconfiguration of + SSL parameters causes a <i>full</i> SSL renegotiation handshake. When this + option is used mod_ssl tries to avoid unnecessary handshakes by doing more + granular (but still safe) parameter checks. Nevertheless these granular + checks sometimes maybe not what the user expects, so enable this on a + per-directory basis only, please. </ul> <p> @@ -1191,10 +1372,10 @@ are available: </ul> Notice that <em>expression</em> is first parsed into an internal machine -representation and then evaluated in a second step. Actually in Global and +representation and then evaluated in a second step. Actually, in Global and Per-Server Class context <em>expression</em> is parsed at startup time and -at runtime the machine representation is executed only. For Per-Directory -context this is different: Here <em>expression</em> has to be parsed and +at runtime only the machine representation is executed. For Per-Directory +context this is different: here <em>expression</em> has to be parsed and immediately executed for every request. <p> @@ -1233,13 +1414,13 @@ REQUEST_FILENAME <pre> HTTPS SSL_CLIENT_M_VERSION SSL_SERVER_M_VERSION SSL_CLIENT_M_SERIAL SSL_SERVER_M_SERIAL -SSL_VERSION_LIBRARY SSL_CLIENT_V_START SSL_SERVER_V_START -SSL_VERSION_INTERFACE SSL_CLIENT_V_END SSL_SERVER_V_END +SSL_PROTOCOL SSL_CLIENT_V_START SSL_SERVER_V_START +SSL_SESSION_ID SSL_CLIENT_V_END SSL_SERVER_V_END SSL_CIPHER SSL_CLIENT_S_DN SSL_SERVER_S_DN -SSL_CIPHER_USEKEYSIZE SSL_CLIENT_S_DN_C SSL_SERVER_S_DN_C -SSL_CIPHER_ALGKEYSIZE SSL_CLIENT_S_DN_SP SSL_SERVER_S_DN_SP - SSL_CLIENT_S_DN_L SSL_SERVER_S_DN_L - SSL_CLIENT_S_DN_O SSL_SERVER_S_DN_O +SSL_CIPHER_ALGKEYSIZE SSL_CLIENT_S_DN_C SSL_SERVER_S_DN_C +SSL_CIPHER_USEKEYSIZE SSL_CLIENT_S_DN_SP SSL_SERVER_S_DN_SP +SSL_VERSION_LIBRARY SSL_CLIENT_S_DN_L SSL_SERVER_S_DN_L +SSL_VERSION_INTERFACE SSL_CLIENT_S_DN_O SSL_SERVER_S_DN_O SSL_CLIENT_S_DN_OU SSL_SERVER_S_DN_OU SSL_CLIENT_S_DN_CN SSL_SERVER_S_DN_CN SSL_CLIENT_S_DN_Email SSL_SERVER_S_DN_Email @@ -1282,11 +1463,12 @@ compatibility variables. </tr> <tr id=D><td><code>HTTPS</code></td> <td>flag</td> <td>HTTPS is being used.</td></tr> <tr id=H><td><code>SSL_PROTOCOL</code></td> <td>string</td> <td>The SSL protocol version (SSLv2, SSLv3, TLSv1)</td></tr> +<tr id=H><td><code>SSL_SESSION_ID</code></td> <td>string</td> <td>The hex-encoded SSL session id</td></tr> <tr id=D><td><code>SSL_CIPHER</code></td> <td>string</td> <td>The cipher specification name</td></tr> <tr id=H><td><code>SSL_CIPHER_USEKEYSIZE</code></td> <td>number</td> <td>Number of cipher bits (actually used)</td></tr> <tr id=D><td><code>SSL_CIPHER_ALGKEYSIZE</code></td> <td>number</td> <td>Number of cipher bits (possible)</td></tr> <tr id=H><td><code>SSL_VERSION_INTERFACE</code></td> <td>string</td> <td>The mod_ssl program version</td></tr> -<tr id=D><td><code>SSL_VERSION_LIBRARY</code></td> <td>string</td> <td>The SSLeay program version</td></tr> +<tr id=D><td><code>SSL_VERSION_LIBRARY</code></td> <td>string</td> <td>The OpenSSL program version</td></tr> <tr id=H><td><code>SSL_CLIENT_M_VERSION</code></td> <td>string</td> <td>The version of the client certificate</td></tr> <tr id=D><td><code>SSL_CLIENT_M_SERIAL</code></td> <td>string</td> <td>The serial of the client certificate</td></tr> <tr id=H><td><code>SSL_CLIENT_S_DN</code></td> <td>string</td> <td>Subject DN in client's certificate</td></tr> diff --git a/usr.sbin/httpd/htdocs/manual/mod/mod_usertrack.html b/usr.sbin/httpd/htdocs/manual/mod/mod_usertrack.html index 5dc90165e3f..a949bfd91af 100644 --- a/usr.sbin/httpd/htdocs/manual/mod/mod_usertrack.html +++ b/usr.sbin/httpd/htdocs/manual/mod/mod_usertrack.html @@ -15,11 +15,11 @@ <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> </DIV> -<H1 ALIGN="CENTER">Module mod_usertrack</h1> +<H1 ALIGN="CENTER">Module mod_usertrack</H1> Previous releases of Apache have included a module which generates a 'clickstream' log of user activity on a site using cookies. This was @@ -28,58 +28,128 @@ module has been renamed the "user tracking" module, mod_usertrack. This module has been simplified and new directives added. -<hr> +<HR> -<h2>Logging</h2> +<H2>Logging</H2> Previously, the cookies module (now the user tracking module) did its -own logging, using the <tt>CookieLog</tt> directive. In this release, +own logging, using the <TT>CookieLog</TT> directive. In this release, this module does no logging at all. Instead, a configurable log format file should be used to log user click-streams. This is possible -because the logging module now allows <a -href="../multilogs.html">multiple log files</a>. The cookie itself is -logged by using the text <tt>%{cookie}n </tt> +because the logging module now allows <A +HREF="../multilogs.html">multiple log files</A>. The cookie itself is +logged by using the text <TT>%{cookie}n </TT> in the log file format. For example: -<pre> +<PRE> CustomLog logs/clickstream "%{cookie}n %r %t" -</pre> +</PRE> For backward compatibility the configurable log module implements the -old <tt>CookieLog</tt> directive, but this should be upgraded to the -above <tt>CustomLog</tt> directive. +old <TT>CookieLog</TT> directive, but this should be upgraded to the +above <TT>CustomLog</TT> directive. -<h2>Directives</h2> +<H2>Directives</H2> -<ul> -<li><a href="#cookieexpires">CookieExpires</a> -<li><a href="#cookietracking">CookieTracking</a> -</ul> +<UL> +<LI><A HREF="#cookieexpires">CookieExpires</A> +<LI><A HREF="#cookiename">CookieName</A> +<LI><A HREF="#cookietracking">CookieTracking</A> +</UL> -<hr> +<HR> -<h2><a name="cookieexpires">CookieExpires</A></h2> -<strong>Syntax:</strong> CookieExpires <em>expiry-period</em><br> -<strong>Context:</strong> server config, virtual host<br> -<strong>Status:</strong> optional<br> -<strong>Module:</strong> mod_usertrack<p> +<H2><A NAME="cookieexpires">CookieExpires</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CookieExpires <EM>expiry-period</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> optional<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_usertrack<P> When used, this directive sets an expiry time on the cookie generated -by the usertrack module. The <i>expiry-period</i> can be given either +by the usertrack module. The <EM>expiry-period</EM> can be given either as a number of seconds, or in the format such as "2 weeks 3 days 7 hours". Valid denominations are: years, months, weeks, hours, minutes -and seconds. - -<p>If this directive is not used, cookies last only for the current -browser session.</p> - -<h2><a name="cookietracking">CookieTracking</A></h2> -<strong>Syntax:</strong> CookieTracking <em>on | off</em><br> -<strong>Context:</strong> server config, virtual host, directory, -.htaccess<br> -<strong>Override:</strong> FileInfo<br> -<strong>Status:</strong> optional<br> -<strong>Module:</strong> mod_usertrack<p> +and seconds. If the expiry time is in any format other than one +number indicating the number of seconds, it must be enclosed by +double quotes. + +<P>If this directive is not used, cookies last only for the current +browser session.</P> + +<H2><A NAME="cookiename">CookieName</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CookieName <EM>token</EM> +<BR> +<A + HREF="directive-dict.html#Default" + REL="Help" +><STRONG>Default:</STRONG></A> <EM>Apache</EM> +<BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, directory, +.htaccess<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> optional<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_usertrack +<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Apache 1.3.7 and later +<P> +This directive allows you to change the name of the cookie this module +uses for its tracking purposes. By default the cookie is named +"<CODE>Apache</CODE>". +</P> +<P> +You must specify a valid cookie name; results are unpredictable if +you use a name containing unusual characters. Valid characters +include A-Z, a-z, 0-9, "_", and "-". +</P> + +<H2><A NAME="cookietracking">CookieTracking</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CookieTracking <EM>on | off</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host, directory, +.htaccess<BR> +<A + HREF="directive-dict.html#Override" + REL="Help" +><STRONG>Override:</STRONG></A> FileInfo<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> optional<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_usertrack<P> When the user track module is compiled in, and "CookieTracking on" is set, Apache will start sending a user-tracking cookie for all new @@ -87,10 +157,53 @@ requests. This directive can be used to turn this behavior on or off on a per-server or per-directory basis. By default, compiling mod_usertrack will not activate cookies. +<HR> + +<H2>2-digit or 4-digit dates for cookies?</H2> + +(the following is from message +<022701bda43d$9d32bbb0$1201a8c0@christian.office.sane.com> in +the new-httpd archives) + +<P> + +<PRE> +From: "Christian Allen" <christian@sane.com> +Subject: Re: Apache Y2K bug in mod_usertrack.c +Date: Tue, 30 Jun 1998 11:41:56 -0400 + +Did some work with cookies and dug up some info that might be useful. + +True, Netscape claims that the correct format NOW is four digit dates, and +four digit dates do in fact work... for Netscape 4.x (Communicator), that +is. However, 3.x and below do NOT accept them. It seems that Netscape +originally had a 2-digit standard, and then with all of the Y2K hype and +probably a few complaints, changed to a four digit date for Communicator. +Fortunately, 4.x also understands the 2-digit format, and so the best way to +ensure that your expiration date is legible to the client's browser is to +use 2-digit dates. + +However, this does not limit expiration dates to the year 2000; if you use +an expiration year of "13", for example, it is interpreted as 2013, NOT +1913! In fact, you can use an expiration year of up to "37", and it will be +understood as "2037" by both MSIE and Netscape versions 3.x and up (not sure +about versions previous to those). Not sure why Netscape used that +particular year as its cut-off point, but my guess is that it was in respect +to UNIX's 2038 problem. Netscape/MSIE 4.x seem to be able to understand +2-digit years beyond that, at least until "50" for sure (I think they +understand up until about "70", but not for sure). + +Summary: Mozilla 3.x and up understands two digit dates up until "37" +(2037). Mozilla 4.x understands up until at least "50" (2050) in 2-digit +form, but also understands 4-digit years, which can probably reach up until +9999. Your best bet for sending a long-life cookie is to send it for some +time late in the year "37". +</PRE> <HR> + <H3 ALIGN="CENTER"> - Apache HTTP Server Version 1.2 + Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> diff --git a/usr.sbin/httpd/htdocs/manual/new_features_1_3.html b/usr.sbin/httpd/htdocs/manual/new_features_1_3.html index 2b3c0d6a135..578b83cfda9 100644 --- a/usr.sbin/httpd/htdocs/manual/new_features_1_3.html +++ b/usr.sbin/httpd/htdocs/manual/new_features_1_3.html @@ -70,7 +70,6 @@ the <A HREF="upgrading_to_1_3.html">upgrade notes</A>. it. This opens up more opportunities for log rotation, hit filtering, real-time splitting of multiple vhosts into separate logs, and asynchronous DNS resolving on the fly. - </DL> <P><HR> @@ -207,6 +206,12 @@ documentation</A> for more information. <CODE>VirtualHost</CODE> sections. This is useful for folks trying to debug their virtual host configuration. +<DT><STRONG>Control of HTTP methods</STRONG> +<DD><A HREF="mod/core.html#limitexcept"><LimitExcept> and + </LimitExcept></A> are used to enclose a group of access control + directives which will then apply to any HTTP access method not listed in + the arguments; i.e., it is the opposite of a <Limit> section and can be + used to control both standard and nonstandard/unrecognized methods. </DL> <P><HR> @@ -401,6 +406,11 @@ MIME-typing</A></STRONG> ><CODE>CustomLog</CODE></A> directives, rather than having to spell out the complete log format string each time. +<DT><STRONG>Conditional logging</STRONG> +<DD><A HREF="mod/mod_log_config.html#customlog-conditional">mod_log_config</A> + now supports logging based upon environment variables. + mod_log_referer and mod_log_agent are now deprecated. + <DT><STRONG>mod_cern_meta configurable per-directory</STRONG> <DD><A HREF="mod/mod_cern_meta.html">mod_cern_meta</A> is now configurable on a per-directory basis. @@ -607,7 +617,7 @@ MIME-typing</A></STRONG> config files. So you will see errors in the config file. This should make it easier to start Apache via rsh or crontab. -<DT><STRONG>Year-2000 Improvements</STRONG> +<DT><A NAME="y2k"><STRONG>Year-2000 Improvements</STRONG></A> <DD>The default <CODE>timefmt</CODE> string used by <A HREF="mod/mod_include.html"><CODE>mod_include</CODE></A> has been modified to display the year using four digits rather than the @@ -671,6 +681,15 @@ MIME-typing</A></STRONG> </DL> +<DT><STRONG>Support for Netscape style SHA1 encrypted passwords</STRONG><BR> +<DD>To facilitate migration or integration of BasicAuth password + schemes where the password is encrypted using SHA1 (as opposed + to apache's build in MD5 and/or the OS specific crypt(3) function + ) passwords prefixed with with <CODE>{SHA1}</CODE> are taken + as Base64 encoded SHA1 passwords. More information and + some utilities to convert Netscape ldap/ldif entries can be + found in support/SHA1. + <HR> <H3 ALIGN="CENTER"> Apache HTTP Server Version 1.3 diff --git a/usr.sbin/httpd/htdocs/manual/readme-tpf.html b/usr.sbin/httpd/htdocs/manual/readme-tpf.html index 2e9161b1aa9..a9267dfb387 100644 --- a/usr.sbin/httpd/htdocs/manual/readme-tpf.html +++ b/usr.sbin/httpd/htdocs/manual/readme-tpf.html @@ -8,7 +8,6 @@ <H1 align="center">Overview of the Apache TPF Port</H1> <HR> <CENTER>[ <A HREF="#configuration_files">Configuration Files</A> - | <A HREF="#auto_generated_files">Auto Generated Files</A> | <A HREF="#whats_available">What's Available</A> | <A HREF="#porting_notes">Porting Notes</A> ] </CENTER> @@ -41,8 +40,7 @@ work on TPF with only a couple of operating system specific changes to httpd.conf:<BR> <UL> - <LI>ServerType needs to be "inetd" since TPF does not yet support - "standalone" mode. + <LI>ServerType needs to be "inetd" on pre-PUT09 systems. <LI>Performance considerations may dictate setting KeepAlive to "Off" (the default is "On") or lowering the Timeout value from the default 300 seconds (5 minutes) in order to reduce the number of active ECBs on your system. @@ -68,64 +66,75 @@ <LI>buff.c <LI>buildmark.c <LI>ebcdic.c + <LI>gen_test.char.c + <LI>gen_uri_delims.c <LI>http_config.c <LI>http_core.c <LI>http_log.c - <LI>http_main.c + <LI>http_main.c <A HREF="#note_1"> <i><small>(see note 1)</small></i></A> <LI>http_protocol.c <LI>http_request.c - <LI>http_vhost.c <A HREF="#note_2">*</A> - <LI>mod_access.c + <LI>http_vhost.c <i><small>(requires PUT9)</small></i> + <LI>logresolve.c <i><small>(requires PUT10)</small></i> + <LI>mod_access.c <A HREF="#note_2"> <i><small>(see note 2)</small></i></A> + <LI>mod_actions.c <LI>mod_alias.c <LI>mod_asis.c + <LI>mod_auth_anon.c <LI>mod_autoindex.c <LI>mod_cern_meta.c + <LI>mod_cgi.c <i><small>(requires PUT10)</small></i> <LI>mod_dir.c + <LI>mod_env.c <LI>mod_example.c <LI>mod_expires.c <LI>mod_headers.c <LI>mod_imap.c + <LI>mod_include.c <A HREF="#note_3"> <i><small>(see note 3)</small></i></A> <LI>mod_info.c <LI>mod_log_agent.c <LI>mod_log_config.c <LI>mod_log_referer.c <LI>mod_mime.c + <LI>mod_mime_magic.c <LI>mod_negotiation.c + <LI><A HREF="http://hpwww.ec-lyon.fr/~vincent/apache/mod_put.html">mod_put.c</A> <LI>mod_setenvif.c <LI>mod_speling.c + <LI>mod_status.c + <LI>mod_unique_id.c <i><small>(requires PUT10)</small></i> <LI>mod_userdir.c <LI>mod_usertrack.c <LI>os.c <LI>os-inline.c <LI>regular expression parser + <LI>rotatelogs.c <i><small>(requires PUT10)</small></i> <LI>util.c <LI>util_date.c + <LI>util_script.c <LI>util_uri.c </UL></MULTICOL> - Please keep in mind that some major pieces are not yet in place including - standalone mode, pipes, password/group files, CGI scripts, and MD5 support. - <BR> + <br><b>Notes:</b> + <A NAME="note_1"> </A> + <ol> + <li>"Standalone" mode requires TPF version 4.1 PUT09 <A NAME="note_2"> </A> - <BR> - * virtual hosting requires TPF version 4.1 PUT09 + <li>Use of mod_access directives "<tt>allow from</tt>" & "<tt>deny from</tt>" + with host <i>names</i> (verses ip addresses) requires TPF version 4.1 PUT10 + <A NAME="note_3"> </A> + <li>CGI execution requires TPF version 4.1 PUT10 + </ol> -<H3>Components/modules not (yet?) supported on TPF:</H3> +<H3>Components/modules not yet supported on TPF:</H3> <multicol COLS=3><UL> + <LI>ap_md5c.c <LI>htpasswd.c - <LI>md5c.c - <LI>mod_actions.c <LI>mod_auth.c - <LI>mod_auth_anon.c - <LI>mod_cgi.c <LI>mod_digest.c - <LI>mod_env.c - <LI>mod_include.c - <LI>mod_mime_magic.c + <LI>mod_mmap_static.c <LI>mod_proxy.c <LI>mod_rewrite.c - <LI>mod_status.c - <LI>mod_unique_id.c <LI>proxy_cache.c <LI>proxy_connect.c <LI>proxy_ftp.c @@ -133,19 +142,16 @@ <LI>proxy_util.c <LI>rfc1413.c <LI>util_md5.c - <LI>util_script.c </UL></MULTICOL> <H3>Components/modules that don't apply or that probably won't ever be available on TPF:</H3> <multicol COLS=3><UL> - <LI>gen_test.char.c - <LI>gen_uri_delims.c <LI>mod_auth_db.c <LI>mod_auth_dbm.c <LI>mod_auth_db.module - <LI>mod_mmap_static.c <LI>mod_so.c + <LI>suexec.c </UL></MULTICOL> <A NAME="porting_notes"> </A> @@ -188,16 +194,9 @@ differences in how some functions are implemented on TPF. </P> - <H3>Temporary changes:</H3> - <P>Lastly, we needed to bypass sections of Apache processing - since this first cut for TPF doesn't include - Standalone mode, pipes, forking, et cetera. - </P> - <HR> <CENTER>[ <A HREF="#top">top</A> | <A HREF="#configuration_files">Configuration Files</A> - | <A HREF="#auto_generated_files">Auto Generated Files</A> | <A HREF="#whats_available">What's Available</A> | <A HREF="#porting_notes">Porting Notes</A> ] </CENTER> diff --git a/usr.sbin/httpd/htdocs/manual/sections.html b/usr.sbin/httpd/htdocs/manual/sections.html index ddf041c70e2..cf96b56226d 100644 --- a/usr.sbin/httpd/htdocs/manual/sections.html +++ b/usr.sbin/httpd/htdocs/manual/sections.html @@ -39,9 +39,10 @@ Everything that is syntactically allowed in section). Semantically however some things, and the most notable are <CODE>AllowOverride</CODE> and the two options <CODE>FollowSymLinks</CODE> and <CODE>SymLinksIfOwnerMatch</CODE>, -make no sense in <CODE><Location></CODE>. The same for -<CODE><Files></CODE> -- syntactically everything is fine, but -semantically some things are different. +make no sense in <CODE><Location></CODE>, +<CODE><LocationMatch></CODE> or <CODE><DirectoryMatch></CODE>. +The same for <CODE><Files></CODE> -- syntactically everything +is fine, but semantically some things are different. <H2>How the sections are merged</H2> @@ -140,7 +141,8 @@ Note about .htaccess parsing: <LI> It is not possible to use "<CODE>Options FollowSymLinks</CODE>" or "<CODE>Options SymLinksIfOwnerMatch</CODE>" inside a - <CODE><Location></CODE>/<CODE><LocationMatch></CODE> section + <CODE><Location></CODE>, <CODE><LocationMatch></CODE> + or <CODE><DirectoryMatch></CODE> section (the options are simply ignored). Using the options in question is only possible inside a <CODE><Directory></CODE> section (or a <CODE>.htaccess</CODE> file). diff --git a/usr.sbin/httpd/htdocs/manual/stopping.html b/usr.sbin/httpd/htdocs/manual/stopping.html index e5200a31da9..1b2140a56e1 100644 --- a/usr.sbin/httpd/htdocs/manual/stopping.html +++ b/usr.sbin/httpd/htdocs/manual/stopping.html @@ -132,13 +132,18 @@ In the case of graceful restarts it will also leave children running when it exits. (These are the children which are "gracefully exiting" by handling their last request.) This will cause problems if you attempt to restart the server -- it will -not be able to bind to its listening ports. At present the only work -around is to check the syntax of your files before doing a restart. The -easiest way is to just run httpd as a non-root user. If there are no -errors it will attempt to open its sockets and logs and fail because it's -not root (or because the currently running httpd already has those ports -bound). If it fails for any other reason then it's probably a config file -error and the error should be fixed before issuing the graceful restart. +not be able to bind to its listening ports. Before doing a restart, you +can check the syntax of the configuration files with the <CODE>-t</CODE> +command line argument (see <A HREF="invoking.html">Starting +Apache</A>). This still will not guarantee that the server will restart +correctly. To check the semantics of the configuration files as well +as the syntax, you can try starting httpd as a non-root user. If +there are no errors it will attempt to open its sockets and logs and +fail because it's not root (or because the currently running httpd +already has those ports bound). If it fails for any other reason then +it's probably a config file error and the error should be fixed before +issuing the graceful restart. + <H3>Appendix: signals and race conditions</H3> diff --git a/usr.sbin/httpd/htdocs/manual/vhosts/details.html b/usr.sbin/httpd/htdocs/manual/vhosts/details.html index c0c4e6a73b8..8a765e80dd6 100644 --- a/usr.sbin/httpd/htdocs/manual/vhosts/details.html +++ b/usr.sbin/httpd/htdocs/manual/vhosts/details.html @@ -132,7 +132,7 @@ set. Note that subsequent <CODE>Port</CODE> statements for this vhost will not affect the ports assigned in the address set. <P>During initialization a list for each IP address -is generated an inserted into an hash table. If the IP address is +is generated and inserted into an hash table. If the IP address is used in a <CODE>NameVirtualHost</CODE> directive the list contains all name-based vhosts for the given IP address. If there are no vhosts defined for that address the <CODE>NameVirtualHost</CODE> directive diff --git a/usr.sbin/httpd/htdocs/manual/vhosts/index.html b/usr.sbin/httpd/htdocs/manual/vhosts/index.html index d7fe8bb2f8a..852af89db59 100644 --- a/usr.sbin/httpd/htdocs/manual/vhosts/index.html +++ b/usr.sbin/httpd/htdocs/manual/vhosts/index.html @@ -47,6 +47,7 @@ of virtual host support in Apache version 1.3 and later.</P> <LI><A HREF="examples.html">Virtual Host examples for common setups</A> <LI><A HREF="details.html">In-Depth Discussion of Virtual Host Matching</A> <LI><A HREF="fd-limits.html">File Descriptor Limits</A> +<LI><A HREF="mass.html">Dynamically Configured Mass Virtual Hosting with mod_rewrite</A> </UL> <H2>Configuration directives</H2> diff --git a/usr.sbin/httpd/htdocs/manual/vhosts/name-based.html b/usr.sbin/httpd/htdocs/manual/vhosts/name-based.html index d9a9ce93e8e..15eeab51fdb 100644 --- a/usr.sbin/httpd/htdocs/manual/vhosts/name-based.html +++ b/usr.sbin/httpd/htdocs/manual/vhosts/name-based.html @@ -113,15 +113,18 @@ For example, if local users are familiar with typing "www" or "www.foobar" then you will need to add <CODE>ServerAlias www www.foobar</CODE>. It isn't possible for the server to know what domain the client uses for their name resolution -because the client doesn't provide that information in the request.</P> +because the client doesn't provide that information in the request. +The <CODE>ServerAlias</CODE> directive is generally a way to have different +hostnames pointing to the same virtual host. +</P> <H2>Compatibility with Older Browsers</H2> <P>As mentioned earlier, there are still some clients in use who do not send the required data for the name-based virtual hosts to work properly. These clients will always be sent the pages from the -<CITE>primary</CITE> name-based virtual host (the first virtual host -appearing in the configuration file for a specific IP address).</P> +first virtual host listed for that IP address (the +<CITE>primary</CITE> name-based virtual host).</P> <P>There is a possible workaround with the <A HREF="../mod/core.html#serverpath"><CODE>ServerPath</CODE></A> diff --git a/usr.sbin/httpd/htdocs/manual/windows.html b/usr.sbin/httpd/htdocs/manual/windows.html index f23f1227d94..7b26d4b304d 100644 --- a/usr.sbin/httpd/htdocs/manual/windows.html +++ b/usr.sbin/httpd/htdocs/manual/windows.html @@ -53,7 +53,9 @@ to help with development, or to track down bugs), see the section on <LI><A HREF="#run">Running Apache for Windows</A> <LI><A HREF="#use">Using Apache for Windows</A> <LI><A HREF="#cmdline">Running Apache for Windows from the Command Line</A> - <LI><A HREF="#signal">Signalling Apache when running</A> + <LI><A HREF="#service">Running Apache for Windows as a Service</A> + <LI><A HREF="#signal">Signalling Console Apache when running</A> + <LI><A HREF="#signalsrv">Signalling Service Apache when running</A> <LI><A HREF="#comp">Compiling Apache for Windows</A> </UL> @@ -62,9 +64,9 @@ to help with development, or to track down bugs), see the section on <H2><A NAME="req">Requirements</A></H2> Apache 1.3 is designed to run on Windows NT 4.0. The binary installer -will only work in Intel processors. Apache may also run on Windows 95 -and Windows NT 3.5.1, but these have not been tested. In all cases -TCP/IP networking must be installed. +will only work in Intel processors. Apache may also run on Windows 95, +Windows 98 and Windows NT 3.5.1, but these have not been tested. In +all cases TCP/IP networking must be installed. <P> @@ -72,6 +74,14 @@ If running on Windows 95, using the "Winsock2" upgrade is recommended but may not be necessary. If running on NT 4.0, installing Service Pack 2 is recommended. +<P> + +<STRONG>Note: "Winsock 2" is required for Apache 1.3.7 and later.</STRONG> + +<P> + +"Winsock 2" for Windows 95 is available <A HREF="http://www.microsoft.com/windows95/downloads/">here.</A> + <H2><A NAME="down">Downloading Apache for Windows</A></H2> <P>Information on the latest version of Apache can be found on the @@ -151,7 +161,7 @@ get started quickly the files should work as installed. There are two ways you can run Apache: <UL> - <LI>As a "service" (available on NT only). This is the best option if + <LI>As a <A HREF="#service">"service"</A> (available on NT only). This is the best option if you want Apache to automatically start when you machine boots, and to keep Apache running when you log-off. @@ -161,24 +171,35 @@ There are two ways you can run Apache: </UL> To start Apache as a service, you first need to install it as a -service. Run the "Install Apache as Service" option from the Start -menu. Once this is done you can start Apache by opening the Services -window (in the Control Panel), selecting Apache, then clicking on -Start. Apache will now be running in the background. You can later -stop Apache by clicking on Stop. As an alternative to using the -Services window, you can start and stop Apache from the control line -with +service. Multiple Apache services can be installed, each with a +different name and configuration. To install the default Apache +service named "Apache", run the "Install Apache as Service (NT only)" +option from the Start menu. Once this is done you can start the "Apache" +service by opening the Services window (in the Control Panel), selecting Apache, +then clicking on Start. Apache will now be running in the background. You +can later stop Apache by clicking on Stop. As an alternative to using +the Services window, you can start and stop the "Apache" service from the control +line with <PRE> NET START APACHE NET STOP APACHE </PRE> -To run Apache from a console window, select the "Apache Server" option -from the Start menu. This will open a console window and start Apache -running inside it. The window will remain active until you stop -Apache. To stop Apache running, see <A HREF="#signal"><SAMP>Signalling Apache -when Running</SAMP></A>. +See <A HREF="#signalsrv">Signalling Service Apache when Running</A> +for more information on installing and controlling Apache services. + +<P> + +To run Apache from a console window, select the "Start Apache as +console app" option from the Start menu (in Apache 1.3.4 and earlier, +this option was called "Apache Server"). This will open a console +window and start Apache running inside it. The window will remain +active until you stop Apache. To stop Apache running, either select +the "Shutdown Apache console app" icon option from the Start menu +(this is not available in Apache 1.3.4 or earlier), or see <A +HREF="#signal">Signalling Console Apache when Running</A> for how +to control Apache from the command line. <P> @@ -195,6 +216,12 @@ access the default page, launch a browser and enter this URL: This should respond with a welcome page, and a link to the Apache manual. If nothing happens or you get an error, look in the <SAMP>error_log</SAMP> file in the <SAMP>logs</SAMP> directory. +If your host isn't connected to the net, you may have to use +this URL: + +<PRE> + http://127.0.0.1/ +</PRE> <P> @@ -260,6 +287,49 @@ The main differences in Apache for Windows are: is available.</A> </UL> +<H2><A NAME="service">Running Apache for Windows as a Service</A></H2> + <STRONG>Note: The -n option to specify a service name is only available + with Apache 1.3.7 and later. Earlier versions of Apache only support + the default service name 'Apache'.</STRONG> + +<P> + +You can install Apache as a Windows NT service as follows: + +<PRE> + apache -i -n "service name" +</PRE> + +To install a service to use a particular configuration, specify the +configuration file when the service is installed: + +<PRE> + apache -i -n "service name" -f "\my server\conf\my.conf" +</PRE> + +To remove an Apache service, use + +<PRE> + apache -u -n "service name" +</PRE> + +The default "service name", if one is not specified, is "Apache". + +<P> + +Once a service is installed, you can use the <SAMP>-n</SAMP> option, in conjunction +with other options, to refer to a service's configuration file. For example:<br> + +To test a service's configuration file: +<PRE> + apache -n "service name" -t +</PRE> + +To start a console Apache using a service's configuration file: +<PRE> + apache -n "service name" +</PRE> + <H2><A NAME="cmdline">Running Apache for Windows from the Command Line</A></H2> The Start menu icons and the NT Service manager can provide a simple @@ -268,29 +338,44 @@ work from the command line. <P> When working with Apache it is important to know how it will find the -configuration files. Apache will try one of the following, in this order. +configuration files. You can specify a configuration file on the command line +in two ways: + +<UL> +<LI>-f specifies a path to a particular configuration file +</UL> +<PRE> apache -f "c:\my server\conf\my.conf"</PRE> +<PRE> apache -f test\test.conf</PRE> +<UL> +<LI>-n specifies the configuration file of an installed Apache service (Apache 1.3.7 and later) +</UL> +<PRE> apache -n "service name"</PRE> + +In these cases, the proper ServerRoot should be set in the configuration file. + +<P> + +If you don't specify a configuration file name with -f or -n, Apache will +use the file name compiled into the server, usually "conf/httpd.conf". Invoking +Apache with the -V switch will display this value labeled as SERVER_CONFIG_FILE. +Apache will then determine it's ServerRoot by trying the following, in this order: <UL> <LI>A ServerRoot directive via a -C switch. -<LI>The -f switch on the command line. <LI>The -d switch on the command line. +<LI>Current working directory <LI>A registry entry, created if you did a binary install. <LI>The server root compiled into the server. </UL> <P> The server root compiled into the server is usually "/apache". -invoking apache with the -v switch will display this value +invoking apache with the -V switch will display this value labeled as HTTPD_ROOT. <P> -Your current working directory when Apache is started up has no -effect on Apache's behavior. - -<P> -When invoked from the start menu or the Service Manager, Apache is -usually passed no arguments, so using the registry entry is the preferred -technique. +When invoked from the start menu, Apache is usually passed no arguments, +so using the registry entry is the preferred technique for console Apache. <P> During a binary installation, a registry key will have @@ -303,8 +388,7 @@ been installed, for example: This key is compiled into the server and can enable you to test new versions without affecting the current version. Of course you must take care not to install the new version on top of the -old version in the file system. You cannot run two invocations -of Apache on Windows simultaneously. +old version in the file system. <P> If you did not do a binary install then Apache will in some @@ -328,29 +412,32 @@ To run Apache from the command line as a console application, use the following command: <PRE> - apache -s + apache </PRE> Apache will execute, and will remain running until it is stopped by pressing -control-C. (The -s option is not required by Windows 95, but on Windows NT it -prevents Apache waiting to see if Apache is running as a service.) +control-C. -<P> +<H2><A NAME="signalsrv">Signalling Service Apache when running</A></H2> -You can install Apache as a Windows NT service as follows: +On Windows NT, multiple instances of Apache can be run as services. +Signal an Apache service to start, restart, or shutdown as follows: <PRE> - apache -i + apache -n "service name" -k start + apache -n "service name" -k restart + apache -n "service name" -k shutdown </PRE> -and to remove the Apache service, use +In addition, you can use the native NT NET command to +start and stop Apache services as follows: <PRE> - apache -u + NET START "service name" + NET STOP "service name" </PRE> - -<H2><A NAME="signal">Signalling Apache when running</A></H2> +<H2><A NAME="signal">Signalling Console Apache when running</A></H2> On Windows 95, Apache runs as a console application. You can tell a running Apache to stop by opening another console window and running @@ -494,3 +581,4 @@ the conf/magic and conf/mime.types files as well. </BODY> </HTML> + diff --git a/usr.sbin/httpd/src/.gdbinit b/usr.sbin/httpd/src/.gdbinit index b0aa1e7794f..564d9c3a255 100644 --- a/usr.sbin/httpd/src/.gdbinit +++ b/usr.sbin/httpd/src/.gdbinit @@ -13,3 +13,16 @@ end document dump_table Print the key/value pairs in a table. end + +define dump_string_array + set $a = (char **)((array_header *)$arg0)->elts + set $n = (int)((array_header *)$arg0)->nelts + set $i = 0 + while $i < $n + printf "[%u] '%s'\n", $i, $a[$i] + set $i = $i + 1 + end +end +document dump_string_array + Print all of the elements in an array of strings. +end diff --git a/usr.sbin/httpd/src/Apache.dsp b/usr.sbin/httpd/src/Apache.dsp index 25766afeb59..bbb644ded95 100644 --- a/usr.sbin/httpd/src/Apache.dsp +++ b/usr.sbin/httpd/src/Apache.dsp @@ -96,6 +96,14 @@ SOURCE=.\os\win32\main_win32.c # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\os\win32\apache.ico +# End Source File +# Begin Source File + +SOURCE=.\os\win32\apache.rc +# End Source File # End Group # End Target # End Project diff --git a/usr.sbin/httpd/src/Apache.mak b/usr.sbin/httpd/src/Apache.mak index 738e11bdb06..b44f43e0721 100644 --- a/usr.sbin/httpd/src/Apache.mak +++ b/usr.sbin/httpd/src/Apache.mak @@ -25,9 +25,6 @@ NULL= NULL=nul !ENDIF -CPP=cl.exe -RSC=rc.exe - !IF "$(CFG)" == "Apache - Win32 Release" OUTDIR=.\ApacheR @@ -47,6 +44,7 @@ ALL : "$(OUTDIR)\Apache.exe" !ENDIF CLEAN : + -@erase "$(INTDIR)\apache.res" -@erase "$(INTDIR)\main_win32.obj" -@erase "$(INTDIR)\vc50.idb" -@erase "$(OUTDIR)\Apache.exe" @@ -54,10 +52,44 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" +CPP=cl.exe CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)\Apache.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\ApacheR/ CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +RSC_PROJ=/l 0x809 /fo"$(INTDIR)\apache.res" /d "NDEBUG" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\Apache.bsc" BSC32_SBRS= \ @@ -68,6 +100,7 @@ LINK32_FLAGS=CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ /incremental:no /pdb:"$(OUTDIR)\Apache.pdb" /machine:I386\ /out:"$(OUTDIR)\Apache.exe" LINK32_OBJS= \ + "$(INTDIR)\apache.res" \ "$(INTDIR)\main_win32.obj" "$(OUTDIR)\Apache.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -94,6 +127,7 @@ ALL : "$(OUTDIR)\Apache.exe" !ENDIF CLEAN : + -@erase "$(INTDIR)\apache.res" -@erase "$(INTDIR)\main_win32.obj" -@erase "$(INTDIR)\vc50.idb" -@erase "$(INTDIR)\vc50.pdb" @@ -104,28 +138,11 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" +CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)\Apache.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\ApacheD/ CPP_SBRS=. -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Apache.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ - winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console\ - /incremental:yes /pdb:"$(OUTDIR)\Apache.pdb" /debug /machine:I386\ - /out:"$(OUTDIR)\Apache.exe" -LINK32_OBJS= \ - "$(INTDIR)\main_win32.obj" - -"$(OUTDIR)\Apache.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF .c{$(CPP_OBJS)}.obj:: $(CPP) @<< @@ -157,6 +174,28 @@ LINK32_OBJS= \ $(CPP_PROJ) $< << +RSC=rc.exe +RSC_PROJ=/l 0x809 /fo"$(INTDIR)\apache.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Apache.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console\ + /incremental:yes /pdb:"$(OUTDIR)\Apache.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)\Apache.exe" +LINK32_OBJS= \ + "$(INTDIR)\apache.res" \ + "$(INTDIR)\main_win32.obj" + +"$(OUTDIR)\Apache.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + !IF "$(CFG)" == "Apache - Win32 Release" || "$(CFG)" == "Apache - Win32 Debug" SOURCE=.\os\win32\main_win32.c @@ -165,6 +204,27 @@ SOURCE=.\os\win32\main_win32.c $(CPP) $(CPP_PROJ) $(SOURCE) +SOURCE=.\os\win32\apache.rc +DEP_RSC_APACH=\ + ".\os\win32\apache.ico"\ + + +!IF "$(CFG)" == "Apache - Win32 Release" + + +"$(INTDIR)\apache.res" : $(SOURCE) $(DEP_RSC_APACH) "$(INTDIR)" + $(RSC) /l 0x809 /fo"$(INTDIR)\apache.res" /i "os\win32" /d "NDEBUG" $(SOURCE) + + +!ELSEIF "$(CFG)" == "Apache - Win32 Debug" + + +"$(INTDIR)\apache.res" : $(SOURCE) $(DEP_RSC_APACH) "$(INTDIR)" + $(RSC) /l 0x809 /fo"$(INTDIR)\apache.res" /i "os\win32" /d "_DEBUG" $(SOURCE) + + +!ENDIF + !ENDIF diff --git a/usr.sbin/httpd/src/ApacheCore.def b/usr.sbin/httpd/src/ApacheCore.def index ce7044e12f7..e82c26d2b61 100644 --- a/usr.sbin/httpd/src/ApacheCore.def +++ b/usr.sbin/httpd/src/ApacheCore.def @@ -320,21 +320,56 @@ EXPORTS ap_method_number_of @313 ap_exists_config_define @314 ap_single_module_configure @315 - ap_single_module_init @316 ap_make_etag @317 ap_array_pstrcat @318 ap_os_is_filename_valid @319 - ap_add_config_define @320 - ap_global_ctx @321 - ap_ctx_new @322 - ap_ctx_get @323 - ap_ctx_set @324 - ap_hook_init @325 - ap_hook_kill @326 - ap_hook_configure @327 - ap_hook_register_I @328 - ap_hook_unregister_I @329 - ap_hook_status @330 - ap_hook_use @331 - ap_hook_call @332 + ap_find_list_item @320 + ap_MD5Encode @321 + ap_validate_password @322 + ap_size_list_item @323 + ap_get_list_item @324 + ap_scoreboard_fname @325 + ap_pid_fname @326 + ap_excess_requests_per_child @327 + ap_threads_per_child @328 + ap_max_requests_per_child @329 + ap_daemons_to_start @330 + ap_daemons_min_free @331 + ap_daemons_max_free @332 + ap_daemons_limit @333 + ap_user_name @334 + ap_user_id @335 + ap_group_id @336 + ap_standalone @337 + ap_server_confname @338 + ap_sub_req_method_uri @339 + ap_regerror @341 + ap_regexec @342 + ap_field_noparam @343 + ap_pbase64decode @344 + ap_pbase64encode @345 + ap_base64encode @346 + ap_base64encode_binary @347 + ap_base64encode_len @348 + ap_base64decode @349 + ap_base64decode_binary @350 + ap_base64decode_len @351 + ap_SHA1Init @352 + ap_SHA1Update_binary @353 + ap_SHA1Update @354 + ap_SHA1Final @355 + ap_sha1_base64 @356 + ap_add_config_define @357 + ap_global_ctx @358 + ap_ctx_new @359 + ap_ctx_get @360 + ap_ctx_set @361 + ap_hook_init @362 + ap_hook_kill @363 + ap_hook_configure @364 + ap_hook_register_I @365 + ap_hook_unregister_I @366 + ap_hook_status @367 + ap_hook_use @368 + ap_hook_call @369 diff --git a/usr.sbin/httpd/src/ApacheCore.dsp b/usr.sbin/httpd/src/ApacheCore.dsp index 21e5880f56e..511e5feefe1 100644 --- a/usr.sbin/httpd/src/ApacheCore.dsp +++ b/usr.sbin/httpd/src/ApacheCore.dsp @@ -44,7 +44,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I ".\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 os\win32\ApacheOSR\ApacheOS.lib regex\release\regex.lib ap\Release\ap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 os\win32\ApacheOSR\ApacheOS.lib regex\release\regex.lib ap\Release\ap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /machine:I386 !ELSEIF "$(CFG)" == "ApacheCore - Win32 Debug" @@ -70,7 +70,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I ".\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I ".\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /FR /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -80,7 +80,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 os\win32\ApacheOSD\ApacheOS.lib regex\debug\regex.lib ap\Debug\ap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 os\win32\ApacheOSD\ApacheOS.lib regex\debug\regex.lib ap\Debug\ap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 # SUBTRACT LINK32 /map !ENDIF @@ -142,10 +142,6 @@ SOURCE=.\main\http_vhost.c # End Source File # Begin Source File -SOURCE=.\main\md5c.c -# End Source File -# Begin Source File - SOURCE=.\modules\standard\mod_access.c # End Source File # Begin Source File diff --git a/usr.sbin/httpd/src/ApacheCore.mak b/usr.sbin/httpd/src/ApacheCore.mak index e253234629d..8b012c51223 100644 --- a/usr.sbin/httpd/src/ApacheCore.mak +++ b/usr.sbin/httpd/src/ApacheCore.mak @@ -28,6 +28,10 @@ NULL= NULL=nul !ENDIF +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + !IF "$(CFG)" == "ApacheCore - Win32 Release" OUTDIR=.\CoreR @@ -58,7 +62,6 @@ CLEAN : -@erase "$(INTDIR)\http_protocol.obj" -@erase "$(INTDIR)\http_request.obj" -@erase "$(INTDIR)\http_vhost.obj" - -@erase "$(INTDIR)\md5c.obj" -@erase "$(INTDIR)\mod_access.obj" -@erase "$(INTDIR)\mod_actions.obj" -@erase "$(INTDIR)\mod_alias.obj" @@ -90,8 +93,6 @@ CLEAN : -@erase "$(INTDIR)\util_uri.obj" -@erase "$(INTDIR)\util_win32.obj" -@erase "$(INTDIR)\vc50.idb" - -@erase "$(INTDIR)\ApacheCore.pch" - -@erase "$(OUTDIR)\ApacheCore.pch" -@erase "$(OUTDIR)\ApacheCore.dll" -@erase "$(OUTDIR)\ApacheCore.exp" -@erase "$(OUTDIR)\ApacheCore.lib" @@ -99,46 +100,12 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP=cl.exe -CPP_PROJ=/nologo /MD /W3 /GX /O2 /I ".\include" /D "WIN32" /D "NDEBUG" /D\ - "_WINDOWS" /Fp"$(INTDIR)\ApacheCore.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\"\ - /FD /c +CPP_PROJ=/nologo /MD /W3 /GX /O2 /I ".\include" /D "NDEBUG" /D "WIN32" /D\ + "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /Fp"$(INTDIR)\ApacheCore.pch" /YX\ + /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\CoreR/ CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\ApacheCore.bsc" BSC32_SBRS= \ @@ -146,7 +113,7 @@ BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=os\win32\ApacheOSR\ApacheOS.lib regex\release\regex.lib\ ap\Release\ap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll\ + advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll\ /incremental:no /pdb:"$(OUTDIR)\ApacheCore.pdb" /machine:I386\ /def:".\ApacheCore.def" /out:"$(OUTDIR)\ApacheCore.dll"\ /implib:"$(OUTDIR)\ApacheCore.lib" @@ -164,7 +131,6 @@ LINK32_OBJS= \ "$(INTDIR)\http_protocol.obj" \ "$(INTDIR)\http_request.obj" \ "$(INTDIR)\http_vhost.obj" \ - "$(INTDIR)\md5c.obj" \ "$(INTDIR)\mod_access.obj" \ "$(INTDIR)\mod_actions.obj" \ "$(INTDIR)\mod_alias.obj" \ @@ -242,8 +208,6 @@ CLEAN : -@erase "$(INTDIR)\http_request.sbr" -@erase "$(INTDIR)\http_vhost.obj" -@erase "$(INTDIR)\http_vhost.sbr" - -@erase "$(INTDIR)\md5c.obj" - -@erase "$(INTDIR)\md5c.sbr" -@erase "$(INTDIR)\mod_access.obj" -@erase "$(INTDIR)\mod_access.sbr" -@erase "$(INTDIR)\mod_actions.obj" @@ -306,8 +270,6 @@ CLEAN : -@erase "$(INTDIR)\util_win32.sbr" -@erase "$(INTDIR)\vc50.idb" -@erase "$(INTDIR)\vc50.pdb" - -@erase "$(INTDIR)\ApacheCore.pch" - -@erase "$(OUTDIR)\ApacheCore.pch" -@erase "$(OUTDIR)\ApacheCore.bsc" -@erase "$(OUTDIR)\ApacheCore.dll" -@erase "$(OUTDIR)\ApacheCore.exp" @@ -318,46 +280,12 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP=cl.exe -CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I ".\include" /D "WIN32" /D "_DEBUG"\ - /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\ApacheCore.pch" /YX\ - /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I ".\include" /D "_DEBUG" /D "WIN32"\ + /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /FR"$(INTDIR)\\"\ + /Fp"$(INTDIR)\ApacheCore.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\CoreD/ CPP_SBRS=.\CoreD/ - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\ApacheCore.bsc" BSC32_SBRS= \ @@ -372,7 +300,6 @@ BSC32_SBRS= \ "$(INTDIR)\http_protocol.sbr" \ "$(INTDIR)\http_request.sbr" \ "$(INTDIR)\http_vhost.sbr" \ - "$(INTDIR)\md5c.sbr" \ "$(INTDIR)\mod_access.sbr" \ "$(INTDIR)\mod_actions.sbr" \ "$(INTDIR)\mod_alias.sbr" \ @@ -412,7 +339,7 @@ BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=os\win32\ApacheOSD\ApacheOS.lib regex\debug\regex.lib\ ap\Debug\ap.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll\ + advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll\ /incremental:yes /pdb:"$(OUTDIR)\ApacheCore.pdb" /debug /machine:I386\ /def:".\ApacheCore.def" /out:"$(OUTDIR)\ApacheCore.dll"\ /implib:"$(OUTDIR)\ApacheCore.lib" @@ -430,7 +357,6 @@ LINK32_OBJS= \ "$(INTDIR)\http_protocol.obj" \ "$(INTDIR)\http_request.obj" \ "$(INTDIR)\http_vhost.obj" \ - "$(INTDIR)\md5c.obj" \ "$(INTDIR)\mod_access.obj" \ "$(INTDIR)\mod_actions.obj" \ "$(INTDIR)\mod_alias.obj" \ @@ -469,6 +395,36 @@ LINK32_OBJS= \ !ENDIF +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + !IF "$(CFG)" == "ApacheCore - Win32 Release" || "$(CFG)" ==\ "ApacheCore - Win32 Debug" @@ -481,6 +437,7 @@ DEP_CPP_ALLOC=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -502,6 +459,7 @@ DEP_CPP_ALLOC=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -510,14 +468,6 @@ DEP_CPP_ALLOC=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_ALLOC=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\alloc.obj" "$(INTDIR)\alloc.sbr" : $(SOURCE) $(DEP_CPP_ALLOC)\ @@ -536,6 +486,7 @@ DEP_CPP_BUFF_=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -557,6 +508,7 @@ DEP_CPP_BUFF_=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -565,14 +517,6 @@ DEP_CPP_BUFF_=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_BUFF_=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\buff.obj" "$(INTDIR)\buff.sbr" : $(SOURCE) $(DEP_CPP_BUFF_)\ @@ -591,6 +535,7 @@ DEP_CPP_BUILD=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\httpd.h"\ @@ -609,20 +554,13 @@ DEP_CPP_BUILD=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\httpd.h"\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_BUILD=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\buildmark.obj" "$(INTDIR)\buildmark.sbr" : $(SOURCE)\ @@ -658,6 +596,7 @@ DEP_CPP_HTTP_=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\explain.h"\ ".\include\hsregex.h"\ @@ -684,6 +623,7 @@ DEP_CPP_HTTP_=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\explain.h"\ ".\include\hsregex.h"\ @@ -697,14 +637,6 @@ DEP_CPP_HTTP_=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_HTTP_=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\http_config.obj" "$(INTDIR)\http_config.sbr" : $(SOURCE)\ @@ -724,6 +656,7 @@ DEP_CPP_HTTP_C=\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ ".\include\ap_md5.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\fnmatch.h"\ ".\include\hsregex.h"\ @@ -756,6 +689,7 @@ DEP_CPP_HTTP_C=\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ ".\include\ap_md5.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\fnmatch.h"\ ".\include\hsregex.h"\ @@ -774,14 +708,6 @@ DEP_CPP_HTTP_C=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_HTTP_C=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\http_core.obj" "$(INTDIR)\http_core.sbr" : $(SOURCE)\ @@ -800,8 +726,10 @@ DEP_CPP_HTTP_L=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ + ".\include\http_conf_globals.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ ".\include\http_log.h"\ @@ -823,8 +751,10 @@ DEP_CPP_HTTP_L=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ + ".\include\http_conf_globals.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ ".\include\http_log.h"\ @@ -833,14 +763,6 @@ DEP_CPP_HTTP_L=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_HTTP_L=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\http_log.obj" "$(INTDIR)\http_log.sbr" : $(SOURCE) $(DEP_CPP_HTTP_L)\ @@ -859,6 +781,7 @@ DEP_CPP_HTTP_M=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\explain.h"\ ".\include\hsregex.h"\ @@ -893,6 +816,7 @@ DEP_CPP_HTTP_M=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\explain.h"\ ".\include\hsregex.h"\ @@ -914,14 +838,6 @@ DEP_CPP_HTTP_M=\ ".\os\win32\readdir.h"\ ".\os\win32\registry.h"\ ".\os\win32\service.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_HTTP_M=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\http_main.obj" "$(INTDIR)\http_main.sbr" : $(SOURCE)\ @@ -940,6 +856,7 @@ DEP_CPP_HTTP_P=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -968,6 +885,7 @@ DEP_CPP_HTTP_P=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -983,14 +901,6 @@ DEP_CPP_HTTP_P=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_HTTP_P=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\http_protocol.obj" "$(INTDIR)\http_protocol.sbr" : $(SOURCE)\ @@ -1009,9 +919,11 @@ DEP_CPP_HTTP_R=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\fnmatch.h"\ ".\include\hsregex.h"\ + ".\include\http_conf_globals.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ ".\include\http_log.h"\ @@ -1036,9 +948,11 @@ DEP_CPP_HTTP_R=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\fnmatch.h"\ ".\include\hsregex.h"\ + ".\include\http_conf_globals.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ ".\include\http_log.h"\ @@ -1050,14 +964,6 @@ DEP_CPP_HTTP_R=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_HTTP_R=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\http_request.obj" "$(INTDIR)\http_request.sbr" : $(SOURCE)\ @@ -1076,6 +982,7 @@ DEP_CPP_HTTP_V=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -1100,6 +1007,7 @@ DEP_CPP_HTTP_V=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -1111,14 +1019,6 @@ DEP_CPP_HTTP_V=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_HTTP_V=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\http_vhost.obj" "$(INTDIR)\http_vhost.sbr" : $(SOURCE)\ @@ -1128,46 +1028,6 @@ NODEP_CPP_HTTP_V=\ !ENDIF -SOURCE=.\main\md5c.c - -!IF "$(CFG)" == "ApacheCore - Win32 Release" - -DEP_CPP_MD5C_=\ - ".\include\ap_config.h"\ - ".\include\ap_ctype.h"\ - ".\include\ap_md5.h"\ - ".\include\hsregex.h"\ - ".\os\win32\os.h"\ - - -"$(INTDIR)\md5c.obj" : $(SOURCE) $(DEP_CPP_MD5C_) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ELSEIF "$(CFG)" == "ApacheCore - Win32 Debug" - -DEP_CPP_MD5C_=\ - ".\include\ap_config.h"\ - ".\include\ap_ctype.h"\ - ".\include\ap_md5.h"\ - ".\include\hsregex.h"\ - ".\os\win32\os.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MD5C_=\ - ".\include\ap_config_auto.h"\ - ".\include\os.h"\ - ".\main\ebcdic.h"\ - - -"$(INTDIR)\md5c.obj" "$(INTDIR)\md5c.sbr" : $(SOURCE) $(DEP_CPP_MD5C_)\ - "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -!ENDIF - SOURCE=.\modules\standard\mod_access.c !IF "$(CFG)" == "ApacheCore - Win32 Release" @@ -1177,6 +1037,7 @@ DEP_CPP_MOD_A=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1200,6 +1061,7 @@ DEP_CPP_MOD_A=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1210,14 +1072,6 @@ DEP_CPP_MOD_A=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_A=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_access.obj" "$(INTDIR)\mod_access.sbr" : $(SOURCE)\ @@ -1236,6 +1090,7 @@ DEP_CPP_MOD_AC=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1262,6 +1117,7 @@ DEP_CPP_MOD_AC=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1275,14 +1131,6 @@ DEP_CPP_MOD_AC=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_AC=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_actions.obj" "$(INTDIR)\mod_actions.sbr" : $(SOURCE)\ @@ -1301,6 +1149,7 @@ DEP_CPP_MOD_AL=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1321,6 +1170,7 @@ DEP_CPP_MOD_AL=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1328,14 +1178,6 @@ DEP_CPP_MOD_AL=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_AL=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_alias.obj" "$(INTDIR)\mod_alias.sbr" : $(SOURCE)\ @@ -1354,6 +1196,7 @@ DEP_CPP_MOD_AS=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1379,6 +1222,7 @@ DEP_CPP_MOD_AS=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1391,14 +1235,6 @@ DEP_CPP_MOD_AS=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_AS=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_asis.obj" "$(INTDIR)\mod_asis.sbr" : $(SOURCE) $(DEP_CPP_MOD_AS)\ @@ -1417,6 +1253,8 @@ DEP_CPP_MOD_AU=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_md5.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1440,6 +1278,8 @@ DEP_CPP_MOD_AU=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_md5.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1450,14 +1290,6 @@ DEP_CPP_MOD_AU=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_AU=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_auth.obj" "$(INTDIR)\mod_auth.sbr" : $(SOURCE) $(DEP_CPP_MOD_AU)\ @@ -1476,7 +1308,9 @@ DEP_CPP_MOD_AUT=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ + ".\include\fnmatch.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ @@ -1502,7 +1336,9 @@ DEP_CPP_MOD_AUT=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ + ".\include\fnmatch.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ @@ -1515,14 +1351,6 @@ DEP_CPP_MOD_AUT=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_AUT=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_autoindex.obj" "$(INTDIR)\mod_autoindex.sbr" : $(SOURCE)\ @@ -1541,6 +1369,7 @@ DEP_CPP_MOD_C=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -1568,6 +1397,7 @@ DEP_CPP_MOD_C=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -1582,14 +1412,6 @@ DEP_CPP_MOD_C=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_C=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_cgi.obj" "$(INTDIR)\mod_cgi.sbr" : $(SOURCE) $(DEP_CPP_MOD_C)\ @@ -1608,6 +1430,7 @@ DEP_CPP_MOD_D=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1634,6 +1457,7 @@ DEP_CPP_MOD_D=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1647,14 +1471,6 @@ DEP_CPP_MOD_D=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_D=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_dir.obj" "$(INTDIR)\mod_dir.sbr" : $(SOURCE) $(DEP_CPP_MOD_D)\ @@ -1673,6 +1489,7 @@ DEP_CPP_MOD_E=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1693,6 +1510,7 @@ DEP_CPP_MOD_E=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1700,14 +1518,6 @@ DEP_CPP_MOD_E=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_E=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_env.obj" "$(INTDIR)\mod_env.sbr" : $(SOURCE) $(DEP_CPP_MOD_E)\ @@ -1726,6 +1536,7 @@ DEP_CPP_MOD_I=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1752,6 +1563,7 @@ DEP_CPP_MOD_I=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1765,14 +1577,6 @@ DEP_CPP_MOD_I=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_I=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_imap.obj" "$(INTDIR)\mod_imap.sbr" : $(SOURCE) $(DEP_CPP_MOD_I)\ @@ -1791,6 +1595,7 @@ DEP_CPP_MOD_IN=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1817,6 +1622,7 @@ DEP_CPP_MOD_IN=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1830,16 +1636,6 @@ DEP_CPP_MOD_IN=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_IN=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ - ".\modules\standard\config.h"\ - ".\modules\standard\modules\perl\mod_perl.h"\ "$(INTDIR)\mod_include.obj" "$(INTDIR)\mod_include.sbr" : $(SOURCE)\ @@ -1858,6 +1654,7 @@ DEP_CPP_MOD_IS=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1883,6 +1680,7 @@ DEP_CPP_MOD_IS=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1895,13 +1693,6 @@ DEP_CPP_MOD_IS=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_IS=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_isapi.obj" "$(INTDIR)\mod_isapi.sbr" : $(SOURCE)\ @@ -1920,6 +1711,7 @@ DEP_CPP_MOD_L=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1942,6 +1734,7 @@ DEP_CPP_MOD_L=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1951,14 +1744,6 @@ DEP_CPP_MOD_L=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_L=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_log_config.obj" "$(INTDIR)\mod_log_config.sbr" : $(SOURCE)\ @@ -1977,6 +1762,7 @@ DEP_CPP_MOD_M=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -1998,6 +1784,7 @@ DEP_CPP_MOD_M=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2006,14 +1793,6 @@ DEP_CPP_MOD_M=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_M=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_mime.obj" "$(INTDIR)\mod_mime.sbr" : $(SOURCE) $(DEP_CPP_MOD_M)\ @@ -2032,11 +1811,13 @@ DEP_CPP_MOD_N=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ ".\include\http_log.h"\ + ".\include\http_protocol.h"\ ".\include\http_request.h"\ ".\include\httpd.h"\ ".\include\util_script.h"\ @@ -2056,25 +1837,19 @@ DEP_CPP_MOD_N=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ ".\include\http_core.h"\ ".\include\http_log.h"\ + ".\include\http_protocol.h"\ ".\include\http_request.h"\ ".\include\httpd.h"\ ".\include\util_script.h"\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_N=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_negotiation.obj" "$(INTDIR)\mod_negotiation.sbr" : $(SOURCE)\ @@ -2093,6 +1868,7 @@ DEP_CPP_MOD_S=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2115,6 +1891,7 @@ DEP_CPP_MOD_S=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2124,14 +1901,6 @@ DEP_CPP_MOD_S=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_S=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_setenvif.obj" "$(INTDIR)\mod_setenvif.sbr" : $(SOURCE)\ @@ -2150,6 +1919,7 @@ DEP_CPP_MOD_SO=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2171,6 +1941,7 @@ DEP_CPP_MOD_SO=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2179,14 +1950,6 @@ DEP_CPP_MOD_SO=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_SO=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_so.obj" "$(INTDIR)\mod_so.sbr" : $(SOURCE) $(DEP_CPP_MOD_SO)\ @@ -2205,6 +1968,7 @@ DEP_CPP_MOD_U=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2225,6 +1989,7 @@ DEP_CPP_MOD_U=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2232,14 +1997,6 @@ DEP_CPP_MOD_U=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MOD_U=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\mod_userdir.obj" "$(INTDIR)\mod_userdir.sbr" : $(SOURCE)\ @@ -2258,6 +2015,7 @@ DEP_CPP_MODUL=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2278,6 +2036,7 @@ DEP_CPP_MODUL=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_config.h"\ @@ -2285,13 +2044,6 @@ DEP_CPP_MODUL=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MODUL=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\sfio.h"\ "$(INTDIR)\modules.obj" "$(INTDIR)\modules.sbr" : $(SOURCE) $(DEP_CPP_MODUL)\ @@ -2308,6 +2060,7 @@ SOURCE=.\os\win32\multithread.c DEP_CPP_MULTI=\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\hsregex.h"\ ".\include\multithread.h"\ ".\os\win32\os.h"\ @@ -2322,14 +2075,10 @@ DEP_CPP_MULTI=\ DEP_CPP_MULTI=\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\hsregex.h"\ ".\include\multithread.h"\ ".\os\win32\os.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_MULTI=\ - ".\include\ap_config_auto.h"\ "$(INTDIR)\multithread.obj" "$(INTDIR)\multithread.sbr" : $(SOURCE)\ @@ -2370,6 +2119,7 @@ DEP_CPP_REGIS=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -2390,6 +2140,7 @@ DEP_CPP_REGIS=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -2397,13 +2148,6 @@ DEP_CPP_REGIS=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_REGIS=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\sfio.h"\ "$(INTDIR)\registry.obj" "$(INTDIR)\registry.sbr" : $(SOURCE) $(DEP_CPP_REGIS)\ @@ -2422,6 +2166,7 @@ DEP_CPP_RFC14=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -2444,6 +2189,7 @@ DEP_CPP_RFC14=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -2453,14 +2199,6 @@ DEP_CPP_RFC14=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_RFC14=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\rfc1413.obj" "$(INTDIR)\rfc1413.sbr" : $(SOURCE) $(DEP_CPP_RFC14)\ @@ -2479,6 +2217,7 @@ DEP_CPP_SERVI=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2504,6 +2243,7 @@ DEP_CPP_SERVI=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2516,13 +2256,6 @@ DEP_CPP_SERVI=\ ".\os\win32\readdir.h"\ ".\os\win32\registry.h"\ ".\os\win32\service.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_SERVI=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\sfio.h"\ "$(INTDIR)\service.obj" "$(INTDIR)\service.sbr" : $(SOURCE) $(DEP_CPP_SERVI)\ @@ -2541,6 +2274,7 @@ DEP_CPP_UTIL_=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2563,6 +2297,7 @@ DEP_CPP_UTIL_=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2572,14 +2307,6 @@ DEP_CPP_UTIL_=\ ".\main\test_char.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_UTIL_=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\util.obj" "$(INTDIR)\util.sbr" : $(SOURCE) $(DEP_CPP_UTIL_)\ @@ -2590,36 +2317,24 @@ NODEP_CPP_UTIL_=\ !ENDIF SOURCE=.\main\util_date.c - -!IF "$(CFG)" == "ApacheCore - Win32 Release" - DEP_CPP_UTIL_D=\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\hsregex.h"\ ".\include\util_date.h"\ ".\os\win32\os.h"\ +!IF "$(CFG)" == "ApacheCore - Win32 Release" + + "$(INTDIR)\util_date.obj" : $(SOURCE) $(DEP_CPP_UTIL_D) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ELSEIF "$(CFG)" == "ApacheCore - Win32 Debug" -DEP_CPP_UTIL_D=\ - ".\include\ap_config.h"\ - ".\include\ap_ctype.h"\ - ".\include\hsregex.h"\ - ".\include\util_date.h"\ - ".\os\win32\os.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_UTIL_D=\ - ".\include\ap_config_auto.h"\ - ".\include\os.h"\ - "$(INTDIR)\util_date.obj" "$(INTDIR)\util_date.sbr" : $(SOURCE)\ $(DEP_CPP_UTIL_D) "$(INTDIR)" @@ -2638,6 +2353,7 @@ DEP_CPP_UTIL_M=\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ ".\include\ap_md5.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\httpd.h"\ @@ -2659,6 +2375,7 @@ DEP_CPP_UTIL_M=\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ ".\include\ap_md5.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\httpd.h"\ @@ -2666,14 +2383,6 @@ DEP_CPP_UTIL_M=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_UTIL_M=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\util_md5.obj" "$(INTDIR)\util_md5.sbr" : $(SOURCE) $(DEP_CPP_UTIL_M)\ @@ -2692,6 +2401,7 @@ DEP_CPP_UTIL_S=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2720,6 +2430,7 @@ DEP_CPP_UTIL_S=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2735,14 +2446,6 @@ DEP_CPP_UTIL_S=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_UTIL_S=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\util_script.obj" "$(INTDIR)\util_script.sbr" : $(SOURCE)\ @@ -2761,6 +2464,7 @@ DEP_CPP_UTIL_U=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2783,6 +2487,7 @@ DEP_CPP_UTIL_U=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_conf_globals.h"\ @@ -2792,14 +2497,6 @@ DEP_CPP_UTIL_U=\ ".\main\uri_delims.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_UTIL_U=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\os.h"\ - ".\include\sfio.h"\ "$(INTDIR)\util_uri.obj" "$(INTDIR)\util_uri.sbr" : $(SOURCE) $(DEP_CPP_UTIL_U)\ @@ -2818,6 +2515,7 @@ DEP_CPP_UTIL_W=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -2838,6 +2536,7 @@ DEP_CPP_UTIL_W=\ ".\include\ap.h"\ ".\include\ap_config.h"\ ".\include\ap_ctype.h"\ + ".\include\ap_mmn.h"\ ".\include\buff.h"\ ".\include\hsregex.h"\ ".\include\http_log.h"\ @@ -2845,13 +2544,6 @@ DEP_CPP_UTIL_W=\ ".\include\util_uri.h"\ ".\os\win32\os.h"\ ".\os\win32\readdir.h"\ - {$(INCLUDE)}"sys\stat.h"\ - {$(INCLUDE)}"sys\types.h"\ - -NODEP_CPP_UTIL_W=\ - ".\include\ap_config_auto.h"\ - ".\include\ebcdic.h"\ - ".\include\sfio.h"\ "$(INTDIR)\util_win32.obj" "$(INTDIR)\util_win32.sbr" : $(SOURCE)\ diff --git a/usr.sbin/httpd/src/CHANGES b/usr.sbin/httpd/src/CHANGES index 41833f59eac..1c95e220c5a 100644 --- a/usr.sbin/httpd/src/CHANGES +++ b/usr.sbin/httpd/src/CHANGES @@ -1,3 +1,877 @@ +Changes with Apache 1.3.9 + + *) Remove bogus error message when a redirect doesn't set Location. + Instead, use an empty string to avoid coredump if the error message + was supposed to include a location. [Roy Fielding] + + *) Don't allow configure to include mod_auth_digest unless it is + explicitly requested, even if the user asked for all modules. + [Roy Fielding] + + *) Translate module names to dll names for OS/2 so that they are no more + than 8 characters long and have an extension of "dll" instead of "so". + [Brian Havard] + + *) Print out pointer to Rule DEV_RANDOM when truerand lib not found. + Fix test-compile check to check for randbyte instead of trand32. + Use ap_base64encode_binary/decode instead of copy in mod_auth_digest.c + and tweak to make Amaya happier. [Ronald Tschalär] + + *) Ensure that the installed expat include files are world readable, + just like the other header files. [Martin Kraemer] + + *) Fixed generated AddModule adjustments in APACI's `configure' script + in order to allow (new) modules like mod_vhost_alias to be handled + correctly (which was touched by the adjustments for mod_alias). + [Ralf S. Engelschall] + + *) For binary builds, add -R flag to apachectl to work around the lack of + an absolute path to the ./libexec directory where the libhttp.ep file + is needed for SHARED_CORE architectures. [Randy Terbush] + + *) WIN32: Create the CGI script process as DETACHED. This may solve the + problem observed by some Win95/98 users where they get CGI script + output sent to the console. [Bill Stoddard] + + *) Fix (re)naming in the uuencode/decode section. The ap/ap_ + routines are now called ap_base64* and are 'plain' (i.e., no + pool access or anything clever). Inside util.c the routines acting + like pstrdup are called ap_pbase64encode() and ap_pbase64decode(). + The oddly named ap_uuencode(), ap_uudecode() are kept around for + now but deprecated. [dirkx] + + *) Clean up the base64 and SHA1 additions and make sure they are + represented in the ApacheCore.def, ApacheCoreOS2.def, and httpd.exp + files. [Roy Fielding] + + *) WIN32: Migrate to InstallShield 5.5 and provide a bit more error + checking. Allow compiling on VS 6.0. [Randy Terbush] + + *) Fixed assumption of absolute paths in binbuild.sh. [Tony Finch] + + *) Use TestCompile to search for the truerand library (rather than blindly + assuming its existence). If it is not found, complain (but do not + exit - yet). [Martin Kraemer] + + *) We forgot to add the new exported function names to + src/support/httpd.exp. [Bill Stoddard, Randy Terbush] + + *) Add description of -T command-line option to usage(). + [Ralf S. Engelschall] + + *) For "some" platforms (notably, EBCDIC based ones), libos needs to be + searched only AFTER libap has been searched, because libap needs + some symbols from libos. [Martin Kraemer] + + *) Fix conflict with original mod_digest related to the symbol of the + module dispatch list (which has to be unique for DSO and follow the + usual conventions for the installation procedure). + [Ralf S. Engelschall] + + *) Add a dbm-library check for the "usual places" (-ldbm, -lndbm, -ldb) + for other platforms as well. [Martin Kraemer] + + *) Make ap_sha1.c compile for EBCDIC platforms: replace remaining LONG + types by AP_LONG and replace reference to renamed variable 'ubuf' + by 'buffer'. [Martin Kraemer] + +Changes with Apache 1.3.8 [not released] + + *) Flush the output buffer immediately after sending an error or redirect + response, since the result may be needed by the client to abort a + long data transfer or restart a series of pipelined requests. + [Tom Vaughan <tvaughan@aventail.com>, Roy Fielding] + + *) PORT: Improved compilation and DSO support on Sequent DYNIX/ptx. + [Ian Turner <iant@sequent.com>] PR#4735 + + *) Local struct mmap in http_core.c conflicted with system structure + name on DYNIX -- changed to mmap_rec. [Roy Fielding] PR#4735 + + *) Added updated mod_digest as modules/experimental/mod_auth_digest. + [Ronald Tschalär <ronald@innovation.ch>] + + *) Fix a memory leak where the module counts were getting messed + up across restarts. [David Harris <dharris@drh.net>] + + *) CIDR addresses such as a.b.c.d/24 where d != 0 weren't handled + properly in mod_access. + ["Paul J. Reder" <rederpj@raleigh.ibm.com>] PR#4770 + + *) RewriteLock/RewriteMap didn't work properly with virtual hosts. + [Dmitry Khrustalev <dima@bog.msu.su>] PR#3874 + + *) PORT: Support for compaq/tandem/com. + [Michael Ottati <michael.ottati@compaq.com>, dirkx] + + *) Added SHA1 password encryption support to easy migration from + Netscape servers. See support/SHA1 for more information. + Caused the separation of ap_md5.c into md5, sha1 and a general + ap_checkpass.c with just a validate_passwd routine. Added a + couple of flags to support/htpasswd. Some reuse of the to64() + function; hence renamed to ap_to64(). + [Dirk-Willem van Gulik, Clinton Wong <clintdw@netcom.com>] + + *) Change for EBCDIC platforms (TPF and BS2000) to correctly deal + with ASCII/EBCDIC conversions in "ident" query. + [David McCreedy <McCreedy@us.ibm.com>] + + *) Get rid of redefinition warning on MAC_OS_X_SERVER platform. + Change "Power Macintosh" to Power* so if uname prints "Power Book" + we're still happy on Rhapsody platforms. [Wilfredo Sanchez] + + *) Fix SIGSEGV on some systems because the Vary fix below included + a call to table_do with a variable argument list that was not + NULL terminated. Replaced with better implementation. [Roy Fielding] + +Changes with Apache 1.3.7 [not released] + + *) The "Vary" response header field is now sanitised right before + the header is sent back to the client. Multiple "Vary" fields + are combined, and duplicate tokens (e.g., "Vary: host, host" or + "Vary: host, negotiate, host, accept-language") are reduced to + single instances. This is a better solution than the force-no-vary + one (which is still valid for clients that can't cope with Vary + at all). PR#3118 [Dean Gaudet, Roy Fielding, Ken Coar] + + *) Portability changes for BeOS. [David Reid abb37@dial.pipex.com] + + *) Link DSO's with "gcc -shared" instead of "ld -Bshareable" at + least on Linux and FreeBSD for now. + [Rasmus Lerdorf] + + *) Win32: More apache -k restart work. Restarts are now honored + immediately and connections in the listen queue are -not- lost. + This is made possible by the use of the WSADuplicateSocket() + call. The listeners are opened in the parent, duplicated, then + the duplicates are passed to the child. The original listen sockets + are not closed by the parent across a restart, thus the listen queue + is preserved. + [Bill Stoddard <stoddard@raleigh.ibm.com>] + + *) Fix handling of case when a client has sent "Expect: 100-continue" + and we are going to respond with an error, but get stuck waiting to + discard the body in the pointless hope of preserving the connection. + [Roy Fielding, Joe Orton <jeo101@york.ac.uk>] PR#4499, PR#3806 + + *) Fix 'configure' to work correctly with SysV-based versions of + 'tr' (consistent with Configure's use as well). [Jim Jagielski] + + *) apxs: Add "-S var=val" option which allows for override of CFG_* + built-in values. Add "-e" option which works like -i but doesn't + install the DSO; useful for editing httpd.conf with apxs. Fix + editing code so that multiple invocations of apxs -a will not + create duplicate LoadModule/AddModule entries; apxs can now be + used to re- enable/disable a module. [Wilfredo Sanchez] + + *) Win32: Update the server to use Winsock 2. Specifically, link with + ws2_32.lib rather than wsock32.lib. This gives us access to + WSADuplcateSocket() in addition to some other enhanced comm APIs. + Win 95 users may need to update their TCP/IP stack to pick up + Winsock 2. (See http://www.microsoft.com/windows95/downloads/) + [Bill Stoddard stoddard@raleigh.ibm.com] + + *) Win32: Redirect CGI script stderr (script debug info) into the + error.log when CGI scripts fail. This makes Apache on Win32 + behave more like Unix. + [Bill Stoddard stoddard@raleigh.ibm.com] + + *) Fixed `httpd' usage display: -D was missing. + [Ralf S. Engelschall] PR#4614 + + *) Fix `make r' test procedure in src/regex/: ap_isprint was not found. + [Ralf S. Engelschall] PR#4561, PR#4562 + + *) OS/2: Fix problem with accept lock semaphores where server would die with + "OS2SEM: Error 105 getting accept lock. Exiting!" + [Brian Havard] PR#4505 + + *) Add DSO support for DGUX 4.x using gcc. Tested on x86 platforms. + [Randy Terbush <randy@covalent.net>] + + *) Add the new mass-vhost module (mod_vhost_alias.c) developed and + used by Demon Internet, Ltd. [Tony Finch <fanf@demon.net>] + + *) Better GCC detection for DSO flags under Solaris 2 where the `cc' + command potentially _is_ GCC. [Ralf S. Engelschall] + + *) Fix apxs build issues on AIX + [Rasmus Lerdorf <rasmus@raleigh.ibm.com>] + + *) DocumentRoot Checking: Under previous versions, when Apache + first started up, it used to do a stat of each DocumentRoot to + see if it existed and was a directory. If not, then an error + message was printed. THIS HAS BEEN DISABLED. If DocumentRoot + does not exist, you will get error messages in error_log. If + the '-t' command line option is used (to check the configuration) + the check of DocumentRoot IS performed. An additional command + line option, '-T', has been added if you want to avoid the + DocumentRoot check even when checking the configuration. + [Jim Jagielski] + + *) Win32: The query switch "apache -S" didn't exit after showing the + vhost settings. That was inconsistent with the other query functions. + [Bill Stoddard - Fixed by Martin on Unix in 1.3.4] + + *) Win32: Changed behaviour of apache -k restart. + Previously, the server would drain all connections in the stack's + listen queue before honoring the restart. On a busy server, this + could take hours. Now, a restart is honored almost immediately. + All connections in Apache's queues are handled but connections in + the stack's listen queue are discarded. Restart triggered by + MaxRequestPerChild is unchanged. + [Bill Stoddard <stoddard@raleigh.ibm.com>] + + *) Win32: Eliminated unnecessary call to wait_for_multiple_objects in + the accept loop. Good for a 5% performance boost. Cleaned up + parent/child process management code. + [Bill Stoddard <stoddard@raleigh.ibm.com>] + + *) Added ceiling on file size for memory mapped files. + [John Giannandrea <jg@meer.net>] PR#4122 + + *) Fix ndbm.h include problems with brain-dead glibc >= 2.1 which + has ndbm.h in a non-standard db1/ subdir. PR#4431, PR#4528 + [Henri Gomez <gomez@slib.fr>, Ralf S. Engelschall] + + *) Determine AP_BYTE_ORDER for ap_config_auto.h and already + use this at least for Expat. [Ralf S. Engelschall] + + *) Allow .module files to specify libraries with Lib:. + [Ben Laurie] + + *) Allow SetEnvIf[NoCase] to test environment variables as well + as header fields and request attributes. [Ken Coar] + + *) Fix mod_autoindex's handling of ScanHTMLTitles when file + content-types are "text/html;parameters". PR#4524 [Ken Coar] + + *) Remove "mxb" support from mod_negotiation -- it was a draft feature + never accepted into any standard, and it opens up certain DoS + attacks. [Koen Holtman <Koen.Holtman@cern.ch>] + + *) TestCompile updated. We can now run programs and output the + results during the Configure process. [ Jim Jagielski] + + *) The source is now quad (long long) aware as needed. Specifically, + the Configure process determines the correct size of off_t and + *void. When the OS/platform/compiler supports quads, ap_snprintf() + provides for the 'q' format qualifier (if quads are not available, + 'q' is silently "demoted" to long). [Jim Jagielski] + + *) When the username or password fed to htpasswd is too long, include the + size limit in the error message. Also report illegal characters + (currently only ':') in the username. Add the size restrictions + to the man page. [Ken Coar] + + *) Fixed the configure --without-support option so it doesn't result in + an infinite loop. [Marc Slemko] + + *) Piped error logs could cause a segfault if an error occured + during configuration after a restart. + [Aidan Cully <aidan@panix.com>] PR#4456 + + *) If a "Location" field was stored in r->err_headers_out rather + than r->headers_out, redirect processing wouldn't find it and + the server would core dump on ap_escape_html(NULL). Check both + tables and raise HTTP_INTERNAL_SERVER_ERROR with a log message + if Location isn't set. [Doug MacEachern, Ken Coar] + + *) Add RULE_EXPAT, the src/lib/ directory structure, and a modified copy + of the Expat 1.0.2 distribution. [Greg Stein] + + *) Replace regexec() calls with calls to a new API stub function + ap_regexec(). This solves problems with DSO modules which use the regex + library. [Jens-Uwe Mager <jum@helios.de>, Ralf S. Engelschall] + + *) Add 'Request_Protocol' special keyword to mod_setenvif so that + environment variables can be set according to the protocol version + (e.g., HTTP/0.9 or HTTP/1.1) of the request. [Ken Coar] + + *) Add DSO support for OpenStep (Mach 4.2) platform. + [Ralf S. Engelschall, Rex Dieter <rdieter@math.unl.edu>] PR#3997 + + *) Fix sed regex for generating ap_config_auto.h in src/Configure. + [Jan Gallo <gallo@pvt.sk>] PR#3690, PR#4373 + + *) Switch to /bin/sh5 in APACI on Ultrix and friends to avoid problems with + their brain-dead /bin/sh. [Ralf S. Engelschall] PR#4372 + + *) Better DSO flags recognition on NetBSD platforms using ELF. + [Todd Vierling <tv@pobox.com>] PR#4310 + + *) Always log months in english format for %t in mod_log_config. + [Petr Lampa <lampa@fee.vutbr.cz>] PR#4366, 679 + + *) Support for server-parsed and multiview-determined ReadmeName and + HeaderName files in mod_autoindex. Removed the restriction on + "/"s in ReadmeName and HeaderName directives since the *sub_req* + routines will deal with the access issues. (It's now possible to + have {site|group|project|customer|...} wide readmes and headers.) + [Raymond S Brand <rsbx@rsbx.net>, Ken Coar] PR#1574, 3026, 3529, + 3569, 4256 + + *) When stat() fails, don't assume anything about the contents of + the struct stat. [Ed Korthof <ed@bitmechanic.com>] + + *) It's OK for a semop to return EINTR, just loop around and try + again. [Dean Gaudet] + + *) Fix configuration engine re-entrant hangups, which solve a + handful of problems seen with mod_perl <Perl> configuration sections + [Salvador Ortiz Garcia <sog@msg.com.mx>] + + *) Mac OS and Mac OS X Server now use the appropriate custom layout + by default when building with APACI; allow for platform-specific + variable defaults in configure. [Wilfredo Sanchez] + + *) Do setgid() before initgroups() in http_main; some platforms + zap the grouplist when setgid() is called. This was fixed in + suexec earlier, but the main httpd code missed the change. + [Rob Saccoccio <robs@InfiniteTechnology.com>] PR#2579 + + *) Add recognition of .tgz as a gzipped tarchive. + [Bertrand de Singly <bertrand.de-singly@polytechnique.fr>] PR#2364 + + *) mod_include's fsize/flastmod should allow only relative paths, just + like "include file". [Jaroslav Benkovsky <benkovsk@pha.pvt.cz>] + + *) OS/2: Add support for building loadable modules using DLLs. + [Brian Havard] + + *) Add iconsdir, htdocsdir, and cgidir to config.layout. + [Wilfredo Sanchez] + + *) Fix minor but annoying bug with the test for Configuration.tmpl + being newer than Configuration so that it is less likely to fail + when using APACI and shadow sources. [Wilfredo Sanchez] + + *) PORT: Add initial support for Mac OS (versions 10.0 and + greater). Use Mac OS X Server layout for now. Clean up dyld code + in unix/os.c, and don't install the dyld error handlers, which + are no longer needed in Mac OS. [Wilfredo Sanchez] + + *) Rename Rhapsody layout to "Mac OS X Server". Change install + locations to appropriate ones for user-built (as opposed to + system) installs. [Wilfredo Sanchez] + + *) Modify mod_autoindex's handling of AddDescription so that the + behaviour matches the documentation. [Ken Coar] PR#1898, 3072. + + *) Add functionality to the install-bindist.sh script created by + binbuild.sh to use tar when copying distribution files to the + serverroot. This allows upgrading an existing installation + without nesting the new distribution in the old. + + install-bindist.sh now detects the local perl5 path to install + apxs and dbmmanage with proper path to perl interpreter. + + Add an install-binsupport target which copies the source files + for apxs and dbmmanage to bindist to allow these scripts to + be properly installed relative to the destination serverroot. + [Randy Terbush, Covalent Technologies, randy@covalent.net] + + *) Fix intermittent SEGV in ap_proxy_cache_error() in + src/modules/proxy_util.c where a NULL filepointer and + temporary filename were closed and unlinked. + [Graham Leggett <minfrin@sharp.fm>, + Tim Costello <tjcostel@socs.uts.edu.au>] PR#3178 + + *) Fix inconsistent error messages reported by mod_proxy. + [Graham Leggett <minfrin@sharp.fm>] + + *) OS/2: Fix terminating CGIs that aren't compiled by EMX GCC when a + connection is aborted. [Brian Havard] + + *) Force the LANG envariable to the known state of "C" so that we + have assurance about how string manipulators (e.g., tr) will + function. [Ken Coar] PR#1630 + + *) Add a directive to allow customising of the tracking cookie name. + [Ken Coar] PR#2921, 4303 + + *) Add "force-no-vary" envariable to allow servers to work around + clients that choke on "Vary" fields in the response header. + [Ken Coar, Dmitry Khrustalev <dima@zippy.machaon.ru>] PR#4118 + + *) Fixed a bug in mod_dir that causes a child process will infinitely + recurse when it attemps to handle a request for a directory wnd the + value of the DirectoryIndex directive is a single dot. Also likely + to happen for anyother values of DirectoryIndex that will map back + to the same directory. The handler now only considers regular files + as being index candidates. No PR#s found. + [Raymond S Brand <rsbx@rsbx.net>] + + *) Ease configuration debugging by making TestCompile fall back to + using "make" if the $MAKE variable is unset [Martin Kraemer] + + *) Fixed the ServerSignature directive to work as documented. + [Raymond S Brand <rsbx@rsbx.net>] PR#4248 + + *) Add "opt" (SysV-style) layout to config.layout. [Raymond S Brand + <rsbx@rsbx.net>] + + *) Add APACI --without-execstrip option which can be used to disable the + stripping of executables on installation. This is very important for DSO + and debugging situations. [Ralf S. Engelschall] + + *) Add support for OS/2 (case insenstive filesystem, .exe suffix, etc) + to APACI files and related scripts. + [Yitzchak Scott-Thoennes <sthoenna@efn.org>, Ralf S. Engelschall] PR#4269 + + *) Add support for standalone mode in TPF + [Joe Moenich <moenich@us.ibm.com>] + + *) Fix number of bytes copied by read_connection() in src/support/ab.c + [Jim Cox <jc@superlink.net>] PR#4271 + + *) Fix special RewriteCond "-s" pattern matching. + [Bob Finch <bob@nas.com>] + + *) Fix value quoting in src/Configure script for ap_config_auto.h + [Paul Sutton <paul@awe.com>] + + *) Make sure RewriteLock can be used only in the global context, (i.e. + outside of any <VirtualHost> sections) because it's a global facility of + the rewrite engine. [Ralf S. Engelschall] + + *) Fix the ownership delegation for proxy directory under `make install'. + [Ralf S. Engelschall] + + *) APACI would not correctly build suexec. [Maria Verina + <mariav@icgeb.trieste.it>] PR#4260 + + *) mod_mime_magic passed only the first 4k of a file to + uncompress/gzip, but those tools sometimes do not produce + any output unless a sufficient portion of the compressed + file is input. Change to pass the entire file -- but + only read 4k of output. + [Marcin Cieslak <saper@system.pl>] PR#4097 + + *) "IndexOptions None" generated extra spaces at the end of each + line. [inkling@firstnethou.com] PR#3770 + + *) The "100 Continue" response wasn't being sent after internal + redirects. [Jose KAHAN <kahan@w3.org>] PR#3910, 3806, 3575 + + *) When padding the name with spaces for display, mod_autoindex would + count &, <, and > in their escaped width, messing up the display. + [Dean Gaudet] PR#4075, 3758 + + *) PORT: fixed a compilation problem on NEXT. + [Jacques Distler <distler@golem.ph.utexas.edu>] PR#4130 + + *) r->request_time wasn't being set properly in certain error conditions. + [Dean Gaudet] PR#4156 + + *) PORT: deal with UTS compiler error in http_protocol.c + [Dave Dykstra <dwd@bell-labs.com>] PR#4189 + + *) Add ap_vrprintf() function. [John Tobey <jtobey@banta-im.com>] PR#4246 + + *) Fix the mod_mime hash table to work properly with locales other + than C. [Dean Gaudet] PR#3427 + + *) Fix a memory leak which is exacerbated by certain configurations. + [Dean Gaudet] PR#4225 + + *) Prevent clobbering saved IFS values in APACI. [Jim Jagielski] + + *) Fix buffer overflows in ap_uuencode and ap_uudecode pointed out + by "Peter 'Luna' Altberg <peter@altberg.nu>" and PR#3422 + [Peter 'Luna' Altberg <peter@altberg.nu>, Ronald Tschalär] + + *) Make {Set,Unset,Pass}Env per-directory instead of per-server. + [Ben Laurie] + + *) Correct an apparent typo: on the Windows and MPE platforms, the + htpasswd utility was limiting passwords to only 8 characters. + [Ken Coar] + + *) EBCDIC platforms: David submitted patches for two bugs in the + MD5 digest port for EBCDIC machines: + a) the htdigest utility overwrote the old contents of the digest file + b) the Content-MD5 header value (ContentDigest directive) was wrong + when the returned file was not converted from EBCDIC, but was a + binary (e.g., image file) in the first place. + [David McCreedy <mccreedy@us.ibm.com>] + + *) support/htpasswd now permits the password to be specified on the + command line with the '-b' switch. This is useful when passwords + need to be maintained by scripts -- particularly in the Win32 + environment. [Ken Coar] + + *) Win32: Win32 multiple services patch. Added capability to install and + run multiple copies of apache as individual services. + + Example 1: + apache -n apache1 -i -f c:/httpd.conf + Installs apache as service 'apache1' and associates c:/httpd.conf + with that service. + net start apache1 + Starts apache1 service. + net stop apache1 + Stops apache1 service + + Example 2: + apache -n apache2 -i + Installs apache as service 'apache2'. httpd.conf is located under + the default server root (/apache/conf/httpd.conf). + net start apache2 + Starts apache2 service. + + Example 3: + apache -n apache3 -i -d c:/program files/apache + Install apache as service 'apache3' and sets server root to + c:/program files/apache. + + Example 4: + apache -n apache2 -k restart + Restart apache2 service + + [Keith Wannamaker, Ken Parzygnat, Bill Stoddard] + + *) Correct the signed/unsigned character handling for the MD5 routines; + mismatches were causing compilation problems with gcc -pedantic and + in the TPF cross-compilation. [Ken Coar] + + *) OS/2: Rework CGI handling to use spawn*() instead of fork/exec, achieving + a roughly 5 fold speed up. [Brian Havard] + + *) proxy ftp: instead of using the hardwired string "text/plain" as + a fallback type for files served by the ftp proxy, use the + ap_default_type() function to determine the configured type. + This allows for special configurations like + <Directory proxy:ftp://some.host> + DefaultType gargle/blurb + </Directory> + Additionally, add the Content-Encoding: header to FTP proxy replies + when the encoding is defined (by the AddEncoding directive). + Because it was missing, it was almost impossible to browse compressed + files using the FTP proxy (works now perfectly in Communicator). + The ftp proxy now also returns the Date: and Server: header lines (if not + much else... This code is "somewhat" broken) like normal requests do. + [Martin Kraemer] + + *) Be more smart in APACI's configure script when determining the UID/GID + for User/Group directives and use the determined UID/GID to initialize + the permissions on the proxycachedir. + [Dirk-Willem van Gulik, Ralf S. Engelschall] + + *) Changed the forking-prior-to-cleanup in the proxy module to first + check wether it actually needs to collect garbage. This reduces + the number of fork()s from one/request to just the odd one an hour. + [Dirk-Willem van Gulik] + + *) Added proxy, auth and header support to src/support/ab.c. Added a + README file to src/support/ + [Dirk-Willem van Gulik] + + *) Don't hard-code the path to AWK in --shadow bootstrapping Makefile. + [Ralf S. Engelschall] PR#4050 + + *) Add support for DSO module compilation on BSD/OS 3.x. + [Randy Terbush, Covalent Technologies] + + *) Fix sed-substitutions in `make install': path elements like `httpd/conf' + (for instance from an APACI configure --sysconfdir=/etc/httpd/conf + option) were substituted with $(TARGET).conf, etc. Same for other strings + with dots where the dot wasn't matched as plain text. + [Ralf S. Engelschall] + + *) PORT: Add support for FreeBSD 4.x [Ralf S. Engelschall] + + *) Fix verbose output of APACI configure (option -v) + [Martin Kraemer, Ralf S. Engelschall] + +Changes with Apache 1.3.6 + + *) Removed new PassAllEnv code due to DSO problems. [Lars Eilebrecht] + +Changes with Apache 1.3.5 [not released] + + *) M_INVALID needed a value within the scope of METHODS so that unknown + methods can be access controlled. [Roy Fielding] PR#3821 + + *) Added PassAllEnv; makes server's entire environment available + to CGIs and SSIs executed within directive's scope. [Ken Coar] + + *) ap_uuencode() always added two trailing '='s and encoding of + 8 bit characters on a machine with signed char may produced + incorrect results. Additionally ap_uuencode() should now + work correctly on EBCDIC platforms. + [Ronald Tschalär <ronald@innovation.ch>] PR#3411 + + *) WIN32: Binary installer now runs the configuration DLL before + the reboot prompt (which is only given if MSVCRT.DLL system + DLL is new or updated). This should avoid the configuration + directory being empty after installation. [Paul Sutton] + PR#3767, 3800, 3827, 3850, 3900, 3953, 3988 + + *) WIN32: Binary installer now creates Start menu options to start + and stop Apache as a console application and to uninstall + the Apache service on NT. [Paul Sutton] PR#3741 + + *) WIN32: Apache.exe now contains an icon. [Paul Sutton] + + *) PORT: Switch back to using fcntl() locking on Linux -- instabilities + have been reported with flock() locking (probably related to kernel + version). [Dean Gaudet] PR#2723, 3531 + + *) Using APACI, the main config file (usually httpd.conf) was + not being adjusted as $(TARGET).conf. [Wilfredo Sanchez + <wsanchez@apple.com>] + + *) PORT: AIX does not require the SHARED_CODE "hack" + [Ryan Bloom <rbb@raleigh.ibm.com>] + + *) Set-Cookie headers were being doubled up for some CGIs by the O(n^2) + avoidance code added in 1.3.3. + [Dean Gaudet, Jeff Lewis <lewis@stanford.edu>] PR#3872 + + *) ap_isxdigit was somehow neglected when adding the ap_isfoo() macros + for 8-bit safeness. [Dean Gaudet] + + *) PORT: Use -fPIC instead of -fpic on Solaris and SunOS for compiling DSOs + because SPARCs have a small machine-specific maximum size for the Global + Offset Table which is often exceeded when compiling one of the larger + third-party modules with Apache. [Peter Urban <Peter.Urban@epfl.ch>] PR#3977 + + *) Move the directive `ExtendedStatus' in httpd.conf-dist-win _after_ the + DSO/DLL section because it's a directive from mod_status and isn't + available before the DLL of mod_status is loaded. + [Martin POESCHL <mpoeschl@gmx.net>] PR#3936 + + *) SECURITY: Fix a bug in the calculation of the buffer size for the line + continuation facility in Apache's configuration files which could + lead to a buffer overflow situation. + [Thomas Devanneaux <Thomas.Devanneaux@enst.fr>] PR#3617 + + *) Make documentation and error messages of APACI's --activate-module=FILE + option more clear. [Jan Wolter <janc@wwnet.net>] PR#3995 + + *) Fix the gcc version check (for enabling the `inline' facility) to + really support all future gcc versions >= 2.7 until we know more. + [John Tobey <jtobey@banta-im.com>] PR#3983 + + *) Let APACI's configure script correctly complain for unknown --enable-XXX + and --disable-XXX options. [Ralf S. Engelschall] PR#3958 + + *) Link the shared core bootstrap program (``Rule SHARED_CORE=yes'') also + against libap.a and use its ap_snprintf() instead of sprintf() to avoid + possible buffer overflows. [Ralf S. Engelschall] + + *) Remove no longer used non-API function ap_single_module_init(). + [Ralf S. Engelschall] + + *) Add Apple's Mac OS X Server Layout "Rhapsody" to config.layout. + [Wilfredo Sanchez] + + *) Add cgidir, htdocsdir, iconsdir variables to Makefile.tmpl in order + to make platform installations easier. [Wilfredo Sanchez] + + *) In configure, do not append the target name to the directory path if + the path already contains "apache". [Ralf S. Engelschall] + + *) SIGPIPE is now ignored by the server core. The request write routines + (ap_rputc, ap_rputs, ap_rvputs, ap_rwrite, ap_rprintf, ap_rflush) now + correctly check for output errors and mark the connection as aborted. + Replaced many direct (unchecked) calls to ap_b* routines with the + analogous ap_r* calls. [Roy Fielding] + + *) Enhanced mod_rewrite's mapfile handling: The in-core cache for text and + DBM format mapfiles now uses a 4-way hash table with LRU functionality. + Furthermore map lookups for non-existent keys are now cached as well. + Additionally "txt" maps are now parsed with simple string functions + instead of using ap_pregcomp(). As a side effect a bug that prevented + the usage of keys containing the "," character was fixed. + The changes drastically improve the performance when large rewrite maps + are in use. + [Michael van Elst <mlelstv@serpens.swb.de>, Lars Eilebrecht] PR#3160 + + *) Added ap_sub_req_method_uri() for doing a subrequest with a method + other than GET, and const'd the definition of method in request_rec. + [Greg Stein] + + *) Use proper pid_t type for saving PIDs in alloc.c. [John Bley] + + *) Replaced use of WIN32 define with HAVE_DRIVE_LETTERS to indicate + when the OS allows a DOS drive letter within pathnames. [Brian Havard] + + *) Add %V to mod_log_config, this logs the hostname according to the + UseCanonicalName setting (this is the pre-1.3.4 behaviour of + %v). Useful for mass vhosting. [Tony Finch <dot@dotat.at>] + + *) Add support for \n and \t to mod_log_config, can be used to produce + more reliable logs with multiline entries. [Tony Finch <dot@dotat.at>] + + *) Fixed a few compiler nits. [John Bley <jbb6@acpub.duke.edu>] + + *) Added informative error messages for failed munmap() and fseek() calls + in http_core.c. [John Bley, Roy Fielding] + + *) Added some informative error messages for some failed malloc() + calls. [John Bley <jbb6@acpub.duke.edu>, Jim Jagielski] + + *) OS/2 ap_os_canonical_filename()'s behaviour is improved: ap_assert() + is removed. This allows <Directory proxy:*> directives to work and + prevents invalid requests from killing the process. + [Brian Havard <brianh@kheldar.apana.org.au>] + + *) Reorganised FAQ document. + [Joshua Slive <slive@finance.commerce.ubc.ca>] PR#2497 + + *) src/support/: The ApacheBench benchmark program was overhauled by + David N. Welton: you can now have it generate an HTML TABLE, presumably + for integration into other HTML sources. David updated the ab man page + as well and added some missing descriptions. Thanks! + [David N. Welton <davidw@prosa.it>] + + *) Win32: The filename validity checker now allows filenames containing + characters in the range 0x80 to 0xff (for example accented characters). + [Paul Sutton] PR#3890 + + *) Added conditional logging based upon environment variables to + mod_log_config. mod_log_referer and mod_log_agent + are now deprecated. [Ken Coar] + + *) Allow apache acting as a proxy server to relay the real + reason of a failure to a client rather than the "internal + server error" it does currently. The general exposure mechanism + can be triggered by any module by setting the "verbose-error-to" + note to "*"; this allows more than just proxy errors to be exposed. + [Cliff Skolnick, Roy Fielding, Martin Kraemer] Related to PR#3455, 4086 + + *) Moved man pages for ab and apachectrl to section 8. + [Wilfredo Sanchez, Roy Fielding] + + *) Added -S option to install.sh so that options can be passed to + strip on some platforms. [Ralf S. Engelschall, Wilfredo Sanchez] + + *) Tweak modules Makefile generated by Configure so that it handles + the test case of no modules being selected. [chaz@reliant.com] + + *) Added a <LimitExcept method ...> sectioning directive that allows + the user to assign authentication control to any HTTP method that + is *not* given in the argument list; i.e., the logical negation + of the <Limit> directive. This is particularly useful for controlling + access on methods unknown to the Apache core, but perhaps known by + some module or CGI script. [Roy Fielding, Tony Finch] + + *) Prevent apachectl from complaining if the PIDFILE exists but + does not contain a process id, as might occur if the server is + being rapidly restarted. [Wilfredo Sanchez] + + *) Win32: Add global symbols missing from ApacheCore.def. [Carl Olsen] + + *) Entity tag comparisons for If-Match and If-None-Match were not being + performed correctly -- weak tags might cause false positives. Also, + strong comparison wasn't properly enforced in all cases. + [Roy Fielding, Ken Coar, Dean Gaudet] PR#2065, 3657 + + *) OS/2: Supply OS/2 error code instead of errno on semaphore errors. + [Brian Havard] + + *) Work around a bug in Lynx regarding its sending "Negotiate: trans" + even though it doesn't understand TCN. [Koen Holtman, Roy Fielding] + + *) Added ap_size_list_item(), ap_get_list_item(), and ap_find_list_item() + to util.c for parsing an HTTP header field value to extract the next + list item, taking into account the possible presence of nested comments, + quoted-pairs, and quoted-strings. ap_get_list_item() also removes + insignificant whitespace and lowercases non-quoted tokens. + [Roy Fielding] PR#2065 + + *) proxy: The various calls to ap_proxyerror() can return HTTP/1.1 status + code different from 500. This allows the proxy to, e.g., return + "403 Forbidden" for ProxyBlock'ed URL's. [Martin Kraemer] Related to PR#3455 + + *) Fix ordering of language variants for the case where the traditional + negotiation algorithm is being used with multiple language variants + and no Accept-Language. [James Treacy <treacy@debian.org>] PR#3299, 3688 + + *) Do not round the TCN quality calculation to 5 decimal places, + unlike RFC 2296, because the calculation might need 12 decimal places + to get the right result. [Roy Fielding] + + *) Remove unused code to disable transparent negotiation when + negotiating on encoding only, as we now handle encoding too + (though this is nonstandard for TCN), remove charset=ISO-8859-1 + fiddle from the fiddle-averse RVSA comparison, and fix bugs in + some debugging statements within mod_negotiation. [Koen Holtman] + + *) Fixed a rare memory corruption possibility in mod_dir if the index + file is negotiable and no acceptable variant can be found. + [Dean Gaudet, Roy Fielding, Martin Kraemer] + + *) Win32: Add new config directive, ScriptInterpreterSource, to enable + searching the Win32 registry for script interpreters. + [Bill Stoddard] + + *) Win32: The compiled-in default filename for the error log is now + error.log, which matches the default in the distributed httpd.conf. + [Paul Sutton] + + *) Win32: Any error messages from -i or -u command line options are now + displayed on the console output rather than sent to the error log. + Also the "Running Apache..." message is not output unless Apache is + going to serve requests. [Paul Sutton] + + *) Rework the MD5 authentication scheme to use FreeBSD's algorithm, + and use a private significator ('$apr1$') to mark passwords as + being smashed with our own algorithm. Also abstract the password + checking into a new ap_validate_password() routine. [Ken Coar] + + *) Win32: The filename validity checker now allows "COM" but refuses + access to "COM1" through "COM4". This allows filenames such + as "com.name" to be served. [Paul Sutton] PR#3769. + + *) BS2000: Adapt to the new ufork() system call interface which will + make subtasking easier on the OSD/POSIX mainframe environment. + [Martin Kraemer] + + *) Add a compatibility define for escape_uri() -> ap_escape_uri() to + ap_compat.h. [David White <david@persimmon.com>] PR#3725 + + *) Make NDBM file suffix determination for mod_rewrite more accurate, i.e. + use `.db' instead of `.pag' not only for FreeBSD, but also when + the NDBM library looks like Berkeley-DB based. + [Ralf S. Engelschall] PR#3773 + + *) Add ability to handle DES or MD5 authentication passwords. + [Ryan Bloom <rbb@Raleigh.IBM.Com>] + + *) Fix O(n^2) memory consumption in mod_speling. [Dean Gaudet] + + *) SECURITY: Avoid some buffer overflow problems when escaping + quoted strings. (This overflow was on the heap and we believe + impossible to exploit.) [Rick Perry <perry@ece.vill.edu>] + + *) Let src/Configure be aware of CFLAGS options starting with plus + signs as it's the case for the HP/UX compiler. + [Doug Yatcilla <yatcilda@umdnj.edu>] PR#3681 + + *) Remove the hard-wire of TAR=tar (we now check for gtar and gnutar first) + and check to see if the tar we wind up with supports '-h'. + [Jim Jagielski] PR#3671 + + *) A consistent and conservative style for all shell scripts has been + implemented. Basically, all shell string tests use the traditional + hack of 'if [ "x$var" != "x" ]' or 'if [ "x$var" = "xstring" ]' + to protect against bare null variable strings (ie: wrapping both + sides with double quotes and prepending 'x'). 'x' was chosen + because it's more universal and hopefully easier for old shell + prgrammers, as well as being easier to search for in 'vi' (/x\$) :) + [Jim Jagielski] + + *) The status module now prints out both the main server generation as + well as the generation of each process. Also, the vhost info is + printed with '?notable'. [Jim Jagielski] + + *) Move src/main/md5c.c to src/ap/ap_md5c.c; it's httpd-neutral + and this makes its functions available to things in src/support. + [Ken Coar] + Changes with Apache 1.3.4 *) Renamed macros status_drops_connection to ap_status_drops_connection @@ -1967,7 +2841,7 @@ Changes with Apache 1.3b6 *) PORT: IRIX needs the -n32 flag iff using the 'cc' compiler [Jim Jagielski] PR#1901 - *) BUG: Configure was using TCC and CC inconsistantly. Make sure + *) BUG: Configure was using TCC and CC inconsistently. Make sure Configure knows which CC we are using. [Jim Jagielski] *) "Options +Includes" wasn't correctly merged if "+IncludesNoExec" diff --git a/usr.sbin/httpd/src/CHANGES.SSL b/usr.sbin/httpd/src/CHANGES.SSL index 16304281a32..00b298731c5 100644 --- a/usr.sbin/httpd/src/CHANGES.SSL +++ b/usr.sbin/httpd/src/CHANGES.SSL @@ -1,8 +1,8 @@ _ _ - _ __ ___ ___ __| | ___ ___| | - | '_ ` _ \ / _ \ / _` | / __/ __| | - | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay - |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ + _ __ ___ ___ __| | ___ ___| | mod_ssl + | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL + | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org + |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org |_____| _____________________________________________________________________________ @@ -13,7 +13,462 @@ This file summarizes *all* types of changes to the mod_ssl package, i.e. changes between each betalevel and patchlevel, i.e. changes between 2.x.y->2.x.(y+1) and 2.x.y->2.(x+1).0. Take this list as a reference for - concrete and detailed information about every single change. + concrete and detailed information about every single change. There are + _INTENTIONALLY_ no contributor names attached to the entries. Instead all + contributors are listed in the CREDITS file. + + ____ _ _ + |___ \ | || | + __) || || |_ + / __/ |__ _| + __ |_____(_) |_| ___________________________________________ + + Changes with mod_ssl 2.4.2 (30-Aug-1999 to 06-Sep-1999) + + *) Added hint about -fPIC vs. -fpic to INSTALL document. + + *) Changed /sw/bin/perl to the more common /usr/bin/perl + in pkg.contrib/loadcacert.cgi. + + *) Fixed two (harmless) compile-time warnings related to + `unsigned char *' vs. `char *'. + + *) Added hint about required browser restarts on re-installations. + + *) Added quotes to DocumentRoot in conf/httpd.conf-dist + to avoid problems with binbuild.sh. + + *) Fixed --with-apxs: configure.stub.sh has to be `sourced' as + `./configure.stub.sh' instead of just `configure.stub.sh' or some + Bourne Shells cannot find it. + + Changes with mod_ssl 2.4.1 (18-Aug-1999 to 30-Aug-1999) + + *) Added logging hint "too restrictive SSLCipherSuite or using DSA server + certificate?" for "no shared cipher" errors. + + *) Added an explicit ap_blush() call to the connection close hook to + make sure that pending outgoing data is flushed _before_ the SSL + layer is closed. This is important to make sure that the pending + data is still transferred through the SSL layer. Else an I/O + error can occur inside the browser because the pending data is + transferred as plain data (at a time where the browser will no + longer expect the data, i.e. after the SSL close notify message + was already received by it). + + *) Added new FAQ entries. + + *) Show `-D EAPI_MM' on `httpd -V', too. + + *) Pass also $(MFLAGS) to src/support/mkcert.sh for consistency. + + *) Fixed mod_define.html: `docroot' was doubled. + + *) Made sure mkcert.sh handles the algorithm variable more robust in order + to make sure that people do not accidently choose the DSA variant. + + *) mod_ssl now complains already at startup if one tries to use ``SSLMutex + file:...'' on Win32 (where the semaphore mutex _has_ to be used). + + *) Removed obsolete pkg.ssldoc/ssl_cover_title.gif + + Changes with mod_ssl 2.4.0 (03-Aug-1999 to 18-Aug-1999) + + *) Upgraded from Apache 1.3.6 to Apache 1.3.9 + (Apache versions 1.3.7 and 1.3.8 were not released). + + *) Fixed a nasty bug in mod_define.c: the global define variable pool was + never destroyed and this way could lead to segfaults on server restarts. + + *) Pass number of bytes from ``SSLRandomSeed exec:/path/to/prog(bytes)'' as + first argument to /path/to/prog in order to allow the program to know + how much bytes of entropy it should provide on stdout. + + ____ _____ + |___ \ |___ / + __) | |_ \ + / __/ _ ___) | + __ |_____(_)____/ __________________________________________ + + Changes with mod_ssl 2.3.11 (28-Jul-1999 to 03-Aug-1999) + + *) Changed pass phrase dialog: Now you're allowed to enter even 1 char pass + phrases, i.e. you're no longer required to enter more than 4 characters. + That's important for encrypted private keys not generated via OpenSSL. + + *) Added configuration check: Now mod_ssl checks on startup whether the + CommonName (CN) of a certificate matches the ServerName of the virtual + host. If not, a warning is given, because it will lead to at least + popping up dialog boxes in NS and IE. + + *) Added configuration check: Now mod_ssl checks whether more than one + SSL-aware virtual host uses the same IP:port and complains with a + warning, because for SSL name-based virtual hosts cannot be used. + + *) Overhauled mod_define: it now uses a global define value table and + this way not works correctly also in <VirtualHost> sections and other + contexts. + + *) Added a few more FAQ entries. + + *) Cleaned up ssl_init_Module() function: it now no longer + destroys the server_rec argument as a side-effect. + + *) Fixed top-level Makefile.tmpl: ssl.crl wasn't created; README.CRL + wasn't installed; incorporated an important escaping bugfix from Apache + 1.3.7-dev. + + *) Added fallback definitions for TRUE/FALSE to ap_mm.h + + *) Fixed I/O pre-sucking for HTTPS proxy situations where + no mod_ssl context is attached to SSL structures. + + *) Fixed Mutex acquiring under Win32: the result value + was computed incorrectly and leaded to warning log entries. + + *) Catch SIGPIPE in truerand.c (a contrib program in pkg.contrib/) to allow + it behave correctly under `SSLRandomSeed exec:bin/truerand N'. + + Changes with mod_ssl 2.3.10 (26-Jul-1999 to 28-Jul-1999) + + *) Changed the handling of the `per-URL SSL re-configuration in conjunction + with POST method based HTTP requests' problem: Per default mod_ssl now + returns a METHOD_NOT_ALLOWED HTTP error when one tries to POST to a URL + which has SSL parameters re-configured, because mod_ssl per default + cannot handle this situation (for technical reasons). This way the I/O + errors which occured in the past are now at least replaced by a correct + error message. + + But when you build with --enable-rule=SSL_EXPERIMENTAL you get + experimental support for this situation and you then _CAN_ use POST even + in conjunction with per-URL SSL re-configurations. + + But nevertheless one have to keep in mind that the POST body is still + transferred under the global SSL parameters and that the renegotiation + (typically to a stronger cipher, etc.) happens only before the response + is sent (and not before the POST data is read!). The rule of thumb is: + per-URL SSL parameters _CANNOT_ be applied to _ANY_ part of the + _REQUEST_, they are only guarrantied to be applied to the _RESPONSE_. + + In practice there are situations (for instance when the client resumes + the request already with previously renegotiated parameters, etc.) where + the situation _CAN_ be better. But you cannot _EXPECT_ it to be better + and mod_ssl _CANNOT GUARRANTY_ it to be better, of course. + + *) Added support for latest OpenSSL 0.9.4-dev snapshot version. + + *) Fixed initialization and cleanup relazed problems with SSLMutex: The + mutex is now closed before the chown and the mutex is removed only in + the parent on module shutdown. + + *) Removed HTTPD_ROOT from EAPI_MM_CORE_PATH definition in httpd.h + because it is redundant and can cause problems. + + Changes with mod_ssl 2.3.9 (25-Jul-1999 to 26-Jul-1999) + + *) Compile ap_make_shared_sub_pool() only under -DEAPI + and added it to httpd.exp. + + *) Fixed alloc.c again: the ap_mm_destroy has to be used only for + defined(EAPI) && defined(EAPI_MM) and not just for defined(EAPI). + + Changes with mod_ssl 2.3.8 (25-Jul-1999 to 25-Jul-1999) + + *) Fixed a nasty problem with early pool cleanups during + startup when shared memory session caches are configured. + + Changes with mod_ssl 2.3.7 (14-Jul-1999 to 25-Jul-1999) + + *) Optimization for logfile handling: We now short-circuit the + filedescriptors for inherited logfiles in order to save filedescriptors. + This is important for mass virtual hosting situations where we really + have to reduce the resource consumption. + + *) Enhanced the DBM-based SSL Session Cache: + + o the cache DBM files are removed on shutdowns and restarts now + to prevent the occurance of DBM inconsistencies over long runs. + + o the DBM store operation now stores only data which has + sizeof(key)+sizeof(data) < 1024 to make sure some broken vendor DBM + libraries do not segfault on large entries. Only with the built-in + SDBM library up to 8KB are stored. + + o the expiry procedure was rewritten to prevent problems with + less smart DBM libraries: Instead of iterating and deleting in + parallel (which causes some DBM libraries to become totally crazy) a + two pass approach is used. In the first pass the DBM library is + scanned and expired elements are remembered only. In the second pass + the rememebered elements are actually deleted. + + *) Fixed SSL mutex handling: the mutex file was not removed on shutdown. + + *) Fixed global shared memory pool handling in alloc.c: The shared memory + related temporary files of MM were not removed because ap_mm_destroy() + was missing on exit. + + *) A few adjustments anf fixes to the FAQ and added hint to OpenSA + to INSTALL.Win32. + + *) Fixed ``SSLRandomSeed exec:..'' for OS/2 and Win32. + + *) Fixed shared memory pool handling in alloc.c: + Two realloc() calls were not shared memory aware. + + Changes with mod_ssl 2.3.6 (22-Jun-1999 to 14-Jul-1999) + + *) Enhanced ap_mm_create() failure messages in alloc.c + + *) Fixed a core dump for the rare situation where mod_ssl was build + statically into Apache but not enabled (AddModule). + + *) Perform more tries to chown() used DBM files. + + *) Fixed memory leaks on restarts related to shared memory session cache: + the MM object wasn't removed at all. + + *) Allow SSL_DBM_FILE_SUFFIX_DIR and SSL_DBM_FILE_SUFFIX_PAG + to be overridden via CFLAGS. + + *) Fixed grammar and typos in ssl_reference.wml + + *) Done a blind update of the INSTALL.Win32 document. + + *) Added five new FAQ entries. + + *) Fixed EAPI MM related permission problems. + + *) On startup the configured cipher suite is now also + displayed under log level "trace". + + *) Let the Win32 configure.bat complain when --with-apache or + --with-ssl is missing. + + *) Added new `SSLCertificateChainFile /path/to/file' directive. This can + point to a file containing the concatenation of PEM encoded CA + certificates which explicitly form the server certificate chain. This is + intended for instance for the Global-ID situation where one _has_ to + send the intermediate CA of Verisign with the GID while one wants to + avoid that under client authentication all clients issued by this CA are + accepted (which would happen when one references the CA cert via + SSLCACertificatePath or SSLCACertificateFile instead of + SSLCertificateChainFile). + + *) Changed the "Interrupted by system" `error' to `info' level in + case errno is not > 0. + + Changes with mod_ssl 2.3.5 (18-Jun-1999 to 22-Jun-1999) + + *) Rewritten the DBM and SHM expiration functions in ssl_engine_scache.c to + avoid problematic situation where one deletes an entry before the + iteration counter was incremented. This was perhaps also another reasons + for the session cache related core dumps. + + *) Fixed a nasty bug in ssl_util_table.c: A static (heap-based) calloc() + call was forgotten to be converted to a dynamic (shared memory based) + table->calloc() call. This leaded to various core dumps once the session + cache's hash table was filled as had to be resized (which occured + only after some time of operation, of course). + + *) Now mod_ssl displays an info logfile entry when the server certificate + is a SCG one and warning logfile entries when the server certificate has + BasicConstraints CA:TRUE or pathlen>0. + + *) Fixed FakeBasicAuth handling: ssl::client::dn wasn't + set correctly and wasn't set at all in renegotiation context. + + *) Fixed HowTo example with +FakeBasicAuth: AuthName was + missing and typos + + Changes with mod_ssl 2.3.4 (09-Jun-1999 to 18-Jun-1999) + + *) The Fake Basic Auth stuff now is logging it's operation. + + *) Fixed pkg.contrib/cca.sh script: CA:TRUE was incorrect + for a client certificate, of course. + + *) Added session cache status display to the pages generated by mod_status. + When "ExtendedStatus on" is used mod_ssl appends session cache + information (supported for both DBM and SHM). + + *) Fixed ``SSLVerifyClient optional_no_ca'' for per-directory context. + + *) Added ``SSLOptions +OptRenegotiate'': + This enables optimized SSL connection renegotiation handling when SSL + directives are used in per-directory context. Per default a strict + handling is enabled where every per-directory reconfiguration of SSL + parameters cause a full SSL renegotiation handshake. When this option + is used mod_ssl tries to avoid unnecessary handshakes by doing more + granular (but still safe) parameter checks. This should reduce + the renegotiation overhead a little bit. + + *) Also print SSL errors on SSL_ERROR_SYSCALL situation. + + *) Make sure EAPI_MM=SYSTEM doesn't add -I/usr/include to CFLAGS (which + occurrs for instance under Debian where MM is installed in system + locations). + + *) The SSL session context is now also set on session renegotiations. + + Changes with mod_ssl 2.3.3 (08-Jun-1999 to 09-Jun-1999) + + *) Various type fixes for Session Cache code. + + *) A few fixes to make the Win32 world happy again. + + *) Fixed glibc 2.1 ndbm.h inclusion problems. + + *) Make sure that in "SSLSessionCache shm:/path/to/file(NNN)" + the size NNN cannot be specified greater than the maximum + possible shared memory segment (which is platform + dependent, of course). + + Changes with mod_ssl 2.3.2 (28-May-1999 to 08-Jun-1999) + + *) Removed obsolete mca.sh script and updated cca.sh script to current + OpenSSL state. + + *) Now "SSLSessionCache none" really disables _all_ caching, + i.e. including the internal OpenSSL cache. + + *) Added Shared Memory based SSL Session Cache: A new "SSLSessionCache + shm:/path/to/file(bytes)" variant of the SSL session cache was added. + This uses a high-performance hash table inside a shared memory segment + to provide the fastest inter-process session cache which is possible. + For this Apache+EAPI has to be built with EAPI_MM (linked against the MM + library, the shared memory abstraction). + + *) Fixed the EAPI_MM related patches to Apache's src/Configure: + The variables were overridden instead of extended. + + *) Added hint to FAQ to make sure people enter the FQDN for CommonName when + generating a server certificate. Added hint to EGD to reference chapter. + + *) Some more Win32 fixes. + + *) Fixed a session cache problem on shutdowns. + + *) Fixed mod_ssl's ``configure --with-mm=DIR'' + + Changes with mod_ssl 2.3.1 (25-Apr-1999 to 28-May-1999) + + *) Fixed two memory leaks in ssl_util_ssl.c related to BIOs. + + *) Fixed EAPI sources in src/ap/: They failed to compile + when -DEAPI wasn't used which isn't nice. + + *) Fixed Win32 stuff: src/ap/ap.mak missed entries for ap_mm.[ch], + src/modules/ssl/Makefile.win32 missed entry for ssl_engine_dh.c, + configure.bat wasn't aware of the new include/openssl/ layout. + + Changes with mod_ssl 2.3.0 (12-Apr-1999 to 25-May-1999) + + *) Upgraded to final OpenSSL 0.9.3 API and made this + version the lowest possible OpenSSL version for mod_ssl. + + *) Fixed ap_mm.c stubs. + + *) Updated dependencies in src/modules/ssl/Makefile.tmpl + + *) Fixed INSTALL document for OpenSSL 0.9.3: + -DNO_IDEA => no-idea and -DRSAref & friends => rsaref. + + *) ** Second major step for DH/DSA support **: + The mod_ssl module itself is now aware of multiple certificate/keys when + they are of a different type (one RSA, the other DSA). All internal + cert/key related handling which was hard-coded for RSA was replaced by + generic code which supports both RSA and DSA. This way now all SSL + ciphers, including the real Diffie-Hellman ciphers like + EDH-DSS-DES-CBC3-SHA are supported by mod_ssl. + + *) Upgraded Thawte's sxnet stuff in pkg.contrib/ + + *) Added new variable SSL_SESSION_ID which contains the hex-encoded SSL + session id. This variable is also exported to the SSI/CGI environment + and can be used as a session-unique key. + + *) Added more error checking for SSL_XXX variable lookups. + + *) ** First major step for DH/DSA support **: + 1) snakeoil.{crt,key} was renamed to snakeoil-rsa.{crt,key} and a + snakeoil-dsa.{crt,key} was created. 2) src/support/ca-fix.c was kicked + out (it's obsolete with OpenSSL 0.9.3) and 3) src/support/mkcert.sh was + changed to use the new `openssl x509 -extfile ..' instead of ca-fix and + to support the generation of DSA certs/keys via `openssl gendsa'. + Finally 4) the top-level Makefiles were adjusted to support an + ALGO={RSA,DSA} parameter for selecting the algorithm in batch and a + VIEW=1 parameter for viewing the generated cert/key in plain text + format. + + *) Removed more source code relicts of SSLeay by replacing + them with the official OpenSSL variants. + + *) Added ap_{mm,MM}* function list to src/support/httpd.exp + + *) Update ap_mm.{c,h} for MM 1.0.3, i.e. add stubs for new + ap_{MM,mm,mm_core}_permission() function. + + *) Replaced all references to EAY's old email address with the new one. + + *) Fixed source tree creation: ap_mm.[ch] wasn't installed. + + *) Removed -l option from yacc call in src/modules/ssl/Makefile.tmpl and + touch the pre-generated scanner/parser files so the generation isn't + done for end users. + + *) Give more reasonable error message on pass phrase dialog by + distinguishing between "Pass phrase incorrect" and "Private key not + found" situations. + + *) Fixed configure and configure.bat scripts: ssl.crl wasn't created + and server.csr wasn't installed under Win32. + + *) Added a new ``SSLOptions +StrictRequire'' This _forces_ forbidden + access when SSLRequireSSL or SSLRequire successfully decided that access + should be forbidden. Usually the default is that at least a used + ``Satisfy any'' can cancel such access denies (when other access + restrictions were passed), because that's how the Apache Satisfy + mechanism should work. But for strict access restriction you can use + SSLRequireSSL and/or SSLRequire in combination with an ``SSLOptions + +StrictRequire''. Then an additional ``Satisfy Any'' has no chance once + mod_ssl has decided to deny access. + + *) Removed all direct Apache-SSL related comparsions from the mod_ssl FAQ + chapter of the user manual to finally avoid any more blames by Ben + Laurie. + + *) Upgraded to the forthcoming OpenSSL 0.9.3 API. Because of too much API + changes (constifications, STACK_OF, etc.) we cannot provide support for + older versions any longer without making the mod_ssl source code ugly. + OTOH for mkcert.sh we already want >= 0.9.3, so drop support for all + older versions now. + + *) Switched all addresses and references to new modssl.org domain. + + *) Updated the User Manual for version 2.3 + + *) Various stylistic source code cleanups. + + *) EBCDIC-related fix for variable lookup functions. + + *) Added generic Shared Memory support to Extended API (EAPI) via the new + MM library (available externally). First two new ap_mm.c/ap_mm.h source + files provide new functions ap_mm_xxx() which are either stubs (when no + shared memory support is available via the MM library) or call the + mm_xxx() counterparts of the MM library. Second, shared memory pools + are patched into alloc.c/alloc.h which uses the ap_mm_xxx() functions in + the background. + + *) Added support for X.509 CA Certificate Revocation Lists (CRL). For this + the two new directives SSLCARevocationPath and SSLCARevocationFile + (similar to SSLCACertificate{Path,File}) are provided where one can + store CRL files. The preconfigured default directory for CRLs is + PREFIX/conf/ssl.crl. The SSLCARevocationPath is a directory where the + CRLs are looked up via hash symlinks. For this a ssl.crl/Makefile is + provided similar to ssl.crt/Makefile. + + *) Kicked out all remaining SSLeay references and dependencies. The + minimum SSL library version which is now required is OpenSSL 0.9.2b. ____ ____ |___ \ |___ \ @@ -21,6 +476,216 @@ / __/ _ / __/ __ |_____(_)_____| _________________________________________ + Changes with mod_ssl 2.2.8 (29-Mar-1999 to 12-Apr-1999) + + *) Use SSL_smart_shutdown() also for SSL proxy stuff. + + *) Fixed some compat variable mappings and updated ssl_compat.wml + document to reflect the current compat state. + + *) Added ssl_log_applies() function in advance for forthcoming feature + commits. + + *) Added NEWS file to distribution which summarizes the major changes and + this way gives a faster overview for the impatient users. + + *) Added a new pkg.contrib/cca.sh script which I used for client auth + testing with the latest OpenSSL versions. Additionally adjust old + mca.sh script for OpenSSL. + + *) Added the missing ssl_template.inc file to the distribution + + *) Various source code cleanups to make forthcoming patches more clean. + + Changes with mod_ssl 2.2.7 (24-Mar-1999 to 29-Mar-1999) + + *) Fixed the ``HTTPS request received for child'' log entries: Now no + longer multiple copies of a message occur, because mod_ssl logs them + only on initial requests (and no longer on sub-requests and internal + redirects). + + *) Fixed a few more memory leaks which occured on server restarts. + + *) Added entry to the FAQ for the MSIE work-around with + ``SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown''. + + *) Added support for two SetEnvIf variables: ssl-unclean-shutdown and + ssl-accurate-shutdown. These can be used to for instance force different + shutdown approaches for particular browsers. An ``SetEnvIf User-Agent + ".*MSIE.*" ssl-unclean-shutdown'' now forces the old mod_ssl 2.1 + behaviour where no close notify messages are sent at all before + connection close. An ``SetEnvIf User-Agent ".*Lynx.*" + ssl-accurate-shutdown'' forces an accurate shutdown when the client is + Lynx+OpenSSL where mod_ssl both sends it's close notify alert and waits + for the close notify alert of the client. + + *) Updated source file dependecies in src/modules/ssl/Makefile.tmpl. + + Changes with mod_ssl 2.2.6 (18-Mar-1999 to 24-Mar-1999) + + *) Now mod_ssl logs the current Apache, mod_ssl and OpenSSL versions at + startup which makes it easier to distinguish which software combination + is actually running by just looking into the log. + + *) Added support for new 56/1024 bit export ciphersuites (idea overtaken + from Apache-SSL 1.32) and sign-only-certificate situations where + stronger (1024 instead of 512 bit) temporary keys are reasonable to use. + + *) Upgrade to new upstream version Apache 1.3.6 on vendor branch. + [Version 1.3.5 was not released because of last minute problems] + + *) *** SECURITY *** SECURITY *** SECURITY *** + In the OpenSSL project we discovered that a terrible security hole + exists for _all_ SSLeay/OpenSSL server applications that use virtual + hosting. Here sessions could be resumed in the wrong context thus + bypassing client certificate protection! This hole is now fixed in + OpenSSL 0.9.2b by an ad-hoc solution were SSL sessions cannot be resumed + unless the server application tags it with a unique context id per + virtual host. mod_ssl now also performs this tagging to prevent this + exploit. + + *) Added the nifty EAPI-based mod_define module to the source tree. This + modules provides variable definitions for arbitrary directive lines, + i.e. you can expand ${xxx} on any(!) directive line. This module is + disabled per default in src/Configuration.tmpl (need an + --enable-module=define) and it lives in the new pkg.addon area. + + *) Added Stronghold's table look and feel to mod_status' display page. + This patch is harmless and enabled per default and lives in the new + pkg.addon area. + + *) Opened another distribution package subdir: pkg.addon/. + Here addons will be stored which are not directly/physically related to + mod_ssl and EAPI, but indirectly. + + *) Cleaned up the generation of the signature table in ap_hook.c + and updated the hook list with the still missing vendor hooks. + + *) Renamed recently added vendor hooks to from ssl::vendor::xxx to + ap::mod_ssl::vendor::xxx to be consistent with remaining EAPI hook + names. + + *) Upgrade to new upstream version Apache 1.3.5 on vendor branch + + *) Fixed a segfault in the HTTPS support for mod_proxy which + occured when the proxy couldn't connect to the remote host. + + *) Be 100% conservative and clean and use SSL_clean() after SSL_new(). + + Changes with mod_ssl 2.2.5 (04-Mar-1999 to 18-Mar-1999) + + *) Fixed the situation were we discovered processes consuming + 100% CPU time. This occured under various not exactly known + circumstances, but it seems it was always when the client plays bad with + the socket connection and OpenSSL cannot recognize it. Then the state + machine of SSL_shutdown() seems to loop endless. It's now fixed by not + limiting the iterations. + + *) Fixed a typo in the SSL_CERTIFICATE_FILE define, although this + variable is still not used. + + *) Fixed the POST-problem where kept-alive HTTPS connections hang or + resulted in an I/O error inside the browser because the ``SSL close + notify'' alert couldn't be sent correctly because of Apache's internal + ``lingering close'' handling. EAPI was changed to now correctly call the + close_connection module hook also on timeout and linger closes. This + EAPI change means you cannot upgrade your libssl.so with --with-apxs to + this version. A complete Apache rebuild with the updated EAPI code is + necessary. + + *) The SSLCertificateFile and SSLCertificateKeyFile directives now can read + PEM (=DER+Base64+headers), DER+Base64 (without headers) and plain DER + format certificate and private key files. This is mostly provided for + convinience reasons. + + *) Add FAQ entry: How to convert PEM into DER. + + Changes with mod_ssl 2.2.4 (21-Feb-1999 to 04-Mar-1999) + + *) Add important note to INSTALL/INSTALL.Win32 that all + documentation references already use the term OpenSSL, the file and + program names `openssl', etc. although most of the users are still using + SSLeay and don't have any `openssl' command, etc. + + *) Fixed two export warnings for ssl_expr_parse.c under Win32. + + *) In correspondence with the SSLeay to OpenSSL transition + we changed the --with-ssleay=DIR option to --with-ssl=DIR (but the old + variant is still recognized for backward compatibility, of course). For + consistency we also renamed --with-rsaref=DIR to --with-rsa=DIR. + + *) Ported src/support/ca-fix tool to OpenSSL 0.9.2, although after final + switching to OpenSSL 0.9.2 as the minimum required toolkit version we + will no longer need this tool. But until then let us be friendly and + support the OpenSSL snapshots ;-) + + *) Added the first cut of Vendor extension support. This stuff is + currently _NOT_ compiled in per default. It has to be enabled with the + new APACI --enable-rule=SSL_VENDOR option. The idea is this: the mod_ssl + sources contain EAPI vendor hooks (`ssl::vendor::xxxx') and internal + EAPI context variables which can be used to change or extend mod_ssl by + a vendor without patching the source code. Grep for `ssl::vendor::' + inside src/modules/ssl/ for more details. Additionally vendors can now + add their own source code as files named ssl_vendor.c, ssl_vendor_XXX.c, + etc. The libssl.module script automatically picks these up under + configuration time and mod_ssl under run-time calls the functions `void + ssl_vendor_register(void)' and `void ssl_vendor_unregister(void)' inside + these objects to bootstrap them. Read the src/modules/ssl/README file + for more details. + + *) Fixed two old Stronghold directive compatibility mappings, added missing + Stronghold directive mappings and added a bunch of additional Stronghold + variable mappings. + + *) Big and official switch from the name `Apache Interface to SSLeay' to + `Apache Interface to OpenSSL', from any SSLeay-references to + OpenSSL-references, etc. There is still support for SSLeay, of course. + But this renaming cleanup has to be done, because in the near future + support for SSLeay has to be completely dropped due to non-optional + support for new features like DSA/DH, etc (which is only possible with + OpenSSL). + + *) Made the error messages of `configure' even more idiot-proof :-( + + *) Fixed the connection closing phase: First, mod_ssl no longer hooks into + this phase by using ap_register_cleanup() (with the connection pool) + because the cleanup functions are called by Apache's API a lot too late + (actually _after_ the socket was already closed!). Instead a new EAPI + hook `close_connection' was added to register a hook which is run + directly _before_ the socket is closed. Second, the SSL ``Close + Notify'' alert is now always sent (even when older IE browsers display + the message in the window), because not sending the alert is a violation + of the SSL/TLS standard. + !! ATTENTION: THIS HAD TO CHANGE EAPI, SO YOU HAVE TO RECOMPILE APACHE !! + + *) Enhance the output of alert messages under `SSLLogLevel trace'. + + *) Make mod_ssl aware of the forthcoming OpenSSL 0.9.2 version + where some callback function signatures will be changed + and a few new TLSv1 export ciphers are added. + + *) Fixed restarts which were broken due to recent changes to the cert/key + handling (DER/internal conversions). Now mod_ssl again surives server + restarts without problems. + + *) Replaced `%0 %*' with `%0 %1 %2 %3 %4 %5 %6 %7 %8 %9' in configure.bat + because Windows 98 is even more braindead than anyone can image. + + *) Added AP_HOOK_DECLTMP return code semantic to EAPI's hook mechanism + which is needed in the forthcoming vendor hooks to avoid local temporary + variables. + + *) Fixed the `SSLLogLevel debug' output where confusing `Ops, no memory + buffer?' messages occured in the past. The BIO callback function now + only outputs messages for the actual read/write calls. + + *) Fixed a warning the `gcc -O -Wall ...' compiler flag combination causes. + + *) Fixed confusing terms in the final messages in mkcert.sh + which display a short description of files under `make certificate'. + + *) Fixed compilation for SunOS where no RAND_MAX exists. + Changes with mod_ssl 2.2.3 (05-Feb-1999 to 21-Feb-1999) *) Cleaned up the namespace of mod_ssl structures: @@ -1023,7 +1688,7 @@ $ make certificate TYPE=dummy (dummy self-signed Snake Oil cert) $ make certificate TYPE=test (test cert signed by Snake Oil CA) $ make certificate TYPE=custom (custom cert signed by own CA) - $ make certificate TYPE=official (existing official cert) + $ make certificate TYPE=existing (existing official cert) CRT=/path/to/your.crt [KEY=/path/to/your.key] The default is TYPE=test which is equivalent to the old `make @@ -1738,7 +2403,7 @@ $ make certificate TYPE=dummy (dummy self-signed Snake Oil cert) $ make certificate TYPE=test (test cert signed by Snake Oil CA) $ make certificate TYPE=custom (custom cert signed by own CA) - $ make certificate TYPE=official (existing official cert) + $ make certificate TYPE=existing (existing official cert) CRT=/path/to/your.crt [KEY=/path/to/your.key] The default is TYPE=test which is equivalent to the old `make diff --git a/usr.sbin/httpd/src/Configuration b/usr.sbin/httpd/src/Configuration index a10f798aa6e..68cc2dfaf91 100644 --- a/usr.sbin/httpd/src/Configuration +++ b/usr.sbin/httpd/src/Configuration @@ -26,47 +26,6 @@ # not enabled). The AddModule directive can be used to enable such a # module. By default no such modules are defined. -################################################################ -# SSL support: -# -# o Set SSL_BASE to either the directory of your SSLeay -# source tree or the installation tree. Alternatively you can -# also use the value 'SYSTEM' which then indicates that SSLeay -# is installed under various system locations. -# -# o If you're a US-citizen you have to compile SSLeay with the -# RSAref library (which replaces the RSA code of SSLeay) -# because of patent legalities with the RSA algorithm used for -# the SSL protocol. For this situation you already have to -# compile SSLeay with the -DRSAref define and now you have to -# force Apache to link against the RSAglue library (from -# SSLeay) and the rsaref library (from RSA). So, set RSA_BASE -# to the directory of your RSAref source tree or to 'SYSTEM' -# (indicating that librsaref.a is installed under a system -# location) -# -# o Disable SSL_COMPAT rule to build mod_ssl without backward -# compatibility code for Apache-SSL 1.x, mod_ssl 2.0.x Sioux -# 1.x and Stronghold 2.x. -# -# o The SSL_SDBM rule controls whether the built-in SDBM library should be -# used instead of a custom defined or vendor supplied DBM library. Use the -# value 'default' for automatic determination or use 'yes' to force the use -# of SDBM in case the vendor DBM library is buggy or restricts the data -# sizes too dramatically. -# -# o The SSL_EXPERIMENTAL rule can be used to enable still experimental code -# inside mod_ssl. These are usually new features which need some more -# testing before they can be considered stable. So, enabled this on your own -# risk and only when you like to see Apache+mod_ssl dump core ;-) -# - -#SSL_BASE=/usr/local/ssl -#RSA_BASE=/usr/local/rsa -SSL_BASE=SYSTEM -Rule SSL_COMPAT=yes -Rule SSL_SDBM=default -Rule SSL_EXPERIMENTAL=no ################################################################ # Makefile configuration @@ -165,12 +124,12 @@ Rule SHARED_CHAIN=default # functions. The format is: Rule RULE=value # # At present, only the following RULES are known: WANTHSREGEX, SOCKS4, -# SOCKS5, IRIXNIS, IRIXN32 and PARANOID. +# SOCKS5, IRIXNIS, IRIXN32, PARANOID, and DEV_RANDOM. # -# For all Rules, if set to "yes", then Configure knows we want that -# capability and does what is required to add it in. If set to "default" -# then Configure makes a "best guess"; if set to anything else, or not -# present, then nothing is done. +# For all Rules except DEV_RANDOM, if set to "yes", then Configure knows +# we want that capability and does what is required to add it in. If set +# to "default" then Configure makes a "best guess"; if set to anything +# else, or not present, then nothing is done. # # SOCKS4: # If SOCKS4 is set to 'yes', be sure that you add the socks library @@ -201,12 +160,11 @@ Rule SHARED_CHAIN=default # is performing this function. If PARANOID is set to yes, it will # actually print-out the code that the modules execute # -# EAPI: -# Enable the Extended API which provides more module hooks, a generic -# low-level hook mechanism and a generic context mechanism. Please notice -# that enabling this rule forces you to recompile (with -DEAPI) all existing -# modules which are already built and installed as DSOs. Because under EAPI -# the module configuration structure has a different size. +# EXPAT: +# Include James Clark's Expat package into Apache, for use by the +# modules. The "default" is to include it if the lib/expat-lite/ +# directory is present. This rule will always be interpreted as "no" +# if the directory is not present. # Rule SOCKS4=no @@ -214,7 +172,20 @@ Rule SOCKS5=no Rule IRIXNIS=no Rule IRIXN32=yes Rule PARANOID=no -Rule EAPI=no +Rule EXPAT=default + +# DEV_RANDOM: +# Note: this rule is only used when compiling mod_auth_digest. +# mod_auth_digest requires a cryptographically strong random seed for its +# random number generator. It knows two ways of getting this: 1) from +# a file or device (such as "/dev/random"), or 2) from the truerand +# library. If this rule is set to 'default' then Configure will choose +# to use /dev/random if it exists, else /dev/urandom if it exists, +# else the truerand library. To override this behaviour set DEV_RANDOM +# either to 'truerand' (to use the library) or to a device or file +# (e.g. '/dev/urandom'). If the truerand library is selected, Configure +# will assume "-L/usr/local/lib -lrand". +Rule DEV_RANDOM=default # The following rules should be set automatically by Configure. However, if # they are not set by Configure (because we don't know the correct value for @@ -256,6 +227,13 @@ Rule WANTHSREGEX=default # AddModule modules/experimental/mod_mmap_static.o +## mod_vhost_alias provides support for mass virtual hosting +## by dynamically changing the document root and CGI directory +## based on the host header or local IP address of the request. +## See "../htdocs/manual/vhosts/mass.html". + +# AddModule modules/standard/mod_vhost_alias.o + ## ## Config manipulation modules ## @@ -344,13 +322,6 @@ AddModule modules/standard/mod_actions.o AddModule modules/standard/mod_userdir.o -## The proxy module enables the server to act as a proxy for outside -## http and ftp services. It's not as complete as it could be yet. -## NOTE: You do not want this module UNLESS you are running a proxy; -## it is not needed for normal (origin server) operation. - -# AddModule modules/proxy/libproxy.a - ## The Alias module provides simple URL translation and redirection. AddModule modules/standard/mod_alias.o @@ -377,14 +348,39 @@ AddModule modules/standard/mod_auth.o ## "gdbm" package if not and possibly adjust EXTRA_LIBS. (This may be ## done by Configure at a later date) -AddModule modules/standard/mod_auth_dbm.o -AddModule modules/standard/mod_auth_db.o +# AddModule modules/standard/mod_auth_dbm.o +# AddModule modules/standard/mod_auth_db.o ## "digest" implements HTTP Digest Authentication rather than the less -## secure Basic Auth used by the other modules. +## secure Basic Auth used by the other modules. This is the old version. # AddModule modules/standard/mod_digest.o +## "auth_digest" implements HTTP/1.1 Digest Authentication (RFC 2617) +## rather than the less secure Basic Auth used by the other modules. +## This is an updated version of mod_digest, but it is not as well tested +## and is therefore marked experimental. Use either the one above, or +## this one below, but not both digest modules. +## Note: if you add this module in then you might also need the +## truerand library (available for example from +## ftp://research.att.com/dist/mab/librand.shar) - see the Rule +## DEV_RANDOM above for more info. +## +## Must be added above (run later than) the proxy module because the +## WWW-Authenticate and Proxy-Authenticate headers are parsed in the +## post-read-request phase and it needs to know if this is a proxy request. + +# AddModule modules/experimental/mod_auth_digest.o + +## Optional Proxy +## +## The proxy module enables the server to act as a proxy for outside +## http and ftp services. It's not as complete as it could be yet. +## NOTE: You do not want this module UNLESS you are running a proxy; +## it is not needed for normal (origin server) operation. + +# AddModule modules/proxy/libproxy.a + ## Optional response header manipulation modules. ## ## cern_meta mimics the behavior of the CERN web server with regards to @@ -440,9 +436,3 @@ AddModule modules/standard/mod_auth_db.o AddModule modules/standard/mod_setenvif.o -## mod_ssl incorporates SSL into Apache. -## It must stay last here to be first in execution to -## fake basic authorization. - -AddModule modules/ssl/libssl.a - diff --git a/usr.sbin/httpd/src/Configuration.tmpl b/usr.sbin/httpd/src/Configuration.tmpl index 351303ec0e8..35fdc590708 100644 --- a/usr.sbin/httpd/src/Configuration.tmpl +++ b/usr.sbin/httpd/src/Configuration.tmpl @@ -29,25 +29,21 @@ ################################################################ # SSL support: # -# o Set SSL_BASE to either the directory of your SSLeay -# source tree or the installation tree. Alternatively you can -# also use the value 'SYSTEM' which then indicates that SSLeay -# is installed under various system locations. -# -# o If you're a US-citizen you have to compile SSLeay with the -# RSAref library (which replaces the RSA code of SSLeay) -# because of patent legalities with the RSA algorithm used for -# the SSL protocol. For this situation you already have to -# compile SSLeay with the -DRSAref define and now you have to -# force Apache to link against the RSAglue library (from -# SSLeay) and the rsaref library (from RSA). So, set RSA_BASE -# to the directory of your RSAref source tree or to 'SYSTEM' -# (indicating that librsaref.a is installed under a system -# location) -# -# o Disable SSL_COMPAT rule to build mod_ssl without backward -# compatibility code for Apache-SSL 1.x, mod_ssl 2.0.x Sioux -# 1.x and Stronghold 2.x. +# o Set SSL_BASE to either the directory of your OpenSSL source tree or the +# installation tree. Alternatively you can also use the value 'SYSTEM' which +# then indicates that OpenSSL is installed under various system locations. +# +# o If you're a US-citizen you have to compile OpenSSL with the RSAref library +# (which replaces the RSA code of OpenSSL) because of patent legalities with +# the RSA algorithm used for the SSL protocol. For this situation you +# already have to compile OpenSSL with the -DRSAref define and now you have +# to force Apache to link against the RSAglue library (from OpenSSL) and the +# rsaref library (from RSA). So, set RSA_BASE to the directory of your +# RSAref source tree or to 'SYSTEM' (indicating that librsaref.a is +# installed under a system location) +# +# o Disable SSL_COMPAT rule to build mod_ssl without backward compatibility +# code for Apache-SSL 1.x, mod_ssl 2.0.x, Sioux 1.x and Stronghold 2.x. # # o The SSL_SDBM rule controls whether the built-in SDBM library should be # used instead of a custom defined or vendor supplied DBM library. Use the @@ -59,13 +55,18 @@ # inside mod_ssl. These are usually new features which need some more # testing before they can be considered stable. So, enabled this on your own # risk and only when you like to see Apache+mod_ssl dump core ;-) -# +# +# o The SSL_VENDOR rule can be used to enable code inside mod_ssl which can be +# used by product vendors to extend mod_ssl via EAPI hooks without patching +# the source. Additionally ssl_vendor*.c source files are automatically +# picked up by the compilation process. #SSL_BASE=/usr/local/ssl #RSA_BASE=/usr/local/rsa Rule SSL_COMPAT=yes Rule SSL_SDBM=default Rule SSL_EXPERIMENTAL=no +Rule SSL_VENDOR=no ################################################################ # Makefile configuration @@ -108,6 +109,24 @@ EXTRA_DEPS= #TARGET= ################################################################ +# Extended API (EAPI) support: +# +# EAPI: +# The EAPI rule enables more module hooks, a generic low-level hook +# mechanism, a generic context mechanism and shared memory based pools. +# +# EAPI_MM: +# Set the EAPI_MM variable to either the directory of a MM Shared Memory +# Library source tree or the installation tree of MM. Alternatively you can +# also use the value 'SYSTEM' which then indicates that MM is installed +# under various system locations. When the MM library files cannot be found +# the EAPI still can be built, but without shared memory pool support, of +# course. + +Rule EAPI=no +#EAPI_MM=SYSTEM + +################################################################ # Dynamic Shared Object (DSO) support # # There is experimental support for compiling the Apache core and @@ -164,12 +183,12 @@ Rule SHARED_CHAIN=default # functions. The format is: Rule RULE=value # # At present, only the following RULES are known: WANTHSREGEX, SOCKS4, -# SOCKS5, IRIXNIS, IRIXN32 and PARANOID. +# SOCKS5, IRIXNIS, IRIXN32, PARANOID, and DEV_RANDOM. # -# For all Rules, if set to "yes", then Configure knows we want that -# capability and does what is required to add it in. If set to "default" -# then Configure makes a "best guess"; if set to anything else, or not -# present, then nothing is done. +# For all Rules except DEV_RANDOM, if set to "yes", then Configure knows +# we want that capability and does what is required to add it in. If set +# to "default" then Configure makes a "best guess"; if set to anything +# else, or not present, then nothing is done. # # SOCKS4: # If SOCKS4 is set to 'yes', be sure that you add the socks library @@ -200,12 +219,11 @@ Rule SHARED_CHAIN=default # is performing this function. If PARANOID is set to yes, it will # actually print-out the code that the modules execute # -# EAPI: -# Enable the Extended API which provides more module hooks, a generic -# low-level hook mechanism and a generic context mechanism. Please notice -# that enabling this rule forces you to recompile (with -DEAPI) all existing -# modules which are already built and installed as DSOs. Because under EAPI -# the module configuration structure has a different size. +# EXPAT: +# Include James Clark's Expat package into Apache, for use by the +# modules. The "default" is to include it if the lib/expat-lite/ +# directory is present. This rule will always be interpreted as "no" +# if the directory is not present. # Rule SOCKS4=no @@ -213,7 +231,20 @@ Rule SOCKS5=no Rule IRIXNIS=no Rule IRIXN32=yes Rule PARANOID=no -Rule EAPI=no +Rule EXPAT=default + +# DEV_RANDOM: +# Note: this rule is only used when compiling mod_auth_digest. +# mod_auth_digest requires a cryptographically strong random seed for its +# random number generator. It knows two ways of getting this: 1) from +# a file or device (such as "/dev/random"), or 2) from the truerand +# library. If this rule is set to 'default' then Configure will choose +# to use /dev/random if it exists, else /dev/urandom if it exists, +# else the truerand library. To override this behaviour set DEV_RANDOM +# either to 'truerand' (to use the library) or to a device or file +# (e.g. '/dev/urandom'). If the truerand library is selected, Configure +# will assume "-L/usr/local/lib -lrand". +Rule DEV_RANDOM=default # The following rules should be set automatically by Configure. However, if # they are not set by Configure (because we don't know the correct value for @@ -255,6 +286,13 @@ Rule WANTHSREGEX=default # AddModule modules/experimental/mod_mmap_static.o +## mod_vhost_alias provides support for mass virtual hosting +## by dynamically changing the document root and CGI directory +## based on the host header or local IP address of the request. +## See "../htdocs/manual/vhosts/mass.html". + +# AddModule modules/standard/mod_vhost_alias.o + ## ## Config manipulation modules ## @@ -264,6 +302,11 @@ Rule WANTHSREGEX=default AddModule modules/standard/mod_env.o +## mod_define expands variables on arbitrary directive lines. +## It requires Extended API (EAPI). + +# AddModule modules/extra/mod_define.o + ## ## Request logging modules ## @@ -343,13 +386,6 @@ AddModule modules/standard/mod_actions.o AddModule modules/standard/mod_userdir.o -## The proxy module enables the server to act as a proxy for outside -## http and ftp services. It's not as complete as it could be yet. -## NOTE: You do not want this module UNLESS you are running a proxy; -## it is not needed for normal (origin server) operation. - -# AddModule modules/proxy/libproxy.a - ## The Alias module provides simple URL translation and redirection. AddModule modules/standard/mod_alias.o @@ -380,10 +416,35 @@ AddModule modules/standard/mod_auth.o # AddModule modules/standard/mod_auth_db.o ## "digest" implements HTTP Digest Authentication rather than the less -## secure Basic Auth used by the other modules. +## secure Basic Auth used by the other modules. This is the old version. # AddModule modules/standard/mod_digest.o +## "auth_digest" implements HTTP/1.1 Digest Authentication (RFC 2617) +## rather than the less secure Basic Auth used by the other modules. +## This is an updated version of mod_digest, but it is not as well tested +## and is therefore marked experimental. Use either the one above, or +## this one below, but not both digest modules. +## Note: if you add this module in then you might also need the +## truerand library (available for example from +## ftp://research.att.com/dist/mab/librand.shar) - see the Rule +## DEV_RANDOM above for more info. +## +## Must be added above (run later than) the proxy module because the +## WWW-Authenticate and Proxy-Authenticate headers are parsed in the +## post-read-request phase and it needs to know if this is a proxy request. + +# AddModule modules/experimental/mod_auth_digest.o + +## Optional Proxy +## +## The proxy module enables the server to act as a proxy for outside +## http and ftp services. It's not as complete as it could be yet. +## NOTE: You do not want this module UNLESS you are running a proxy; +## it is not needed for normal (origin server) operation. + +# AddModule modules/proxy/libproxy.a + ## Optional response header manipulation modules. ## ## cern_meta mimics the behavior of the CERN web server with regards to diff --git a/usr.sbin/httpd/src/Configure b/usr.sbin/httpd/src/Configure index b3b36170a9b..307bfc4b21b 100644 --- a/usr.sbin/httpd/src/Configure +++ b/usr.sbin/httpd/src/Configure @@ -64,6 +64,7 @@ # fp2rp: # slo.sh: +LANG=C; export LANG exitcode=0 trap 'rm -f $tmpfile $tmpfile2 $tmpfile3 $tmpconfig $awkfile; exit $exitcode' 0 1 2 3 15 @@ -76,7 +77,8 @@ tmpfile2=$tmpfile.2 tmpfile3=$tmpfile.3 awkfile=$tmpfile.4 tmpconfig=$tmpfile.5 -SUBDIRS="ap main modules" +SUBDIRS="ap main" +APLIBDIRS="" #################################################################### ## Now handle any arguments, which, for now, is -file @@ -90,12 +92,6 @@ while [ "x$1" != "x" ]; do exitcode=1 exit 1 fi - elif [ "x$1" = "x-make" ] ; then - shift 1; makefile_tmpl=$1; shift 1 - if [ ! -r $makefile_tmpl ]; then - echo "$makefile_tmpl does not exist or is not readable." - exit 1 - fi else echo "ERROR: Bad command line option '$1'" echo " Please read the file INSTALL." @@ -114,7 +110,7 @@ fi ## Now see if Configuration.tmpl is more recent than $file. If ## so, then we complain and bail out ## -if ls -lt Configuration.tmpl $file | head -1 | \ +if ls -lt $file Configuration.tmpl | head -1 | \ grep 'Configuration.tmpl' > /dev/null then echo "Configuration.tmpl is more recent than $file;" @@ -178,7 +174,7 @@ fi ## that the user was using the old default root directory ## and issue a notice about it. ## -if [ $file != "Configuration.apaci" ] +if [ "x$file" != "xConfiguration.apaci" ] then if [ -d /usr/local/etc/httpd/ ] then @@ -228,14 +224,14 @@ RULE_SOCKS5=`./helpers/CutRule SOCKS5 $file` RULE_IRIXNIS=`./helpers/CutRule IRIXNIS $file` RULE_IRIXN32=`./helpers/CutRule IRIXN32 $file` RULE_PARANOID=`./helpers/CutRule PARANOID $file` -RULE_EAPI=`./helpers/CutRule EAPI $file` +RULE_EXPAT=`./helpers/CutRule EXPAT $file` RULE_SHARED_CORE=`./helpers/CutRule SHARED_CORE $file` RULE_SHARED_CHAIN=`./helpers/CutRule SHARED_CHAIN $file` #################################################################### ## Rule SHARED_CORE implies required DSO support ## -if [ "$RULE_SHARED_CORE" = "yes" ]; then +if [ "x$RULE_SHARED_CORE" = "xyes" ]; then using_shlib=1 fi @@ -316,6 +312,8 @@ case "$PLAT" in OS='IBM AIX 4.3' CFLAGS="$CFLAGS -DAIX=43 -U__STR__" LDFLAGS="$LDFLAGS -lm" + RULE_SHARED_CORE=no + DEF_SHARED_CORE=no ;; *-ibm-aix*) OS='IBM AIX' @@ -335,8 +333,8 @@ case "$PLAT" in OSDIR="os/os2" DEF_WANTHSREGEX=yes OS='EMX OS/2' - CFLAGS="$CFLAGS -DOS2 -Zbsd-signals -Zbin-files -DTCPIPV4 -g" - LDFLAGS="$LDFLAGS -Zexe" + CFLAGS="$CFLAGS -DOS2 -DTCPIPV4 -g -Zmt" + LDFLAGS="$LDFLAGS -Zexe -Zmtd -Zsysv-signals -Zbin-files" LIBS="$LIBS -lsocket -lufc -lbsd" DBM_LIB="-lgdbm" SHELL=sh @@ -378,7 +376,7 @@ case "$PLAT" in echo "but if you would care to port to 64-bit, send us the patches." DEF_WANTHSREGEX=yes DBM_LIB="" - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX-64 w/NIS' CFLAGS="$CFLAGS -DIRIX" LIBS="$LIBS -lsun" @@ -390,14 +388,14 @@ case "$PLAT" in *-sgi-irix32) DEF_WANTHSREGEX=yes DBM_LIB="" - if [ "$RULE_IRIXN32" = "yes" ]; then - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX-32 w/NIS' else OS='SGI IRIX-32' fi else - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX w/NIS' else OS='SGI IRIX' @@ -409,7 +407,7 @@ case "$PLAT" in *-sgi-irix) DEF_WANTHSREGEX=yes DBM_LIB="" - if [ "$RULE_IRIXNIS" = "yes" ]; then + if [ "x$RULE_IRIXNIS" = "xyes" ]; then OS='SGI IRIX w/NIS' CFLAGS="$CFLAGS -DIRIX" LIBS="$LIBS -lsun" @@ -441,6 +439,11 @@ case "$PLAT" in DBM_LIB="" DB_LIB="" ;; + *-bsdi3) + if [ "x$using_shlib" = "x1" ] ; then + CC="shlicc2" + fi + ;; *-bsdi*) OS='BSDI' DBM_LIB="" @@ -458,7 +461,7 @@ case "$PLAT" in PLATOSVERS=`echo $PLAT | sed 's/^.*freebsd//'` OS="FreeBSD $PLATOSVERS" case "$PLATOSVERS" in - [23]*) + [234]*) DEF_WANTHSREGEX=no CFLAGS="$CFLAGS -funsigned-char" ;; @@ -484,14 +487,16 @@ case "$PLAT" in CC='cc' OPTIM='-O' CFLAGS="$CFLAGS -DNEXT" - CFLAGS_SHLIB='-dynamic -fno-common' - LD_SHLIB='cc' - LDFLAGS_SHLIB='-dynamiclib -undefined warning' DEF_WANTHSREGEX=yes ;; *-apple-rhapsody*) OS='Mac OS X Server' - CFLAGS="$CFLAGS -DRHAPSODY" + CFLAGS="$CFLAGS -DMAC_OS_X_SERVER" + DEF_WANTHSREGEX=yes + ;; + *-apple-macos*) + OS='Mac OS' + CFLAGS="$CFLAGS -DMAC_OS" DEF_WANTHSREGEX=yes ;; *-dec-osf*) @@ -600,6 +605,7 @@ case "$PLAT" in LIBS="$LIBS -lsocket -lnsl -lgen" LD_SHLIB='cc' LDFLAGS_SHLIB="-Zlink=so" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-Zlink=dynamic -Wl,-Bexport" CFLAGS_SHLIB='-Zpic' ;; @@ -615,10 +621,9 @@ case "$PLAT" in BS2000*-siemens-sysv4*) OS='BS2000' OSDIR='os/bs2000' - CC='c89 -XLLML -XLLMK' + CC='c89 -XLLML -XLLMK -XL' CFLAGS="$CFLAGS -DCHARSET_EBCDIC -DSVR4 -D_XPG_IV" DEF_WANTHSREGEX=yes - LIBS="$LIBS -lsocket -lnsl -lc" DBM_LIB="" ;; *-siemens-sysv4*) @@ -696,10 +701,41 @@ case "$PLAT" in OS='Paragon OSF/1' CFLAGS="$CFLAGS -DPARAGON" ;; - *DYNIX*) + *-sequent-ptx2.*.*) + DEF_WANTHSREGEX=yes + OS='SEQUENT DYNIX/ptx v2.*.*' + CFLAGS="$CFLAGS -DSEQUENT=20 -Wc,-pw" + LIBS="$LIBS -lsocket -linet -lnsl -lc -lseq" + ;; + *-sequent-ptx4.0.*) + DEF_WANTHSREGEX=yes + OS='SEQUENT DYNIX/ptx v4.0.*' + CFLAGS="$CFLAGS -DSEQUENT=40 -Wc,-pw" + LIBS="$LIBS -lsocket -linet -lnsl -lc" + ;; + *-sequent-ptx4.[123].*) + DEF_WANTHSREGEX=yes + OS='SEQUENT DYNIX/ptx v4.1.*/v4.2.*' + CFLAGS="$CFLAGS -DSEQUENT=41 -Wc,-pw" + LIBS="$LIBS -lsocket -lnsl -lc" + ;; + *-sequent-ptx4.4.*) + DEF_WANTHSREGEX=yes + OS='SEQUENT DYNIX/ptx v4.4.*' + CFLAGS="$CFLAGS -DSEQUENT=44 -Wc,-pw" + LIBS="$LIBS -lsocket -lnsl -lc" + ;; + *-sequent-ptx4.5.*) + DEF_WANTHSREGEX=yes + OS='SEQUENT DYNIX/ptx v4.5.*' + CFLAGS="$CFLAGS -DSEQUENT=45 -Wc,-pw" + LIBS="$LIBS -lsocket -lnsl -lc" + ;; + *-sequent-ptx5.0.*) DEF_WANTHSREGEX=yes - OS='SEQUENT' - CFLAGS="$CFLAGS -DSEQUENT" + OS='SEQUENT DYNIX/ptx v5.0.*' + CFLAGS="$CFLAGS -DSEQUENT=50 -Wc,-pw" + LIBS="$LIBS -lsocket -lnsl -lc" ;; *NEWS-OS*) DEF_WANTHSREGEX=yes @@ -737,6 +773,11 @@ case "$PLAT" in CC='cc' RANLIB='true' ;; + *-tandem-oss) + OS='Tandem OSS' + CFLAGS="-D_TANDEM_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" + CC='c89' + ;; *) # default: Catch systems we don't know about OS='Unknown and unsupported OS' echo Sorry, but we cannot grok \"$PLAT\" @@ -788,7 +829,7 @@ echo >>Makefile.config "SHELL=$SHELL" #################################################################### ## And adjust/override WANTHSREGEX as needed ## -if [ "$RULE_WANTHSREGEX" = "default" ]; then +if [ "x$RULE_WANTHSREGEX" = "xdefault" ]; then if [ "x$DEF_WANTHSREGEX" = "x" ]; then RULE_WANTHSREGEX=yes else @@ -915,6 +956,7 @@ TTARGET=`egrep '^TARGET=' Makefile.config | tail -1 | awk -F= '{print $2}'` ## TLD_SHLIB=`egrep '^LD_SHLIB=' Makefile.config | tail -1 | awk -F= '{print $2}'` TLDFLAGS_SHLIB=`egrep '^LDFLAGS_SHLIB=' Makefile.config | tail -1 | awk -F= '{print $2}'` +TLDFLAGS_MOD_SHLIB=`egrep '^LDFLAGS_MOD_SHLIB=' Makefile.config | tail -1 | awk -F= '{print $2}'` TLDFLAGS_SHLIB_EXPORT=`egrep '^LDFLAGS_SHLIB_EXPORT=' Makefile.config | tail -1 | awk -F= '{print $2}'` TCFLAGS_SHLIB=`egrep '^CFLAGS_SHLIB=' Makefile.config | tail -1 | awk -F= '{print $2}'` @@ -943,27 +985,36 @@ if [ "x$using_shlib" = "x1" ] ; then SHLIB_SUFFIX_NAME=so SHLIB_SUFFIX_DEPTH=all SHLIB_EXPORT_FILES=no + SHARED_CORE_EP='lib$(TARGET).ep' + SHCORE_IMPLIB='' case "$PLAT" in *-linux1) CFLAGS_SHLIB="-fpic" LDFLAGS_SHLIB="-Bshareable" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-rdynamic" ;; *-linux2) + LD_SHLIB="gcc" CFLAGS_SHLIB="-fpic" - LDFLAGS_SHLIB="-Bshareable" + LDFLAGS_SHLIB="-shared" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-rdynamic" SHLIB_SUFFIX_DEPTH=0 ;; *-freebsd2*) + LD_SHLIB="gcc" CFLAGS_SHLIB="-fpic" - LDFLAGS_SHLIB="-Bshareable" + LDFLAGS_SHLIB="-shared" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" SHLIB_SUFFIX_DEPTH=2 ;; - *-freebsd3*) + *-freebsd3*|*-freebsd4*) + LD_SHLIB="gcc" CFLAGS_SHLIB="-fpic" - LDFLAGS_SHLIB="-Bshareable" + LDFLAGS_SHLIB="-shared" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` if [ "x$OBJFORMAT" = "xelf" ]; then LDFLAGS_SHLIB_EXPORT="-Wl,-E" @@ -976,48 +1027,67 @@ if [ "x$using_shlib" = "x1" ] ; then *-openbsd*) CFLAGS_SHLIB="-fPIC" LDFLAGS_SHLIB="-Bforcearchive -Bshareable" - LDFLAGS_SHLIB_EXPORT="" - SHLIB_SUFFIX_DEPTH=2 - ;; - alpha-*-netbsd*|mips-*-netbsd*|powerpc-*-netbsd*) - CFLAGS_SHLIB="-fpic -DPIC" - LDFLAGS_SHLIB="-shared" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" SHLIB_SUFFIX_DEPTH=2 ;; *-netbsd*) - CFLAGS_SHLIB="-fpic -DPIC" - LDFLAGS_SHLIB="-Bshareable" - LDFLAGS_SHLIB_EXPORT="" + CFLAGS_SHLIB="-fPIC -DPIC" + if echo __ELF__ | ${CC} -E - | grep -q __ELF__; then + LDFLAGS_SHLIB="-Bshareable" + LDFLAGS_SHLIB_EXPORT="" + else + LDFLAGS_SHLIB="-shared" + LDFLAGS_SHLIB_EXPORT="-Wl,-E" + fi + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB SHLIB_SUFFIX_DEPTH=2 ;; + *-bsdi3) + LD_SHLIB="shlicc2" + LDFLAGS_SHLIB="-r" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB + ;; *-bsdi) CFLAGS_SHLIB="-fPIC" LDFLAGS_SHLIB="-shared" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-rdynamic" ;; - *-apple-rhapsody*) + *-next-openstep*) + LD_SHLIB='cc' + CFLAGS_SHLIB='-dynamic -fno-common' + LDFLAGS_SHLIB='-bundle -undefined warning' + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB + LDFLAGS_SHLIB_EXPORT='' + SHLIB_SUFFIX_DEPTH=0 + ;; + *-apple-rhapsody* | *-apple-macos* ) LD_SHLIB="cc" CFLAGS_SHLIB="" LDFLAGS_SHLIB='$(EXTRA_LDFLAGS) -bundle -undefined suppress' + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" SHLIB_SUFFIX_DEPTH=0 ;; *-solaris2*) - case $CC in - */gcc|gcc ) CFLAGS_SHLIB="-fpic" ;; - */cc|cc ) CFLAGS_SHLIB="-KPIC" ;; - esac + if [ "x`$CC -v 2>&1 | grep gcc`" != "x" ]; then + CFLAGS_SHLIB="-fPIC" + else + CFLAGS_SHLIB="-KPIC" + fi LDFLAGS_SHLIB="-G" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" SHLIB_SUFFIX_DEPTH=1 ;; *-sunos4*) case $CC in - */gcc|gcc ) CFLAGS_SHLIB="-fpic" ;; + */gcc|gcc ) CFLAGS_SHLIB="-fPIC" ;; */acc|acc ) CFLAGS_SHLIB="-pic" ;; esac LDFLAGS_SHLIB="-assert pure-text" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" ;; *-sgi-irix32) @@ -1031,11 +1101,12 @@ if [ "x$using_shlib" = "x1" ] ; then N32FLAG="-n32" ;; esac - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then LDFLAGS_SHLIB="$N32FLAG -shared" else LDFLAGS_SHLIB="-shared" fi + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" ;; *-sgi-irix64) @@ -1049,11 +1120,12 @@ if [ "x$using_shlib" = "x1" ] ; then N32FLAG="-n32" ;; esac - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then LDFLAGS_SHLIB="$N32FLAG -shared" else LDFLAGS_SHLIB="-shared" fi + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" ;; *-sgi-irix) @@ -1062,6 +1134,7 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="-KPIC" ;; esac LDFLAGS_SHLIB="-shared" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" ;; *-dec-osf*) @@ -1070,6 +1143,7 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="" ;; esac LDFLAGS_SHLIB="-shared -expect_unresolved '*' -s" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" ;; *-unixware*) @@ -1078,6 +1152,7 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="-KPIC" ;; esac LDFLAGS_SHLIB="-Bdynamic -G" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-Wl,-Bexport" ;; *-sco5*) @@ -1087,8 +1162,23 @@ if [ "x$using_shlib" = "x1" ] ; then esac LDFLAGS_SHLIB="-G" LDFLAGS_SHLIB_EXPORT="-Wl,-Bexport" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB SHLIB_SUFFIX_DEPTH=1 ;; + *-sequent-ptx*) + case $PLAT in + *-sequent-ptx2*) + ;; + *-sequent-ptx4.0*) + ;; + *-sequent-ptx*) + CFLAGS_SHLIB="-KPIC" + LDFLAGS_SHLIB="-G" + LDFLAGS_SHLIB_EXPORT="-Wl,-Bexport" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB + ;; + esac + ;; RM*-siemens-sysv4*) # MIPS hosts can take advantage of the LDFLAGS_SHLIB_EXPORT switch case $CC in @@ -1096,6 +1186,7 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="-KPIC" ;; esac LDFLAGS_SHLIB="-G" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-Wl,-Blargedynsym" ;; *-siemens-sysv4*) @@ -1105,6 +1196,7 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="-KPIC" ;; esac LDFLAGS_SHLIB="-G" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" SHLIB_SUFFIX_DEPTH=0 DEF_SHARED_CORE=yes @@ -1115,6 +1207,7 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="-KPIC" ;; esac LDFLAGS_SHLIB="-G" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="" DEF_SHARED_CORE=yes ;; @@ -1124,8 +1217,8 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="+z" ;; esac LDFLAGS_SHLIB="-b" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-Wl,-E -Wl,-B,deferred" - SHLIB_SUFFIX_NAME=sl ;; *-hp-hpux10.*|*-hp-hpux11.*) case $CC in @@ -1133,8 +1226,8 @@ if [ "x$using_shlib" = "x1" ] ; then */cc|cc ) CFLAGS_SHLIB="+z" ;; esac LDFLAGS_SHLIB="-b" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-Wl,-E -Wl,-B,deferred -Wl,+s" - SHLIB_SUFFIX_NAME=sl ;; *-ibm-aix*) case $CC in @@ -1149,6 +1242,7 @@ if [ "x$using_shlib" = "x1" ] ; then LDFLAGS_SHLIB="-H512 -T512 -bhalt:4 -bM:SRE -e _nostart" ;; esac + LDFLAGS_MOD_SHLIB="$LDFLAGS_SHLIB -bI:@libexecdir@/httpd.exp -lc" LDFLAGS_SHLIB="$LDFLAGS_SHLIB -bI:\$(SRCDIR)/support/httpd.exp " LDFLAGS_SHLIB="$LDFLAGS_SHLIB -bE:\`echo \$@|sed -e 's:\.so\$\$:.exp:'\`" LDFLAGS_SHLIB="$LDFLAGS_SHLIB -lc" @@ -1158,9 +1252,33 @@ if [ "x$using_shlib" = "x1" ] ; then *-*-powermax*) LD_SHLIB='cc' LDFLAGS_SHLIB="-Zlink=so" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="-Zlink=dynamic -Wl,-Bexport" CFLAGS_SHLIB='-Zpic' ;; + *-OS/2*) + DEF_SHARED_CORE=yes + LDFLAGS_SHLIB="`echo $LDFLAGS|sed -e s/-Zexe//` -Zdll" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB + SHLIB_SUFFIX_NAME=dll + SHLIB_SUFFIX_DEPTH=0 + LD_SHLIB=$CC + LD_SHCORE_DEF="ApacheCoreOS2.def" + LD_SHCORE_LIBS="$LIBS" + LIBS_SHLIB='$(SRCDIR)/ApacheCoreOS2.a -lsocket -lbsd $(EXTRA_LIBS)' + SHARED_CORE_EP='' + SHCORE_IMPLIB='ApacheCoreOS2.a' + OS_MODULE_INCLUDE='Makefile.OS2' + ;; + *-dgux) + case $CC in + */gcc|gcc ) CFLAGS_SHLIB="-fpic" ;; + esac + DEF_SHARED_CORE=yes + LDFLAGS_SHLIB="-G" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB + LDFLAGS_SHLIB_EXPORT="" + ;; *) ## ok, no known explict support for shared objects ## on this platform, but we give not up immediately. @@ -1186,6 +1304,7 @@ if [ "x$using_shlib" = "x1" ] ; then # so we can guess the flags from its knowledge CFLAGS_SHLIB="`$PERL -V:cccdlflags | cut -d\' -f2`" LDFLAGS_SHLIB="`$PERL -V:lddlflags | cut -d\' -f2`" + LDFLAGS_MOD_SHLIB=$LDFLAGS_SHLIB LDFLAGS_SHLIB_EXPORT="`$PERL -V:ccdlflags | cut -d\' -f2`" # but additionally we have to inform the # user that we are just guessing the flags @@ -1263,7 +1382,7 @@ case "$OS" in esac ;; *IRIX-64*) - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then case "$CC" in */cc|cc ) CFLAGS="$CFLAGS -n32" @@ -1273,7 +1392,7 @@ case "$OS" in fi ;; *IRIX-32*) - if [ "$RULE_IRIXN32" = "yes" ]; then + if [ "x$RULE_IRIXN32" = "xyes" ]; then case "$CC" in */cc|cc ) CFLAGS="$CFLAGS -n32" @@ -1329,11 +1448,30 @@ case "$PLAT" in *-dg-dgux*) # R4.11MU02 requires -lsocket -lnsl ... no idea if it's earlier or # later than what we already knew about. PR#732 - if ./helpers/TestCompile lib socket; then - LIBS="$LIBS -lsocket" + if ./helpers/TestCompile lib nsl; then + LIBS="$LIBS -lnsl" + TLIB='-lnsl' fi + if TLIB=$TLIB ./helpers/TestCompile lib socket; then + LIBS="-lsocket $LIBS" + fi + ;; + BS2000*-siemens-sysv4*) + # Depending on the BS2000 OS and compiler/crte release, + # -lnsl may be available (or may be not). + # In standard SVR4 systems, -lsocket relies on some symbols + # from -lnsl, so the test for -lnsl must appear first. if ./helpers/TestCompile lib nsl; then LIBS="$LIBS -lnsl" + TLIB='-lnsl' + fi + if TLIB=$TLIB ./helpers/TestCompile lib socket; then + LIBS="-lsocket $LIBS" + fi + if ./helpers/TestCompile func initgroups; then + : + else + CFLAGS="$CFLAGS -DNEED_INITGROUPS" fi ;; esac @@ -1342,7 +1480,7 @@ esac # We assume that if they are using SOCKS4, then they've # adjusted EXTRA_LIBS and/or EXTRA_LDFLAGS as required, # otherwise we assume "-L/usr/local/lib -lsocks" -if [ "$RULE_SOCKS4" = "yes" ]; then +if [ "x$RULE_SOCKS4" = "xyes" ]; then echo " + enabling SOCKS4 support" CFLAGS="$CFLAGS -DSOCKS -DSOCKS4" CFLAGS="$CFLAGS -Dconnect=Rconnect -Dselect=Rselect" @@ -1361,7 +1499,7 @@ fi # We assume that if they are using SOCKS5, then they've # adjusted EXTRA_LIBS and/or EXTRA_LDFLAGS as required, # otherwise we assume "-L/usr/local/lib -lsocks5" -if [ "$RULE_SOCKS5" = "yes" ]; then +if [ "x$RULE_SOCKS5" = "xyes" ]; then echo " + enabling SOCKS5 support" CFLAGS="$CFLAGS -DSOCKS -DSOCKS5" CFLAGS="$CFLAGS -Dconnect=SOCKSconnect -Dselect=SOCKSselect" @@ -1504,13 +1642,18 @@ for modfile in $MODFILES ; do sed '1,/ConfigStart/d;/ConfigEnd/,$d' $tmpfile2 > \ $tmpfile3 echo " o $modname uses ConfigStart/End" - if [ "$RULE_PARANOID" = "yes" ]; then + if [ "x$RULE_PARANOID" = "xyes" ]; then sed 's/^/>> /' $tmpfile3 fi . ./$tmpfile3 fi + if grep "Libs:" $tmpfile2 > /dev/null; then + modlibs1=`grep Libs: $tmpfile2 | sed 's/^.*Libs:[ ]*//'` + echo " o $modbase adds libraries: $modlibs1" + modlibs="$modlibs $modlibs1" + fi rm -f $tmpfile2 $tmpfile3 - if [ "$ext" != "so" ]; then + if [ "x$ext" != "x$SHLIB_SUFFIX_NAME" ]; then ext=o fi fi @@ -1518,11 +1661,11 @@ for modfile in $MODFILES ; do modname=`echo $modbase | sed 's/^.*\///' | \ sed 's/^mod_//' | sed 's/^lib//' | sed 's/$/_module/'` fi - if [ "$ext" != "so" ]; then + if [ "x$ext" != "x$SHLIB_SUFFIX_NAME" ]; then echo "Module $modname $modbase.$ext" >>$tmpfile fi # optionally generate export file for some linkers - if [ "$ext" = "so" -a "$SHLIB_EXPORT_FILES" = "yes" ]; then + if [ "x$ext" = "x$SHLIB_SUFFIX_NAME" -a "x$SHLIB_EXPORT_FILES" = "xyes" ]; then echo "$modname" >$modbase.exp fi done @@ -1532,34 +1675,107 @@ done ## Now HS's POSIX regex implementation if needed/wanted. We do it ## now since AddModule may have changed it ## -if [ "$RULE_WANTHSREGEX" = "yes" ]; then +if [ "x$RULE_WANTHSREGEX" = "xyes" ]; then REGLIB="regex/libregex.a" SUBDIRS="regex $SUBDIRS" CFLAGS="$CFLAGS -DUSE_HSREGEX" fi #################################################################### -# Extended API support: -if [ "$RULE_EAPI" = "yes" ]; then +## Extended API (EAPI) support: +## +if [ "x$RULE_EAPI" = "x" ]; then + RULE_EAPI=`./helpers/CutRule EAPI $file` +fi +if [ "x$RULE_EAPI" = "xyes" ]; then echo " + enabling Extended API (EAPI)" CFLAGS="$CFLAGS -DEAPI" # some vendor compilers are too restrictive + # for our ap_hook and ap_ctx sources. case "$OS:$CC" in *IRIX-32*:*/cc|*IRIX-32*:cc ) CFLAGS="$CFLAGS -woff 1048,1110,1164" ;; esac + # MM Shared Memory Library support for EAPI + if [ "x$EAPI_MM" = "x" ]; then + EAPI_MM=`egrep '^EAPI_MM=' $file | tail -1 | awk -F= '{print $2}'` + fi + if [ "x$EAPI_MM" != "x" ]; then + case $EAPI_MM in + SYSTEM|/* ) ;; + * ) for p in . .. ../..; do + if [ -d "$p/$EAPI_MM" ]; then + EAPI_MM="`echo $p/$EAPI_MM | sed -e 's;/\./;/;g'`" + break + fi + done + ;; + esac + if [ "x$EAPI_MM" = "xSYSTEM" ]; then + echo " using MM library for EAPI: (system-wide)" + CFLAGS="$CFLAGS -DEAPI_MM" + __INCLUDES="`mm-config --cflags`" + if [ "x$__INCLUDES" != "x-I/usr/include" ]; then + INCLUDES="$INCLUDES $__INCLUDES" + fi + LDFLAGS="$LDFLAGS `mm-config --ldflags`" + LIBS="$LIBS `mm-config --libs`" + else + if [ -f "$EAPI_MM/.libs/libmm.a" -a -f "$EAPI_MM/mm.h" ]; then + echo " using MM library: $EAPI_MM (source-tree only)" + case $EAPI_MM in + /* ) ;; + * ) EAPI_MM="\$(SRCDIR)/$EAPI_MM" ;; + esac + CFLAGS="$CFLAGS -DEAPI_MM" + INCLUDES="$INCLUDES -I$EAPI_MM" + LDFLAGS="$LDFLAGS -L$EAPI_MM/.libs" + LIBS="$LIBS -lmm" + elif [ -f "$EAPI_MM/bin/mm-config" ]; then + echo " using MM library: $EAPI_MM (installed)" + CFLAGS="$CFLAGS -DEAPI_MM" + INCLUDES="$INCLUDES `$EAPI_MM/bin/mm-config --cflags`" + LDFLAGS="$LDFLAGS `$EAPI_MM/bin/mm-config --ldflags`" + LIBS="$LIBS `$EAPI_MM/bin/mm-config --libs`" + else + echo "Configure:Error: Cannot find MM library under $EAPI_MM" 1>&2 + exit 1 + fi + fi + fi +fi + + +#################################################################### +## Add in the Expat library if needed/wanted. +## +if [ -d ./lib/expat-lite/ ]; then + if [ "x$RULE_EXPAT" = "xdefault" ]; then + RULE_EXPAT=yes + fi +else + if [ "$xRULE_EXPAT" = "xyes" ]; then + echo "ERROR: RULE_EXPAT set to \"yes\" but is not available." + exit 1 + else + RULE_EXPAT=no + fi +fi +if [ "x$RULE_EXPAT" = "xyes" ]; then + EXPATLIB="lib/expat-lite/libexpat.a" + APLIBDIRS="expat-lite $APLIBDIRS" + CFLAGS="$CFLAGS -DUSE_EXPAT -I\$(SRCDIR)/lib/expat-lite" fi #################################################################### ## Now the SHARED_CHAIN stuff ## -LIBS_SHLIB='' if [ "x$using_shlib" = "x1" ] ; then - if [ "$RULE_SHARED_CHAIN" = "default" ] ; then + if [ "x$RULE_SHARED_CHAIN" = "xdefault" ] ; then RULE_SHARED_CHAIN=$DEF_SHARED_CHAIN fi - if [ "$RULE_SHARED_CHAIN" = "yes" ]; then + if [ "x$RULE_SHARED_CHAIN" = "xyes" ]; then echo " + enabling DSO files to be linked against others" # determine libraries which can be safely linked # to our DSO files, i.e. PIC libraries and shared libraries @@ -1574,10 +1790,10 @@ fi ## Now the SHARED_CORE stuff ## if [ "x$using_shlib" = "x1" ] ; then - if [ "$RULE_SHARED_CORE" = "default" ] ; then + if [ "x$RULE_SHARED_CORE" = "xdefault" ] ; then RULE_SHARED_CORE=$DEF_SHARED_CORE fi - if [ "$RULE_SHARED_CORE" = "yes" ]; then + if [ "x$RULE_SHARED_CORE" = "xyes" ]; then echo " + enabling generation of Apache core as DSO" # shuffle compiler flags from shlib variant to standard CFLAGS="$CFLAGS $CFLAGS_SHLIB" @@ -1587,20 +1803,20 @@ if [ "x$using_shlib" = "x1" ] ; then # select the special subtarget for shared core generation SUBTARGET=target_shared # determine additional suffixes for libhttpd.so - V=1 R=3 P=4 - if [ "$SHLIB_SUFFIX_DEPTH" = "0" ]; then + V=1 R=3 P=9 + if [ "x$SHLIB_SUFFIX_DEPTH" = "x0" ]; then SHLIB_SUFFIX_LIST="" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "1" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "x1" ]; then SHLIB_SUFFIX_LIST="$V" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "2" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "x2" ]; then SHLIB_SUFFIX_LIST="$V.$R" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "3" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "x3" ]; then SHLIB_SUFFIX_LIST="$V.$R.$P" fi - if [ "$SHLIB_SUFFIX_DEPTH" = "all" ]; then + if [ "x$SHLIB_SUFFIX_DEPTH" = "xall" ]; then SHLIB_SUFFIX_LIST="$V $V.$R $V.$R.$P" fi fi @@ -1623,6 +1839,13 @@ if [ "x$using_shlib" = "x1" ] ; then if [ "x$TLDFLAGS_SHLIB_EXPORT" = "x" ]; then echo "LDFLAGS_SHLIB_EXPORT=$LDFLAGS_SHLIB_EXPORT" >> Makefile.config fi + if [ "x$TLDFLAGS_MOD_SHLIB" = "x" ]; then + echo "LDFLAGS_MOD_SHLIB=$LDFLAGS_MOD_SHLIB" >> Makefile.config + fi + echo "LD_SHCORE_DEF=$LD_SHCORE_DEF" >> Makefile.config + echo "LD_SHCORE_LIBS=$LD_SHCORE_LIBS" >> Makefile.config + echo "SHARED_CORE_EP=$SHARED_CORE_EP" >> Makefile.config + echo "SHCORE_IMPLIB=$SHCORE_IMPLIB" >> Makefile.config fi #################################################################### @@ -1763,10 +1986,11 @@ echo "" >>Makefile #################################################################### ## Now add the target for the main Makefile ## -echo "SUBDIRS=$SUBDIRS" >> Makefile +echo "SUBDIRS=$SUBDIRS lib modules" >> Makefile echo "SUBTARGET=$SUBTARGET" >> Makefile echo "SHLIB_SUFFIX_NAME=$SHLIB_SUFFIX_NAME" >> Makefile echo "SHLIB_SUFFIX_LIST=$SHLIB_SUFFIX_LIST" >> Makefile +echo "SHLIB_EXPORT_FILES=$SHLIB_EXPORT_FILES" >> Makefile echo "" >> Makefile #################################################################### @@ -1791,6 +2015,7 @@ echo "LIBS_SHLIB=$LIBS_SHLIB" >>Makefile.config echo "LDFLAGS1=$LDFLAGS" >>Makefile.config echo "MFLAGS_STATIC=$MFLAGS_STATIC" >>Makefile.config echo "REGLIB=$REGLIB" >>Makefile.config +echo "EXPATLIB=$EXPATLIB" >>Makefile.config echo "RANLIB=$RANLIB" >>Makefile.config #################################################################### @@ -1803,6 +2028,17 @@ if [ "x$using_shlib" = "x1" ] ; then *-ibm-aix* ) DL_LIB="-lld" ;; + *-sequent-ptx* ) + case $PLAT in + *-sequent-ptx2*) + ;; + *-sequent-ptx4.0*) + ;; + *-sequent-ptx*) + DL_LIB="-ldl" + ;; + esac + ;; *-hp-hpux*) if ./helpers/TestCompile func shl_load; then : @@ -1829,6 +2065,93 @@ if [ "x$using_shlib" = "x1" ] ; then fi #################################################################### +## More building ap_config_auto.h +## +## We check the sizeof various data types +## +echo " + checking sizeof various data types" +AP_TYPE_QUAD=`./helpers/TestCompile -r sizeof 'long long'` +if [ "x$AP_TYPE_QUAD" = "x" ]; then + AP_TYPE_QUAD="unknown_quad" + AP_LONGEST_LONG="long" +else + AP_LONGEST_LONG="long long" +fi + +echo "" >>$AP_CONFIG_AUTO_H +echo "/* determine: longest possible integer type */" >>$AP_CONFIG_AUTO_H +echo "#ifndef AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H +echo "#define AP_LONGEST_LONG $AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H +echo "#endif" >>$AP_CONFIG_AUTO_H + +#################################################################### +## More building ap_config_auto.h +## +## We check for the endianess of the machine +## +AP_BYTE_ORDER=`./helpers/TestCompile -r byteorder` +if [ "x$AP_BYTE_ORDER" = "x21" ]; then + AP_BYTE_ORDER="21" # big endian +else + AP_BYTE_ORDER="12" # little endian +fi + +echo "" >>$AP_CONFIG_AUTO_H +echo "/* determine: byte order of machine (12: little endian, 21: big endian) */" >>$AP_CONFIG_AUTO_H +echo "#ifndef AP_BYTE_ORDER" >>$AP_CONFIG_AUTO_H +echo "#define AP_BYTE_ORDER $AP_BYTE_ORDER" >>$AP_CONFIG_AUTO_H +echo "#endif" >>$AP_CONFIG_AUTO_H + +## +## Now compare the sizes of off_t to long +## +AP_TYPE_OFF_T=`./helpers/TestCompile -r sizeof off_t` +if [ "x$AP_TYPE_OFF_T" = "x" ]; then + AP_TYPE_OFF_T="unknown_off_t" +fi + +AP_TYPE_LONG=`./helpers/TestCompile -r sizeof long` +if [ "x$AP_TYPE_LONG" = "x" ]; then + AP_TYPE_LONG="unknown_long" +fi + +if [ "x$AP_TYPE_OFF_T" != "x$AP_TYPE_LONG" ]; then + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is off_t a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_OFF_T_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#define AP_OFF_T_IS_QUAD 1" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +else + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is off_t a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_OFF_T_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#undef AP_OFF_T_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +fi + +## +## Now see of void * is as big as a quad (long long) +## +AP_TYPE_VOID_P=`./helpers/TestCompile -r sizeof 'void *'` +if [ "x$AP_TYPE_VOID_P" = "x" ]; then + AP_TYPE_VOID_P="unknown_void_p" +fi + +if [ "x$AP_TYPE_VOID_P" = "x$AP_TYPE_QUAD" ]; then + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is void * a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_VOID_P_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#define AP_VOID_P_IS_QUAD 1" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +else + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is void * a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_VOID_P_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#undef AP_VOID_P_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +fi + +#################################################################### ## Finish building ap_config_auto.h ## ## We pick out all -D's from CFLAGS and insert them as defines into @@ -1838,14 +2161,13 @@ fi TEXTRA_CFLAGS=`egrep '^EXTRA_CFLAGS=' Makefile.config | tail -1 |\ sed -e 's;^EXTRA_CFLAGS=;;' -e 's;\`.*\`;;'` tmpstr=`echo $CFLAGS $TEXTRA_CFLAGS |\ - sed -e 's;[ ]-;!-;g' -e 's/\\\"/\"/g' -e 's/\([^\\]\)"/\1/g'` + sed -e 's;[ ]\([+-]\);!\1;g' -e 's/\([^\\\]\)"/\1/g' -e 's/\\\"/\"/g'` OIFS="$IFS" IFS='!' for cflag in $tmpstr; do echo "$cflag" >>$tmpconfig done IFS="$OIFS" -if [ -r $tmpconfig ]; then awk >>$AP_CONFIG_AUTO_H <$tmpconfig ' /^-D.*/ { i = index($0, "=") @@ -1861,7 +2183,6 @@ awk >>$AP_CONFIG_AUTO_H <$tmpconfig ' printf ("#ifndef %s\n#define %s %s\n#endif\n", define, define, value) } ' -fi # finish header file echo "" >>$AP_CONFIG_AUTO_H @@ -1870,7 +2191,7 @@ echo "#endif /* AP_CONFIG_AUTO_H */" >>$AP_CONFIG_AUTO_H #################################################################### ## Finish creating the Makefile.config file ## -echo "LIBS1=$LIBS">> Makefile.config +echo "LIBS1=$modlibs $LIBS">> Makefile.config echo "##" >> Makefile.config echo "## (End of automatically generated section)">> Makefile.config echo "##" >> Makefile.config @@ -1881,7 +2202,7 @@ echo "" >> Makefile.config ## check ## -if [ "$OS" = "TPF" ] ; then +if [ "x$OS" = "xTPF" ] ; then : else echo " + doing sanity check on compiler and options" @@ -1908,7 +2229,7 @@ $CAT Makefile.config >> Makefile sed -e "s#@@Configuration@@#$file#" "Makefile.tmpl" >>Makefile # xxx/Makefile -MAKEDIRS="support main ap regex $OSDIR" +MAKEDIRS="support $SUBDIRS" for dir in $MAKEDIRS ; do echo Creating Makefile in $dir ./helpers/mfhead $dir $file > $dir/Makefile @@ -1917,6 +2238,40 @@ for dir in $MAKEDIRS ; do done #################################################################### +## Now create the lib/Makefile +## +./helpers/mfhead modules $file > lib/Makefile +$CAT Makefile.config | sed -e 's:^SRCDIR=.*:SRCDIR=..:' >> lib/Makefile + +$CAT << EOF >> lib/Makefile +APLIBS=$APLIBDIRS +CFLAGS=\$(OPTIM) \$(CFLAGS1) \$(EXTRA_CFLAGS) + +default: all + +all clean distclean depend :: + @for i in \$(APLIBS) ""; do \\ + if [ "x\$\$i" != "x" ]; then \\ + echo "===> \$(SDP)lib/\$\$i"; \\ + (cd \$\$i && \$(MAKE) \$(MFLAGS_STATIC) SDP='\$(SDP)' CC='\$(CC)' AUX_CFLAGS='\$(CFLAGS)' RANLIB='\$(RANLIB)' \$@) || exit 1; \\ + echo "<=== \$(SDP)lib/\$\$i"; \\ + fi; \\ + done + +EOF + +#################################################################### +## Now create the lib/xxx/Makefile +## + +for dir in $APLIBDIRS ; do + echo Creating Makefile in lib/$dir + ./helpers/mfhead lib/$dir $file > lib/$dir/Makefile + $CAT Makefile.config lib/$dir/Makefile.tmpl |\ + sed -e "s:^SRCDIR=.*:SRCDIR=`./helpers/fp2rp lib/$dir`:" >> lib/$dir/Makefile +done + +#################################################################### ## Now create the modules/Makefile ## ./helpers/mfhead modules $file > modules/Makefile @@ -1929,10 +2284,12 @@ CFLAGS=\$(OPTIM) \$(CFLAGS1) \$(EXTRA_CFLAGS) default: all all clean distclean depend :: - @for i in \$(MODULES); do \\ + @for i in \$(MODULES) ""; do \\ + if [ "x\$\$i" != "x" ]; then \\ echo "===> \$(SDP)modules/\$\$i"; \\ (cd \$\$i && \$(MAKE) \$(MFLAGS_STATIC) SDP='\$(SDP)' CC='\$(CC)' AUX_CFLAGS='\$(CFLAGS)' RANLIB='\$(RANLIB)' \$@) || exit 1; \\ echo "<=== \$(SDP)modules/\$\$i"; \\ + fi; \\ done EOF @@ -2011,7 +2368,7 @@ dummy $(LIB): $(OBJS) ar cr $@ $(OBJS) $(RANLIB) $@ -.SUFFIXES: .o .so +.SUFFIXES: .o .so .dll .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< @@ -2039,6 +2396,10 @@ depend: EOF fi + if [ "x$OS_MODULE_INCLUDE" != "x" ]; then + echo "include $OS_MODULE_INCLUDE" >> $moddir/Makefile + fi + $CAT << 'EOF' >> $moddir/Makefile ## ## (End of automatically generated section) diff --git a/usr.sbin/httpd/src/Makefile.bsd-wrapper b/usr.sbin/httpd/src/Makefile.bsd-wrapper deleted file mode 100644 index 7de03ccf79a..00000000000 --- a/usr.sbin/httpd/src/Makefile.bsd-wrapper +++ /dev/null @@ -1,64 +0,0 @@ -# $OpenBSD: Makefile.bsd-wrapper,v 1.12 1999/03/08 17:42:42 beck Exp $ -.include <bsd.own.mk> -PROG=httpd -BINDIR=/usr/sbin -BINOWN=root -BINGRP=daemon -#MAN= httpd.8 - -all: Makefile - ${MAKE} - -.FORCE: .IGNORE - -helpers/GuessOS: - /usr/bin/lndir -s -e Makefile.bsd-wrapper -e obj -e obj.${MACHINE_ARCH} -e Configuration ${.CURDIR} ${.OBJDIR}; cp ${.CURDIR}/Configuration ${.OBJDIR}/Configuration - -config: .FORCE - touch ${.OBJDIR}/Configuration - PATH="/bin:/usr/bin:/sbin:/usr/sbin" \ - CC="${CC}" CFLAGS="${CFLAGS}" \ - sh ${.CURDIR}/Configure -file ${.OBJDIR}/Configuration -make ${.CURDIR}/Makefile.tmpl - -Makefile: helpers/GuessOS - # This is a nasty hack - @for f in CutRule GuessOS MakeEtags PrintPath TestCompile buildinfo.sh \ - checkheader.sh findcpp.sh fmn.sh fp2rp install.sh mfhead mkdir.sh \ - mkshadow.sh ppl.sh slo.sh; do \ - test -x ${.CURDIR}/helpers/$$f || \ - chmod +x ${.CURDIR}/helpers/$$f ; \ - done - touch ${.OBJDIR}/Configuration - PATH="/bin:/usr/bin:/sbin:/usr/sbin" \ - CC="${CC}" CFLAGS="${CFLAGS}" \ - sh ${.CURDIR}/Configure -file ${.OBJDIR}/Configuration -make ${.CURDIR}/Makefile.tmpl - -install: - ${INSTALL} ${INSTALL_COPY} ${INSTALL_STRIP} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} ${PROG} ${DESTDIR}${BINDIR} - -clean cleandir: -.if exists(${.OBJDIR}/Makefile) - ${MAKE} clean -.endif - /bin/rm -f Makefile - /bin/rm -f modules/standard/Makefile - /bin/rm -f modules/ssl/Makefile - /bin/rm -f modules/Makefile - /bin/rm -f support/Makefile - /bin/rm -f main/Makefile - /bin/rm -f ap/Makefile - /bin/rm -f regex/Makefile - /bin/rm -f os/unix/Makefile - /bin/rm -f Makefile.config - /bin/rm -f modules.c - - -depend: - # Nothing here yet -lint: - #Nothing here yet -tags: - #Nothing here yet - -.include<bsd.obj.mk> -.include<bsd.subdir.mk> diff --git a/usr.sbin/httpd/src/Makefile.nt b/usr.sbin/httpd/src/Makefile.nt index 68c9a10db26..02dc752f645 100644 --- a/usr.sbin/httpd/src/Makefile.nt +++ b/usr.sbin/httpd/src/Makefile.nt @@ -55,6 +55,10 @@ _build: cd ap nmake /nologo CFG="ap - Win32 %LONG%" -f ap.mak cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 %LONG%" -f htpasswd.mak + nmake /nologo CFG="htdigest - Win32 %LONG%" -f htdigest.mak + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 %LONG%" -f gen_uri_delims.mak nmake /nologo CFG="gen_test_char - Win32 %LONG%" -f gen_test_char.mak @@ -84,6 +88,7 @@ _install: -mkdir $(INSTDIR)\modules -mkdir $(INSTDIR)\logs -mkdir $(INSTDIR)\conf + -mkdir $(INSTDIR)\bin copy Apache%SHORT%\Apache.exe $(INSTDIR) copy Core%SHORT%\ApacheCore.dll $(INSTDIR) copy os\win32\ApacheModuleStatus%SHORT%\ApacheModuleStatus.dll $(INSTDIR)\modules @@ -97,6 +102,8 @@ _install: copy os\win32\ApacheModuleSpeling%SHORT%\ApacheModuleSpeling.dll $(INSTDIR)\modules copy os\win32\ApacheModuleUserTrack%SHORT%\ApacheModuleUserTrack.dll $(INSTDIR)\modules copy modules\proxy\%LONG%\ApacheModuleProxy.dll $(INSTDIR)\modules + copy support\%LONG%\htpasswd.exe $(INSTDIR)\bin + copy support\%LONG%\htdigest.exe $(INSTDIR)\bin _clean: cd os\win32 @@ -108,6 +115,10 @@ _clean: cd ap nmake /nologo CFG="ap - Win32 %LONG%" -f ap.mak clean cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 %LONG%" -f htpasswd.mak clean + nmake /nologo CFG="htdigest - Win32 %LONG%" -f htdigest.mak clean + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 %LONG%" -f gen_uri_delims.mak clean del uri_delims.h diff --git a/usr.sbin/httpd/src/Makefile.tmpl b/usr.sbin/httpd/src/Makefile.tmpl index b76ca00e433..a0b666a1efc 100644 --- a/usr.sbin/httpd/src/Makefile.tmpl +++ b/usr.sbin/httpd/src/Makefile.tmpl @@ -11,13 +11,20 @@ OBJS= \ $(OSDIR)/libos.a \ ap/libap.a -TYPE=test +TYPE= +ALGO= CRT= KEY= +VIEW= .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< +# Used to generate import library for OS/2 +.SUFFIXES: .def +.def.a: + emximp -o $@ $< + all: @@Configuration@@ $(TARGET) @@Configuration@@: Configuration.tmpl @@ -32,14 +39,15 @@ $(TARGET): $(EXTRA_DEPS) $(SUBTARGET) target_static: subdirs modules.o $(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ - -o $(TARGET) buildmark.o $(OBJS) $(REGLIB) $(LIBS) + -o $(TARGET) buildmark.o $(OBJS) $(REGLIB) $(EXPATLIB) $(LIBS) target_compile_only: subdirs modules.o $(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c -target_shared: lib$(TARGET).ep +target_shared: $(SHCORE_IMPLIB) $(SHARED_CORE_EP) lib$(TARGET).$(SHLIB_SUFFIX_NAME) $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ - -o $(TARGET) -DSHARED_CORE_BOOTSTRAP main/http_main.c + -o $(TARGET) -DSHARED_CORE_BOOTSTRAP main/http_main.c \ + ap/libap.a $(LIBS) $(SHCORE_IMPLIB) lib$(TARGET).ep: lib$(TARGET).$(SHLIB_SUFFIX_NAME) $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ @@ -48,7 +56,7 @@ lib$(TARGET).ep: lib$(TARGET).$(SHLIB_SUFFIX_NAME) lib$(TARGET).$(SHLIB_SUFFIX_NAME): subdirs modules.o $(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c - $(LD_SHLIB) $(LDFLAGS_SHLIB) -o lib$(TARGET).$(SHLIB_SUFFIX_NAME) buildmark.o $(OBJS) $(REGLIB) + $(LD_SHLIB) $(LDFLAGS_SHLIB) -o lib$(TARGET).$(SHLIB_SUFFIX_NAME) buildmark.o $(OBJS) $(REGLIB) $(EXPATLIB) $(LD_SHCORE_DEF) $(LD_SHCORE_LIBS) @if [ ".$(SHLIB_SUFFIX_LIST)" != . ]; then \ rm -f lib$(TARGET).$(SHLIB_SUFFIX_NAME).*; \ for suffix in $(SHLIB_SUFFIX_LIST) ""; do \ @@ -60,10 +68,10 @@ lib$(TARGET).$(SHLIB_SUFFIX_NAME): subdirs modules.o certificate: @./support/mkcert.sh \ - "$(MAKE)" "$(MFLAGS_STATIC)" \ + "$(MAKE)" "$(MFLAGS) $(MFLAGS_STATIC)" \ "$(SSL_PROGRAM)" ./support \ - "$(TYPE)" "$(CRT)" "$(KEY)" - @cd ../conf/ssl.crt; $(MAKE) $(MFLAGS_STATIC) SSLEAY=$(SSL_PROGRAM) >/dev/null 2>&1 + "$(TYPE)" "$(ALGO)" "$(CRT)" "$(KEY)" "$(VIEW)" + @cd ../conf/ssl.crt; $(MAKE) $(MFLAGS_STATIC) SSL_PROGRAM=$(SSL_PROGRAM) >/dev/null 2>&1 subdirs: @for i in $(SUBDIRS); do \ @@ -98,6 +106,7 @@ distclean: -rm -f modules.c -rm -f modules/Makefile -rm -f regex/Makefile + -rm -f lib/Makefile -rm -f Makefile.config -rm -f Makefile diff --git a/usr.sbin/httpd/src/Makefile_win32.txt b/usr.sbin/httpd/src/Makefile_win32.txt index bcd50c90a86..e4e3bc1e799 100644 --- a/usr.sbin/httpd/src/Makefile_win32.txt +++ b/usr.sbin/httpd/src/Makefile_win32.txt @@ -33,6 +33,10 @@ _build: cd ap nmake /nologo CFG="ap - Win32 Release" -f ap.mak cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Release" -f htpasswd.mak + nmake /nologo CFG="htdigest - Win32 Release" -f htdigest.mak + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Release" -f gen_uri_delims.mak nmake /nologo CFG="gen_test_char - Win32 Release" -f gen_test_char.mak @@ -62,6 +66,7 @@ _install: -mkdir $(INSTDIR)\modules -mkdir $(INSTDIR)\logs -mkdir $(INSTDIR)\conf + -mkdir $(INSTDIR)\bin copy ApacheR\Apache.exe $(INSTDIR) copy CoreR\ApacheCore.dll $(INSTDIR) copy os\win32\ApacheModuleStatusR\ApacheModuleStatus.dll $(INSTDIR)\modules @@ -75,6 +80,8 @@ _install: copy os\win32\ApacheModuleSpelingR\ApacheModuleSpeling.dll $(INSTDIR)\modules copy os\win32\ApacheModuleUserTrackR\ApacheModuleUserTrack.dll $(INSTDIR)\modules copy modules\proxy\Release\ApacheModuleProxy.dll $(INSTDIR)\modules + copy support\Release\htpasswd.exe $(INSTDIR)\bin + copy support\Release\htdigest.exe $(INSTDIR)\bin clean: cd os\win32 @@ -86,6 +93,10 @@ clean: cd ap nmake /nologo CFG="ap - Win32 Release" -f ap.mak clean cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Release" -f htpasswd.mak clean + nmake /nologo CFG="htdigest - Win32 Release" -f htdigest.mak clean + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Release" -f gen_uri_delims.mak clean del uri_delims.h diff --git a/usr.sbin/httpd/src/Makefile_win32_debug.txt b/usr.sbin/httpd/src/Makefile_win32_debug.txt index 599676f86ec..15817ee34b3 100644 --- a/usr.sbin/httpd/src/Makefile_win32_debug.txt +++ b/usr.sbin/httpd/src/Makefile_win32_debug.txt @@ -33,6 +33,10 @@ _build: cd ap nmake /nologo CFG="ap - Win32 Debug" -f ap.mak cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Debug" -f htpasswd.mak + nmake /nologo CFG="htdigest - Win32 Debug" -f htdigest.mak + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Debug" -f gen_uri_delims.mak nmake /nologo CFG="gen_test_char - Win32 Debug" -f gen_test_char.mak @@ -62,6 +66,7 @@ _install: -mkdir $(INSTDIR)\modules -mkdir $(INSTDIR)\logs -mkdir $(INSTDIR)\conf + -mkdir $(INSTDIR)\bin copy ApacheD\Apache.exe $(INSTDIR) copy CoreD\ApacheCore.dll $(INSTDIR) copy os\win32\ApacheModuleStatusD\ApacheModuleStatus.dll $(INSTDIR)\modules @@ -75,6 +80,8 @@ _install: copy os\win32\ApacheModuleSpelingD\ApacheModuleSpeling.dll $(INSTDIR)\modules copy os\win32\ApacheModuleUserTrackD\ApacheModuleUserTrack.dll $(INSTDIR)\modules copy modules\proxy\Debug\ApacheModuleProxy.dll $(INSTDIR)\modules + copy support\Debug\htpasswd.exe $(INSTDIR)\bin + copy support\Debug\htdigest.exe $(INSTDIR)\bin clean: cd os\win32 @@ -86,6 +93,10 @@ clean: cd ap nmake /nologo CFG="ap - Win32 Debug" -f ap.mak clean cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Debug" -f htpasswd.mak clean + nmake /nologo CFG="htdigest - Win32 Debug" -f htdigest.mak clean + cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Debug" -f gen_uri_delims.mak clean del uri_delims.h diff --git a/usr.sbin/httpd/src/ap/Makefile.tmpl b/usr.sbin/httpd/src/ap/Makefile.tmpl index 346b6b6df79..75209a1522c 100644 --- a/usr.sbin/httpd/src/ap/Makefile.tmpl +++ b/usr.sbin/httpd/src/ap/Makefile.tmpl @@ -5,8 +5,9 @@ LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS) LIB=libap.a -OBJS=ap_execve.o ap_cpystrn.o ap_signal.o \ - ap_slack.o ap_snprintf.o ap_fnmatch.o ap_hook.o ap_ctx.o +OBJS=ap_cpystrn.o ap_execve.o ap_fnmatch.o ap_getpass.o ap_md5c.o ap_signal.o \ + ap_slack.o ap_snprintf.o ap_sha1.o ap_checkpass.o ap_base64.o \ + ap_hook.o ap_ctx.o ap_mm.o .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< @@ -41,25 +42,38 @@ depend: # DO NOT REMOVE ap_cpystrn.o: ap_cpystrn.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ - $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/alloc.h \ - $(INCDIR)/buff.h $(INCDIR)/ap.h $(INCDIR)/util_uri.h + $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h ap_execve.o: ap_execve.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ - $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/alloc.h \ - $(INCDIR)/buff.h $(INCDIR)/ap.h $(INCDIR)/util_uri.h + $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h ap_fnmatch.o: ap_fnmatch.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ - $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(INCDIR)/ap_ctype.h \ - $(INCDIR)/hsregex.h $(INCDIR)/fnmatch.h + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/fnmatch.h +ap_getpass.o: ap_getpass.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/ap.h +ap_md5c.o: ap_md5c.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/ap_md5.h \ + $(INCDIR)/ap.h +ap_sha1.o: ap_sha1.c $(INCDIR)/ap_config.h $(INCDIR)/ap_sha1.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c ap_signal.o: ap_signal.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ - $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/alloc.h \ - $(INCDIR)/buff.h $(INCDIR)/ap.h $(INCDIR)/util_uri.h + $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h ap_slack.o: ap_slack.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ - $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/alloc.h \ - $(INCDIR)/buff.h $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ - $(INCDIR)/http_log.h + $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h $(INCDIR)/http_log.h ap_snprintf.o: ap_snprintf.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ - $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/alloc.h \ - $(INCDIR)/buff.h $(INCDIR)/ap.h $(INCDIR)/util_uri.h + $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h diff --git a/usr.sbin/httpd/src/ap/ap.dsp b/usr.sbin/httpd/src/ap/ap.dsp index bbcdda44e0a..9d9c3194f14 100644 --- a/usr.sbin/httpd/src/ap/ap.dsp +++ b/usr.sbin/httpd/src/ap/ap.dsp @@ -102,5 +102,21 @@ SOURCE=.\ap_snprintf.c # PROP Default_Filter "" # End Group +# Begin Source File + +SOURCE=.\ap_md5c.c +# End Source File +# Begin Source File + +SOURCE=.\ap_sha1.c +# End Source File +# Begin Source File + +SOURCE=.\ap_checkpass.c +# End Source File +# Begin Source File + +SOURCE=.\ap_base64.c +# End Source File # End Target # End Project diff --git a/usr.sbin/httpd/src/ap/ap.mak b/usr.sbin/httpd/src/ap/ap.mak index 1e7c74a81b0..84f7b22898b 100644 --- a/usr.sbin/httpd/src/ap/ap.mak +++ b/usr.sbin/httpd/src/ap/ap.mak @@ -25,8 +25,6 @@ NULL= NULL=nul !ENDIF -CPP=cl.exe - !IF "$(CFG)" == "ap - Win32 Release" OUTDIR=.\Release @@ -48,35 +46,77 @@ ALL : "$(OUTDIR)\ap.lib" CLEAN : -@erase "$(INTDIR)\ap_cpystrn.obj" -@erase "$(INTDIR)\ap_fnmatch.obj" + -@erase "$(INTDIR)\ap_md5c.obj" -@erase "$(INTDIR)\ap_hook.obj" -@erase "$(INTDIR)\ap_ctx.obj" + -@erase "$(INTDIR)\ap_mm.obj" -@erase "$(INTDIR)\ap_signal.obj" -@erase "$(INTDIR)\ap_slack.obj" -@erase "$(INTDIR)\ap_snprintf.obj" + -@erase "$(INTDIR)\ap_sha1.obj" + -@erase "$(INTDIR)\ap_base64.obj" + -@erase "$(INTDIR)\ap_checkpass.obj" -@erase "$(INTDIR)\vc50.idb" -@erase "$(OUTDIR)\ap.lib" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" +CPP=cl.exe CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D\ "_WINDOWS" /Fp"$(INTDIR)\ap.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\Release/ CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\ap.bsc" BSC32_SBRS= \ - + LIB32=link.exe -lib LIB32_FLAGS=/nologo /out:"$(OUTDIR)\ap.lib" LIB32_OBJS= \ "$(INTDIR)\ap_cpystrn.obj" \ "$(INTDIR)\ap_fnmatch.obj" \ + "$(INTDIR)\ap_md5c.obj" \ "$(INTDIR)\ap_hook.obj" \ "$(INTDIR)\ap_ctx.obj" \ + "$(INTDIR)\ap_mm.obj" \ "$(INTDIR)\ap_signal.obj" \ "$(INTDIR)\ap_slack.obj" \ - "$(INTDIR)\ap_snprintf.obj" + "$(INTDIR)\ap_snprintf.obj" \ + "$(INTDIR)\ap_sha1.obj" \ + "$(INTDIR)\ap_base64.obj" \ + "$(INTDIR)\ap_checkpass.obj" "$(OUTDIR)\ap.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) $(LIB32) @<< @@ -104,42 +144,27 @@ ALL : "$(OUTDIR)\ap.lib" CLEAN : -@erase "$(INTDIR)\ap_cpystrn.obj" -@erase "$(INTDIR)\ap_fnmatch.obj" + -@erase "$(INTDIR)\ap_md5c.obj" -@erase "$(INTDIR)\ap_hook.obj" -@erase "$(INTDIR)\ap_ctx.obj" + -@erase "$(INTDIR)\ap_mm.obj" -@erase "$(INTDIR)\ap_signal.obj" -@erase "$(INTDIR)\ap_slack.obj" -@erase "$(INTDIR)\ap_snprintf.obj" + -@erase "$(INTDIR)\ap_sha1.obj" + -@erase "$(INTDIR)\ap_base64.obj" + -@erase "$(INTDIR)\ap_checkpass.obj" -@erase "$(INTDIR)\vc50.idb" -@erase "$(OUTDIR)\ap.lib" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" +CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /GX /Z7 /Od /I "../include" /D "WIN32" /D "_DEBUG" /D\ "_WINDOWS" /Fp"$(INTDIR)\ap.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\Debug/ CPP_SBRS=. -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\ap.bsc" -BSC32_SBRS= \ - -LIB32=link.exe -lib -LIB32_FLAGS=/nologo /out:"$(OUTDIR)\ap.lib" -LIB32_OBJS= \ - "$(INTDIR)\ap_cpystrn.obj" \ - "$(INTDIR)\ap_fnmatch.obj" \ - "$(INTDIR)\ap_hook.obj" \ - "$(INTDIR)\ap_ctx.obj" \ - "$(INTDIR)\ap_signal.obj" \ - "$(INTDIR)\ap_slack.obj" \ - "$(INTDIR)\ap_snprintf.obj" - -"$(OUTDIR)\ap.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) - $(LIB32) @<< - $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) -<< - -!ENDIF .c{$(CPP_OBJS)}.obj:: $(CPP) @<< @@ -171,6 +196,33 @@ LIB32_OBJS= \ $(CPP_PROJ) $< << +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\ap.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +LIB32_FLAGS=/nologo /out:"$(OUTDIR)\ap.lib" +LIB32_OBJS= \ + "$(INTDIR)\ap_cpystrn.obj" \ + "$(INTDIR)\ap_fnmatch.obj" \ + "$(INTDIR)\ap_md5c.obj" \ + "$(INTDIR)\ap_hook.obj" \ + "$(INTDIR)\ap_ctx.obj" \ + "$(INTDIR)\ap_mm.obj" \ + "$(INTDIR)\ap_signal.obj" \ + "$(INTDIR)\ap_slack.obj" \ + "$(INTDIR)\ap_snprintf.obj" \ + "$(INTDIR)\ap_sha1.obj" \ + "$(INTDIR)\ap_base64.obj" \ + "$(INTDIR)\ap_checkpass.obj" + +"$(OUTDIR)\ap.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ENDIF + !IF "$(CFG)" == "ap - Win32 Release" || "$(CFG)" == "ap - Win32 Debug" SOURCE=.\ap_cpystrn.c @@ -180,17 +232,24 @@ SOURCE=.\ap_cpystrn.c DEP_CPP_AP_CP=\ "..\include\alloc.h"\ "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\buff.h"\ - "..\include\conf.h"\ "..\include\hsregex.h"\ "..\include\httpd.h"\ "..\include\util_uri.h"\ "..\os\win32\os.h"\ "..\os\win32\readdir.h"\ - + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + NODEP_CPP_AP_CP=\ - "..\include\apctype.h"\ - + "..\include\ap_config_auto.h"\ + "..\include\ebcdic.h"\ + "..\include\os.h"\ + "..\include\sfio.h"\ + "$(INTDIR)\ap_cpystrn.obj" : $(SOURCE) $(DEP_CPP_AP_CP) "$(INTDIR)" @@ -200,17 +259,16 @@ NODEP_CPP_AP_CP=\ DEP_CPP_AP_CP=\ "..\include\alloc.h"\ "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\buff.h"\ - "..\include\conf.h"\ "..\include\hsregex.h"\ "..\include\httpd.h"\ "..\include\util_uri.h"\ "..\os\win32\os.h"\ "..\os\win32\readdir.h"\ - -NODEP_CPP_AP_CP=\ - "..\include\hide.h"\ - + "$(INTDIR)\ap_cpystrn.obj" : $(SOURCE) $(DEP_CPP_AP_CP) "$(INTDIR)" @@ -218,23 +276,43 @@ NODEP_CPP_AP_CP=\ !ENDIF SOURCE=.\ap_fnmatch.c + +!IF "$(CFG)" == "ap - Win32 Release" + DEP_CPP_AP_FN=\ "..\include\ap_config.h"\ "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\fnmatch.h"\ "..\include\hsregex.h"\ "..\os\win32\os.h"\ {$(INCLUDE)}"sys\stat.h"\ {$(INCLUDE)}"sys\types.h"\ - + NODEP_CPP_AP_FN=\ "..\include\ap_config_auto.h"\ "..\include\os.h"\ - + "$(INTDIR)\ap_fnmatch.obj" : $(SOURCE) $(DEP_CPP_AP_FN) "$(INTDIR)" +!ELSEIF "$(CFG)" == "ap - Win32 Debug" + +DEP_CPP_AP_FN=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ + "..\include\fnmatch.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + + +"$(INTDIR)\ap_fnmatch.obj" : $(SOURCE) $(DEP_CPP_AP_FN) "$(INTDIR)" + + +!ENDIF + SOURCE=.\ap_signal.c !IF "$(CFG)" == "ap - Win32 Release" @@ -242,17 +320,24 @@ SOURCE=.\ap_signal.c DEP_CPP_AP_SI=\ "..\include\alloc.h"\ "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\buff.h"\ - "..\include\conf.h"\ "..\include\hsregex.h"\ "..\include\httpd.h"\ "..\include\util_uri.h"\ "..\os\win32\os.h"\ "..\os\win32\readdir.h"\ - + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + NODEP_CPP_AP_SI=\ - "..\include\apctype.h"\ - + "..\include\ap_config_auto.h"\ + "..\include\ebcdic.h"\ + "..\include\os.h"\ + "..\include\sfio.h"\ + "$(INTDIR)\ap_signal.obj" : $(SOURCE) $(DEP_CPP_AP_SI) "$(INTDIR)" @@ -262,17 +347,16 @@ NODEP_CPP_AP_SI=\ DEP_CPP_AP_SI=\ "..\include\alloc.h"\ "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\buff.h"\ - "..\include\conf.h"\ "..\include\hsregex.h"\ "..\include\httpd.h"\ "..\include\util_uri.h"\ "..\os\win32\os.h"\ "..\os\win32\readdir.h"\ - -NODEP_CPP_AP_SI=\ - "..\include\hide.h"\ - + "$(INTDIR)\ap_signal.obj" : $(SOURCE) $(DEP_CPP_AP_SI) "$(INTDIR)" @@ -286,18 +370,25 @@ SOURCE=.\ap_slack.c DEP_CPP_AP_SL=\ "..\include\alloc.h"\ "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\buff.h"\ - "..\include\conf.h"\ "..\include\hsregex.h"\ "..\include\http_log.h"\ "..\include\httpd.h"\ "..\include\util_uri.h"\ "..\os\win32\os.h"\ "..\os\win32\readdir.h"\ - + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + NODEP_CPP_AP_SL=\ - "..\include\apctype.h"\ - + "..\include\ap_config_auto.h"\ + "..\include\ebcdic.h"\ + "..\include\os.h"\ + "..\include\sfio.h"\ + "$(INTDIR)\ap_slack.obj" : $(SOURCE) $(DEP_CPP_AP_SL) "$(INTDIR)" @@ -307,18 +398,17 @@ NODEP_CPP_AP_SL=\ DEP_CPP_AP_SL=\ "..\include\alloc.h"\ "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\buff.h"\ - "..\include\conf.h"\ "..\include\hsregex.h"\ "..\include\http_log.h"\ "..\include\httpd.h"\ "..\include\util_uri.h"\ "..\os\win32\os.h"\ "..\os\win32\readdir.h"\ - -NODEP_CPP_AP_SL=\ - "..\include\hide.h"\ - + "$(INTDIR)\ap_slack.obj" : $(SOURCE) $(DEP_CPP_AP_SL) "$(INTDIR)" @@ -332,17 +422,24 @@ SOURCE=.\ap_snprintf.c DEP_CPP_AP_SN=\ "..\include\alloc.h"\ "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ "..\include\buff.h"\ - "..\include\conf.h"\ "..\include\hsregex.h"\ "..\include\httpd.h"\ "..\include\util_uri.h"\ "..\os\win32\os.h"\ "..\os\win32\readdir.h"\ - + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + NODEP_CPP_AP_SN=\ - "..\include\apctype.h"\ - + "..\include\ap_config_auto.h"\ + "..\include\ebcdic.h"\ + "..\include\os.h"\ + "..\include\sfio.h"\ + "$(INTDIR)\ap_snprintf.obj" : $(SOURCE) $(DEP_CPP_AP_SN) "$(INTDIR)" @@ -350,19 +447,176 @@ NODEP_CPP_AP_SN=\ !ELSEIF "$(CFG)" == "ap - Win32 Debug" DEP_CPP_AP_SN=\ - "..\include\conf.h"\ + "..\include\alloc.h"\ + "..\include\ap.h"\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ + "..\include\buff.h"\ "..\include\hsregex.h"\ + "..\include\httpd.h"\ + "..\include\util_uri.h"\ "..\os\win32\os.h"\ - -NODEP_CPP_AP_SN=\ - "..\include\hide.h"\ - + "..\os\win32\readdir.h"\ + "$(INTDIR)\ap_snprintf.obj" : $(SOURCE) $(DEP_CPP_AP_SN) "$(INTDIR)" !ENDIF +SOURCE=.\ap_md5c.c + +!IF "$(CFG)" == "ap - Win32 Release" + +DEP_CPP_AP_MD=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_md5.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_AP_MD=\ + "..\include\ap_config_auto.h"\ + "..\include\os.h"\ + ".\ebcdic.h"\ + + +"$(INTDIR)\ap_md5c.obj" : $(SOURCE) $(DEP_CPP_AP_MD) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ap - Win32 Debug" + +DEP_CPP_AP_MD=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_md5.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + + +"$(INTDIR)\ap_md5c.obj" : $(SOURCE) $(DEP_CPP_AP_MD) "$(INTDIR)" + + +!ENDIF + + +SOURCE=.\ap_checkpass.c + +!IF "$(CFG)" == "ap - Win32 Release" + +DEP_CPP_AP_CH=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_AP_CH=\ + "..\include\ap_config_auto.h"\ + "..\include\os.h"\ + ".\ebcdic.h"\ + + +"$(INTDIR)\ap_checkpass.obj" : $(SOURCE) $(DEP_CPP_AP_CH) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ap - Win32 Debug" + +DEP_CPP_AP_CH=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + + +"$(INTDIR)\ap_checkpass.obj" : $(SOURCE) $(DEP_CPP_AP_CH) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\ap_sha1.c + +!IF "$(CFG)" == "ap - Win32 Release" + +DEP_CPP_AP_SH=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_sha1.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_AP_SH=\ + "..\include\ap_config_auto.h"\ + "..\include\os.h"\ + ".\ebcdic.h"\ + + +"$(INTDIR)\ap_sha1.obj" : $(SOURCE) $(DEP_CPP_AP_SH) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ap - Win32 Debug" + +DEP_CPP_AP_SH=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_sha1.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + + +"$(INTDIR)\ap_sha1.obj" : $(SOURCE) $(DEP_CPP_AP_SH) "$(INTDIR)" + + +!ENDIF + +SOURCE=.\ap_base64.c + +!IF "$(CFG)" == "ap - Win32 Release" + +DEP_CPP_AP_BA=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + {$(INCLUDE)}"sys\stat.h"\ + {$(INCLUDE)}"sys\types.h"\ + +NODEP_CPP_AP_BA=\ + "..\include\ap_config_auto.h"\ + "..\include\os.h"\ + ".\ebcdic.h"\ + + +"$(INTDIR)\ap_base64.obj" : $(SOURCE) $(DEP_CPP_AP_BA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "ap - Win32 Debug" + +DEP_CPP_AP_BA=\ + "..\include\ap_config.h"\ + "..\include\ap_ctype.h"\ + "..\include\ap_mmn.h"\ + "..\include\hsregex.h"\ + "..\os\win32\os.h"\ + + +"$(INTDIR)\ap_base64.obj" : $(SOURCE) $(DEP_CPP_AP_BA) "$(INTDIR)" + + +!ENDIF !ENDIF diff --git a/usr.sbin/httpd/src/ap/ap_ctx.c b/usr.sbin/httpd/src/ap/ap_ctx.c index db457edae0e..f714fc3ac5a 100644 --- a/usr.sbin/httpd/src/ap/ap_ctx.c +++ b/usr.sbin/httpd/src/ap/ap_ctx.c @@ -60,6 +60,8 @@ ** Written by Ralf S. Engelschall <rse@engelschall.com> */ +#ifdef EAPI + #include "httpd.h" #include "ap_config.h" #include "ap_ctx.h" @@ -126,3 +128,28 @@ API_EXPORT(void *) ap_ctx_get(ap_ctx *ctx, char *key) return NULL; } +API_EXPORT(ap_ctx *) ap_ctx_overlay(pool *p, ap_ctx *over, ap_ctx *base) +{ + ap_ctx *new; + int i; + +#ifdef POOL_DEBUG + if (p != NULL) { + if (!ap_pool_is_ancestor(over->cr_pool, p)) + ap_log_assert("ap_ctx_overlay: overlay's pool is not an ancestor of p", + __FILE__, __LINE__); + if (!ap_pool_is_ancestor(base->cr_pool, p)) + ap_log_assert("ap_ctx_overlay: base's pool is not an ancestor of p", + __FILE__, __LINE__); + } +#endif + if ((new = ap_ctx_new(p)) == NULL) + return NULL; + memcpy(new->cr_entry, base->cr_entry, + sizeof(ap_ctx_entry *)*(AP_CTX_MAX_ENTRIES+1)); + for (i = 0; over->cr_entry[i] != NULL; i++) + ap_ctx_set(new, over->cr_entry[i]->ce_key, over->cr_entry[i]->ce_val); + return new; +} + +#endif /* EAPI */ diff --git a/usr.sbin/httpd/src/ap/ap_execve.c b/usr.sbin/httpd/src/ap/ap_execve.c index 435334610c1..e126b8a5d76 100644 --- a/usr.sbin/httpd/src/ap/ap_execve.c +++ b/usr.sbin/httpd/src/ap/ap_execve.c @@ -126,8 +126,10 @@ int ap_execle(const char *filename, const char *argv0, ...) } va_end(adummy); - if ((argv = (char **) malloc((argc + 2) * sizeof(*argv))) == NULL) + if ((argv = (char **) malloc((argc + 2) * sizeof(*argv))) == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_execle()!\n"); return -1; + } /* Pass two --- copy the argument strings into the result space */ va_start(adummy, argv0); @@ -222,8 +224,10 @@ int ap_execve(const char *filename, const char *argv[], else { int i = count_args(argv) + 1; /* +1 for leading SHELL_PATH */ - if ((script_argv = malloc(sizeof(*script_argv) * i)) == NULL) + if ((script_argv = malloc(sizeof(*script_argv) * i)) == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_execve()!\n"); return -1; + } script_argv[0] = SHELL_PATH; @@ -345,6 +349,10 @@ static const char **hashbang(const char *filename, char **argv) newargv = (char **) malloc((p - lbuf + 1) + (i + sargc + 1) * sizeof(*newargv)); + if (newargv == NULL) { + fprintf(stderr, "Ouch! Out of memory in hashbang()!\n"); + return NULL; + } ws = &((char *) newargv)[(i + sargc + 1) * sizeof(*newargv)]; /* Copy entries to allocated memory */ diff --git a/usr.sbin/httpd/src/ap/ap_hook.c b/usr.sbin/httpd/src/ap/ap_hook.c index 532001bd417..3f649b63928 100644 --- a/usr.sbin/httpd/src/ap/ap_hook.c +++ b/usr.sbin/httpd/src/ap/ap_hook.c @@ -62,7 +62,8 @@ ** Implementation of a Generic Hook Interface for Apache ** Written by Ralf S. Engelschall <rse@engelschall.com> ** -** See ap_hook.h for documentation. +** See POD document at end of ap_hook.h for description. +** View it with the command ``pod2man ap_hook.h | nroff -man | more'' ** ** Attention: This source file is a little bit tricky. ** It's a combination of a C source and an embedded Perl script @@ -77,6 +78,8 @@ * -- D. E. Knuth */ +#ifdef EAPI + #include "httpd.h" #include "http_log.h" #include "ap_config.h" @@ -208,7 +211,7 @@ API_EXPORT(int) ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode mode else { he->he_sig = sig; he->he_modeid = modeid; - if (modeid == AP_HOOK_MODE_DECLINE) { + if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) { if (AP_HOOK_SIG_HAS(sig, RC, char)) he->he_modeval.v_char = va_arg(ap, va_type(char)); else if (AP_HOOK_SIG_HAS(sig, RC, int)) @@ -313,7 +316,7 @@ API_EXPORT(int) ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode modeid, .. va_start(ap, modeid); - if (modeid == AP_HOOK_MODE_DECLINE) { + if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) { if (AP_HOOK_SIG_HAS(sig, RC, char)) modeval.v_char = va_arg(ap, va_type(char)); else if (AP_HOOK_SIG_HAS(sig, RC, int)) @@ -393,6 +396,7 @@ API_EXPORT(int) ap_hook_call(char *hook, ...) static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf) { void *v_rc; + ap_hook_value v_tmp; int rc; /* @@ -444,21 +448,20 @@ static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf) * * 3. Actually currently used hooks. * - * int func(ptr,ptr,int) e.g. ap::buff::read [http_main.c] - * int func(ptr,ptr,int) e.g. ap::buff::write [http_main.c] - * int func(ptr,ptr,int) e.g. ap::buff::writev [http_main.c] - * int func(ptr,ptr,int) e.g. ap::buff::sendwithtimeout [http_main.c] - * int func(ptr,ptr,int) e.g. ap::buff::recvwithtimeout [http_main.c] - * int func(ptr,ptr) e.g. ap::mod_proxy::canon [mod_proxy.c] - * int func(ptr,ptr,ptr,int) e.g. ap::mod_proxy::http::canon [mod_proxy.c] - * int func(ptr,ptr,ptr,ptr,int) e.g. ap::mod_proxy::http::handler [mod_proxy.c] - * int func(ptr,ptr) e.g. ap::mod_proxy::error [mod_proxy.c] - * int func(ptr,ptr,ptr,ptr,int,ptr) e.g. ap::mod_proxy::handler [mod_proxy.c] - * int func(ptr) e.g. ap::mod_proxy::http::handler::set_destport [proxy_http.c] - * ptr func(ptr,ptr) e.g. ap::mod_proxy::http::handler::new_connection [proxy_http.c] - * int func(ptr,ptr,ptr,int,ptr) e.g. ap::mod_proxy::http::handler::write_host_header [proxy_http.c] - * ptr func(ptr,ptr,ptr,ptr,ptr) e.g. ap::mod_ssl::var_lookup [ssl_engine_vars.c] - * ptr func(ptr,ptr) e.g. ap::mod_rewrite::lookup_variable [mod_rewrite.c] + * int func(ptr) [2x] + * int func(ptr,ptr) [2x] + * int func(ptr,ptr,int) [5x] + * int func(ptr,ptr,ptr,int) [1x] + * int func(ptr,ptr,ptr,int,ptr) [1x] + * int func(ptr,ptr,ptr,ptr,int) [1x] + * int func(ptr,ptr,ptr,ptr,int,ptr) [1x] + * ptr func(ptr,ptr) [3x] + * ptr func(ptr,ptr,ptr,ptr,ptr) [1x] + * void func(ptr) [2x] + * void func(ptr,int,int) [1x] + * void func(ptr,ptr) [5x] + * void func(ptr,ptr,ptr) [3x] + * void func(ptr,ptr,ptr,ptr) [2x] * * To simplify the programming task we generate the actual dispatch code * for these calls via the embedded Perl script at the end of this source @@ -473,8 +476,27 @@ static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf) rc = TRUE; v_rc = NULL; - if (!AP_HOOK_SIG_HAS(he->he_sig, RC, void)) - v_rc = va_arg(ap, void *); + if (!AP_HOOK_SIG_HAS(he->he_sig, RC, void)) { + if (he->he_modeid == AP_HOOK_MODE_DECLTMP) { + /* the return variable is a temporary one */ + if (AP_HOOK_SIG_HAS(he->he_sig, RC, char)) + v_rc = &v_tmp.v_char; + else if (AP_HOOK_SIG_HAS(he->he_sig, RC, int)) + v_rc = &v_tmp.v_int; + else if (AP_HOOK_SIG_HAS(he->he_sig, RC, long)) + v_rc = &v_tmp.v_long; + else if (AP_HOOK_SIG_HAS(he->he_sig, RC, float)) + v_rc = &v_tmp.v_float; + else if (AP_HOOK_SIG_HAS(he->he_sig, RC, double)) + v_rc = &v_tmp.v_double; + else if (AP_HOOK_SIG_HAS(he->he_sig, RC, ptr)) + v_rc = &v_tmp.v_ptr; + } + else { + /* the return variable is provided by caller */ + v_rc = va_arg(ap, void *); + } + } /* ----BEGIN GENERATED SECTION-------- */ if (he->he_sig == AP_HOOK_SIG1(void)) { @@ -708,6 +730,16 @@ static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf) *((int *)v_rc) = ((int(*)(void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4); rc = (*((int *)v_rc) != he->he_modeval.v_int); } + else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, int, ptr)) { + /* Call: int func(ptr,ptr,ptr,int,ptr) */ + void *v1 = va_arg(ap, va_type(ptr)); + void *v2 = va_arg(ap, va_type(ptr)); + void *v3 = va_arg(ap, va_type(ptr)); + int v4 = va_arg(ap, va_type(int)); + void *v5 = va_arg(ap, va_type(ptr)); + *((int *)v_rc) = ((int(*)(void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5); + rc = (*((int *)v_rc) != he->he_modeval.v_int); + } else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, ptr, int)) { /* Call: int func(ptr,ptr,ptr,ptr,int) */ void *v1 = va_arg(ap, va_type(ptr)); @@ -729,16 +761,6 @@ static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf) *((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5, v6); rc = (*((int *)v_rc) != he->he_modeval.v_int); } - else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, int, ptr)) { - /* Call: int func(ptr,ptr,ptr,int,ptr) */ - void *v1 = va_arg(ap, va_type(ptr)); - void *v2 = va_arg(ap, va_type(ptr)); - void *v3 = va_arg(ap, va_type(ptr)); - int v4 = va_arg(ap, va_type(int)); - void *v5 = va_arg(ap, va_type(ptr)); - *((int *)v_rc) = ((int(*)(void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5); - rc = (*((int *)v_rc) != he->he_modeval.v_int); - } else if (he->he_sig == AP_HOOK_SIG6(ptr, ptr, ptr, ptr, ptr, ptr)) { /* Call: ptr func(ptr,ptr,ptr,ptr,ptr) */ void *v1 = va_arg(ap, va_type(ptr)); @@ -749,11 +771,38 @@ static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf) *((void * *)v_rc) = ((void *(*)(void *, void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5); rc = (*((void * *)v_rc) != he->he_modeval.v_ptr); } - else if (he->he_sig == AP_HOOK_SIG2(ptr, char)) { - /* Call: ptr func(char) */ - char v1 = va_arg(ap, va_type(char)); - *((void * *)v_rc) = ((void *(*)(char))(hf->hf_ptr))(v1); - rc = (*((void * *)v_rc) != he->he_modeval.v_ptr); + else if (he->he_sig == AP_HOOK_SIG2(void, ptr)) { + /* Call: void func(ptr) */ + void *v1 = va_arg(ap, va_type(ptr)); + ((void(*)(void *))(hf->hf_ptr))(v1); + } + else if (he->he_sig == AP_HOOK_SIG4(void, ptr, int, int)) { + /* Call: void func(ptr,int,int) */ + void *v1 = va_arg(ap, va_type(ptr)); + int v2 = va_arg(ap, va_type(int)); + int v3 = va_arg(ap, va_type(int)); + ((void(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3); + } + else if (he->he_sig == AP_HOOK_SIG3(void, ptr, ptr)) { + /* Call: void func(ptr,ptr) */ + void *v1 = va_arg(ap, va_type(ptr)); + void *v2 = va_arg(ap, va_type(ptr)); + ((void(*)(void *, void *))(hf->hf_ptr))(v1, v2); + } + else if (he->he_sig == AP_HOOK_SIG4(void, ptr, ptr, ptr)) { + /* Call: void func(ptr,ptr,ptr) */ + void *v1 = va_arg(ap, va_type(ptr)); + void *v2 = va_arg(ap, va_type(ptr)); + void *v3 = va_arg(ap, va_type(ptr)); + ((void(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3); + } + else if (he->he_sig == AP_HOOK_SIG5(void, ptr, ptr, ptr, ptr)) { + /* Call: void func(ptr,ptr,ptr,ptr) */ + void *v1 = va_arg(ap, va_type(ptr)); + void *v2 = va_arg(ap, va_type(ptr)); + void *v3 = va_arg(ap, va_type(ptr)); + void *v4 = va_arg(ap, va_type(ptr)); + ((void(*)(void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4); } /* ----END GENERATED SECTION---------- */ else @@ -767,6 +816,8 @@ static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf) return rc; } +#endif /* EAPI */ + /* =cut ## @@ -785,6 +836,7 @@ my $end = '----END GENERATED SECTION----------'; if ($ARGV[0] eq 'used') { my @S = `find .. -type f -name "*.c" -print`; my $s; + my %T = (); foreach $s (@S) { $s =~ s|\n$||; open(FP, "<$s") || die; @@ -799,10 +851,15 @@ if ($ARGV[0] eq 'used') { my ($rc, $args) = ($sig =~ m|^([^,]+)(.*)$|); $args =~ s|^,||; $src =~ s|^.+/||; - printf(" * %-6s%-30s e.g. %s [%s]\n", $rc, "func($args)", $hook, $src); + my $sig = sprintf("%-6sfunc(%s)", $rc, $args); + $T{$sig}++; } $source =~ s|\("([^"]+)",\s*AP_HOOK_SIG[0-9]\((.+?)\)|&printme($s, $1, $2), ''|sge; } + my $t; + foreach $t (sort(keys(%T))) { + printf(" * %-40s [%dx]\n", $t, $T{$t}); + } exit(0); } diff --git a/usr.sbin/httpd/src/ap/ap_snprintf.c b/usr.sbin/httpd/src/ap/ap_snprintf.c index 19292a92792..648d55fca74 100644 --- a/usr.sbin/httpd/src/ap/ap_snprintf.c +++ b/usr.sbin/httpd/src/ap/ap_snprintf.c @@ -78,12 +78,23 @@ typedef enum { #ifndef TRUE #define TRUE 1 #endif +#ifndef AP_LONGEST_LONG +#define AP_LONGEST_LONG long +#endif #define NUL '\0' #define INT_NULL ((int *)0) #define WIDE_INT long +#define WIDEST_INT AP_LONGEST_LONG typedef WIDE_INT wide_int; typedef unsigned WIDE_INT u_wide_int; +typedef WIDEST_INT widest_int; +#ifdef __TANDEM +/* Although Tandem supports "long long" there is no unsigned variant. */ +typedef unsigned long u_widest_int; +#else +typedef unsigned WIDEST_INT u_widest_int; +#endif typedef int bool_int; #define S_NULL "(null)" @@ -338,6 +349,10 @@ static char *ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * Note: we have 2 versions. One is used when we need to use quads + * (conv_10_quad), the other when we don't (conv_10). We're assuming the + * latter is faster. */ static char *conv_10(register wide_int num, register bool_int is_unsigned, register bool_int *is_negative, char *buf_end, @@ -386,6 +401,61 @@ static char *conv_10(register wide_int num, register bool_int is_unsigned, return (p); } +static char *conv_10_quad(register widest_int num, register bool_int is_unsigned, + register bool_int *is_negative, char *buf_end, + register int *len) +{ + register char *p = buf_end; + register u_widest_int magnitude; + + /* + * If the value is less than the maximum unsigned long value, + * then we know we aren't using quads, so use the faster function + */ + if (num <= ULONG_MAX) + return(conv_10( (wide_int)num, is_unsigned, is_negative, + buf_end, len)); + + if (is_unsigned) { + magnitude = (u_widest_int) num; + *is_negative = FALSE; + } + else { + *is_negative = (num < 0); + + /* + * On a 2's complement machine, negating the most negative integer + * results in a number that cannot be represented as a signed integer. + * Here is what we do to obtain the number's magnitude: + * a. add 1 to the number + * b. negate it (becomes positive) + * c. convert it to unsigned + * d. add 1 + */ + if (*is_negative) { + widest_int t = num + 1; + + magnitude = ((u_widest_int) -t) + 1; + } + else + magnitude = (u_widest_int) num; + } + + /* + * We use a do-while loop so that we write at least 1 digit + */ + do { + register u_widest_int new_magnitude = magnitude / 10; + + *--p = (char) (magnitude - new_magnitude * 10 + '0'); + magnitude = new_magnitude; + } + while (magnitude); + + *len = buf_end - p; + return (p); +} + static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len) @@ -525,6 +595,9 @@ static char *conv_fp(register char format, register double num, * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * As with conv_10, we have a faster version which is used when + * the number isn't quad size. */ static char *conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register int *len) @@ -545,6 +618,28 @@ static char *conv_p2(register u_wide_int num, register int nbits, return (p); } +static char *conv_p2_quad(register u_widest_int num, register int nbits, + char format, char *buf_end, register int *len) +{ + register int mask = (1 << nbits) - 1; + register char *p = buf_end; + static const char low_digits[] = "0123456789abcdef"; + static const char upper_digits[] = "0123456789ABCDEF"; + register const char *digits = (format == 'X') ? upper_digits : low_digits; + + if (num <= ULONG_MAX) + return(conv_p2( (u_wide_int)num, nbits, format, buf_end, len)); + + do { + *--p = digits[num & mask]; + num >>= nbits; + } + while (num); + + *len = buf_end - p; + return (p); +} + /* * Do format conversion placing the output in buffer @@ -570,16 +665,22 @@ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), char prefix_char; double fp_num; + widest_int i_quad = (widest_int) 0; + u_widest_int ui_quad; wide_int i_num = (wide_int) 0; u_wide_int ui_num; char num_buf[NUM_BUF_SIZE]; char char_buf[2]; /* for printing %% and %<unknown> */ + enum var_type_enum { + IS_QUAD, IS_LONG, IS_SHORT, IS_INT + }; + enum var_type_enum var_type = IS_INT; + /* * Flag variables */ - boolean_e is_long; boolean_e alternate_form; boolean_e print_sign; boolean_e print_blank; @@ -677,14 +778,20 @@ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), /* * Modifier check */ - if (*fmt == 'l') { - is_long = YES; + if (*fmt == 'q') { + var_type = IS_QUAD; + fmt++; + } + else if (*fmt == 'l') { + var_type = IS_LONG; + fmt++; + } + else if (*fmt == 'h') { + var_type = IS_SHORT; fmt++; } else { - if (*fmt == 'h') /* "short" backward compatibility */ - ++fmt; - is_long = NO; + var_type = IS_INT; } /* @@ -700,23 +807,41 @@ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), */ switch (*fmt) { case 'u': - if (is_long) - i_num = va_arg(ap, u_wide_int); - else - i_num = (wide_int) va_arg(ap, unsigned int); - s = conv_10(i_num, 1, &is_negative, + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, u_widest_int); + s = conv_10_quad(i_quad, 1, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = (wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + i_num = (wide_int) (unsigned short) va_arg(ap, unsigned int); + else + i_num = (wide_int) va_arg(ap, unsigned int); + s = conv_10(i_num, 1, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); break; case 'd': case 'i': - if (is_long) - i_num = va_arg(ap, wide_int); - else - i_num = (wide_int) va_arg(ap, int); - s = conv_10(i_num, 0, &is_negative, + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, widest_int); + s = conv_10_quad(i_quad, 0, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = (wide_int) va_arg(ap, wide_int); + else if (var_type == IS_SHORT) + i_num = (wide_int) (short) va_arg(ap, int); + else + i_num = (wide_int) va_arg(ap, int); + s = conv_10(i_num, 0, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); if (is_negative) @@ -729,12 +854,21 @@ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), case 'o': - if (is_long) - ui_num = va_arg(ap, u_wide_int); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); - s = conv_p2(ui_num, 3, *fmt, + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, u_widest_int); + s = conv_p2_quad(ui_quad, 3, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); + else + ui_num = (u_wide_int) va_arg(ap, unsigned int); + s = conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); if (alternate_form && *s != '0') { *--s = '0'; @@ -745,12 +879,21 @@ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), case 'x': case 'X': - if (is_long) - ui_num = (u_wide_int) va_arg(ap, u_wide_int); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); - s = conv_p2(ui_num, 4, *fmt, + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, u_widest_int); + s = conv_p2_quad(ui_quad, 4, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); + else + ui_num = (u_wide_int) va_arg(ap, unsigned int); + s = conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); if (alternate_form && i_num != 0) { *--s = *fmt; /* 'x' or 'X' */ @@ -840,7 +983,14 @@ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), case 'n': - *(va_arg(ap, int *)) = cc; + if (var_type == IS_QUAD) + *(va_arg(ap, widest_int *)) = cc; + else if (var_type == IS_LONG) + *(va_arg(ap, long *)) = cc; + else if (var_type == IS_SHORT) + *(va_arg(ap, short *)) = cc; + else + *(va_arg(ap, int *)) = cc; break; /* @@ -850,16 +1000,25 @@ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), case 'p': switch(*++fmt) { /* - * If the pointer size is equal to the size of an unsigned - * integer we convert the pointer to a hex number, otherwise - * we print "%p" to indicate that we don't handle "%p". + * If the pointer size is equal to or smaller than the size + * of the largest unsigned int, we convert the pointer to a + * hex number, otherwise we print "%p" to indicate that we + * don't handle "%p". */ case 'p': - ui_num = (u_wide_int) va_arg(ap, void *); - - if (sizeof(char *) <= sizeof(u_wide_int)) - s = conv_p2(ui_num, 4, 'x', - &num_buf[NUM_BUF_SIZE], &s_len); +#ifdef AP_VOID_P_IS_QUAD + if (sizeof(void *) <= sizeof(u_widest_int)) { + ui_quad = (u_widest_int) va_arg(ap, void *); + s = conv_p2_quad(ui_quad, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#else + if (sizeof(void *) <= sizeof(u_wide_int)) { + ui_num = (u_wide_int) va_arg(ap, void *); + s = conv_p2(ui_num, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#endif else { s = "%p"; s_len = 2; diff --git a/usr.sbin/httpd/src/helpers/GuessOS b/usr.sbin/httpd/src/helpers/GuessOS index bac2b5ebc10..c68cfb5aba2 100644 --- a/usr.sbin/httpd/src/helpers/GuessOS +++ b/usr.sbin/httpd/src/helpers/GuessOS @@ -7,6 +7,8 @@ # addition: Any changes or additions to this script should be # Emailed to the Apache group (apache@apache.org). # +# Initially written by Jim Jagielski for the Apache configuration mechanism +# # Be as similar to the output of config.guess/config.sub # as possible. @@ -114,7 +116,11 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in echo "i486-whatever-bsdi"; exit 0 ;; - BSD/386:*|BSD/OS:*) + BSD/386|BSD/OS:3.*) + echo "${MACHINE}-whatever-bsdi3"; exit 0 + ;; + + BSD/386:*|BSD/OS:*) echo "${MACHINE}-whatever-bsdi"; exit 0 ;; @@ -144,6 +150,10 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in echo "${MACHINE}-dec-osf"; exit 0 ;; + NONSTOP_KERNEL:*:*:*) + echo "${MACHINE}-tandem-oss"; exit 0; + ;; + QNX:*) if [ "$VERSION" -gt 422 ]; then echo "${MACHINE}-qssl-qnx32" @@ -188,8 +198,15 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in echo "${MACHINE}-whatever-unixware212"; exit 0 ;; - DYNIX/ptx:4*:*) - echo "${MACHINE}-whatever-sysv4"; exit 0 + DYNIX/ptx:4*:*:i386) + PTXVER=`echo ${VERSION}|sed -e 's/[^.]//'` + echo "${MACHINE}-sequent-ptx${PTXVER}"; exit 0 + ;; + + *:3.2.0:*:i386) + # uname on DYNIX/ptx below V4.0.0 is brain dead + PTXVER=`echo ${VERSION}|sed -e 's/[^.]//'` + echo "${MACHINE}-sequent-ptx${PTXVER}"; exit 0 ;; *:4.0:3.0:[345][0-9]?? | *:4.0:3.0:3[34]??[/,]* | library:*) @@ -242,6 +259,11 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in echo "${MACHINE}-apple-rhapsody${RELEASE}"; exit 0 ;; + "Mac OS":*:*:*) + MACHINE=`uname -p` + echo "${MACHINE}-apple-macos${RELEASE}"; exit 0 + ;; + "RISC iX":*) echo "arm-whatever-riscix"; exit 0; ;; @@ -274,7 +296,7 @@ fi # Apache is not compiled on the TPF platform # therefore an environment variable is used -if [ "$TPF" = "YES" ]; then +if [ "x$TPF" = "xYES" ]; then echo "TPF" exit 0 fi diff --git a/usr.sbin/httpd/src/helpers/PrintPath b/usr.sbin/httpd/src/helpers/PrintPath index 71335280fd3..908d2740083 100644 --- a/usr.sbin/httpd/src/helpers/PrintPath +++ b/usr.sbin/httpd/src/helpers/PrintPath @@ -10,6 +10,9 @@ # Usage: # PrintPath [-s] [-pPATHNAME] program [program ...] # +# Initially written by Jim Jagielski for the Apache configuration mechanism +# (with kudos to Kernighan/Pike) +# # This script falls under the Apache License. # See http://www.apache.org/docs/LICENSE @@ -91,7 +94,7 @@ do do if [ $test_exec_flag $path/${program}${ext} ] && \ [ ! -d $path/${program}${ext} ]; then - if [ "$echo" = "yes" ]; then + if [ "x$echo" = "xyes" ]; then echo $path/${program}${ext} fi exit 0 diff --git a/usr.sbin/httpd/src/helpers/TestCompile b/usr.sbin/httpd/src/helpers/TestCompile index 6be8d474301..4622a3f2fc7 100644 --- a/usr.sbin/httpd/src/helpers/TestCompile +++ b/usr.sbin/httpd/src/helpers/TestCompile @@ -22,6 +22,14 @@ trap 'rm -f Makefile dummy dummy.exe testfunc.c testfunc testfunc.exe; exit $exs # ./helpers/TestCompile sanity # Which does a simple sanity check/test compile # +# ./helpers/TestCompile sizeof <type> +# Which prints out the sizeof <type> (sure would be nice +# if sizeof could be use in preprocessor if's) +# +# ./helpers/TestCompile byteorder +# Which prints out the byte order of the machine +# (12: little endian, 21: big endian) +# # It does these by creating a small mini-makefile, based on # ../Makefile.config and trying to compile a small dummy # program. If the compilation succeeds, we assume the test @@ -32,6 +40,8 @@ trap 'rm -f Makefile dummy dummy.exe testfunc.c testfunc testfunc.exe; exit $exs # located) if you want to test it out. Configure must # also call it as './helpers/TestCompile' # +# Initially written by Jim Jagielski for the Apache configuration mechanism +# # This script falls under the Apache License. # See http://www.apache.org/docs/LICENSE @@ -39,8 +49,15 @@ trap 'rm -f Makefile dummy dummy.exe testfunc.c testfunc testfunc.exe; exit $exs cd ./helpers # -# Handle "verbose" and "silent" flags +# Handle "verbose", "silent" and "runit" flags. Allow for them +# to be set via the environment # +if [ "x$VERBOSE" = "x" ]; then + VERBOSE="no" +fi +if [ "x$TCRUNIT" = "x" ]; then + TCRUNIT="no"; +fi case "$1" in "-v") VERBOSE="yes" @@ -50,6 +67,10 @@ case "$1" in VERBOSE="no" shift ;; + "-r") + TCRUNIT="yes" + shift + ;; esac # @@ -61,8 +82,8 @@ case "$1" in if [ "x$2" = "x" ]; then exit fi - TLIB="-l$2" - if [ "$VERBOSE" = "yes" ]; then + TLIB="-l$2 $TLIB" + if [ "x$VERBOSE" = "xyes" ]; then ERRDIR="" else ERRDIR='2>/dev/null' @@ -74,9 +95,52 @@ case "$1" in echo "int main(void) { $3(); return(0); }" > testfunc.c fi ;; + "sizeof") + if [ "x$2" = "x" ]; then + exit + fi + TLIB="" + if [ "x$VERBOSE" = "xyes" ]; then + ERRDIR="" + else + ERRDIR='2>/dev/null' + fi + TARGET='testfunc' + cat <<EOF >testfunc.c +#include <stdio.h> +#include <sys/types.h> +int main(void) { + printf("%d\n", sizeof($2)); + return(0); +} +EOF + ;; + "byteorder") + TLIB="" + if [ "x$VERBOSE" = "xyes" ]; then + ERRDIR="" + else + ERRDIR='2>/dev/null' + fi + TARGET='testfunc' + cat <<EOF >testfunc.c +#include <stdio.h> +#include <sys/types.h> +int main(void) { + /* Are we little or big endian? From Harbison & Steele */ + union { + long l; + char c[sizeof(long)]; + } u; + u.l = 1; + printf("%s\n", u.c[sizeof(long)-1] == 1 ? "21" : "12"); + return(0); +} +EOF + ;; "sanity") TLIB="" - if [ "$VERBOSE" = "no" ]; then + if [ "x$VERBOSE" = "xno" ]; then ERRDIR='2>/dev/null' else ERRDIR="" @@ -88,7 +152,7 @@ case "$1" in exit fi TLIB="" - if [ "$VERBOSE" = "yes" ]; then + if [ "x$VERBOSE" = "xyes" ]; then ERRDIR="" else ERRDIR='2>/dev/null' @@ -106,7 +170,7 @@ EOF exit fi TLIB="" - if [ "$VERBOSE" = "yes" ]; then + if [ "x$VERBOSE" = "xyes" ]; then ERRDIR="" else ERRDIR='2>/dev/null' @@ -143,7 +207,7 @@ testfunc: EOF # Now run that Makefile -eval "${MAKE} ${TARGET} >/dev/null $ERRDIR" +eval "${MAKE-make} ${TARGET} $ERRDIR >&2" # And see if dummy exists and is executable, if so, then we # assume the condition we are testing for is good @@ -152,5 +216,8 @@ eval "${MAKE} ${TARGET} >/dev/null $ERRDIR" # have PrintPath just search this directory. if ./PrintPath -s -p`pwd` $TARGET ; then + if [ "x$TCRUNIT" = "xyes" ]; then + `pwd`/$TARGET + fi exstat=0 fi diff --git a/usr.sbin/httpd/src/helpers/binbuild.sh b/usr.sbin/httpd/src/helpers/binbuild.sh index 3279148fcbc..e6c3a4b4a9f 100644 --- a/usr.sbin/httpd/src/helpers/binbuild.sh +++ b/usr.sbin/httpd/src/helpers/binbuild.sh @@ -7,14 +7,21 @@ # See http://www.apache.org/docs/LICENSE -APDIR=$(basename $(pwd)) -VER=$(echo $APDIR |sed s/apache-//) -OS=$(src/helpers/GuessOS) -USER="$(src/helpers/buildinfo.sh -n %u@%h%d)" -TAR="$(src/helpers/findprg.sh tar)" -GTAR="$(src/helpers/findprg.sh gtar)" -GZIP="$(src/helpers/findprg.sh gzip)" CONFIGPARAM="--with-layout=BinaryDistribution --enable-module=most --enable-shared=max" +APDIR=`pwd` +APDIR=`basename $APDIR` +VER=`echo $APDIR |sed s/apache_//` +OS=`src/helpers/GuessOS` +TAR="`src/helpers/PrintPath tar`" +GTAR="`src/helpers/PrintPath gtar`" +GZIP="`src/helpers/PrintPath gzip`" + +if [ x$1 != x ] +then + USER=$1 +else + USER="`src/helpers/buildinfo.sh -n %u@%h%d`" +fi if [ ! -f ./ABOUT_APACHE ] then @@ -58,7 +65,10 @@ then exit 1; fi -echo "Binary images successfully created..." +echo "Binary image successfully created..." + +./bindist/bin/httpd -v + echo "Creating supplementary files..." ( echo " " && \ @@ -89,7 +99,7 @@ echo "Creating supplementary files..." ./bindist/bin/httpd -V && \ echo "----------------------------------------------------------------------" \ ) > README.bindist -cp README.bindist ../apache-$VER-$OS.README +cp README.bindist ../apache_$VER-$OS.README ( echo " " && \ echo "Apache $VER binary installation" && \ @@ -119,6 +129,64 @@ cp README.bindist ../apache-$VER-$OS.README echo "# This script installs the Apache binary distribution and" && \ echo "# was automatically created by binbuild.sh." && \ echo " " && \ + echo "lmkdir()" && \ + echo "{" && \ + echo " path=\"\"" && \ + echo " dirs=\`echo \$1 | sed -e 's%/% %g'\`" && \ + echo " mode=\$2" && \ + echo " " && \ + echo " set -- \${dirs}" && \ + echo " " && \ + echo " for d in \${dirs}" && \ + echo " do" && \ + echo " path=\"\${path}/\$d\"" && \ + echo " if test ! -d \"\${path}\" ; then" && \ + echo " mkdir \${path}" && \ + echo " if test \$? -ne 0 ; then" && \ + echo " echo \"Failed to create directory: \${path}\"" && \ + echo " exit 1" && \ + echo " fi" && \ + echo " chmod \${mode} \${path}" && \ + echo " fi" && \ + echo " done" && \ + echo "}" && \ + echo " " && \ + echo "lcopy()" && \ + echo "{" && \ + echo " from=\$1" && \ + echo " to=\$2" && \ + echo " dmode=\$3" && \ + echo " fmode=\$4" && \ + echo " " && \ + echo " test -d \${to} || lmkdir \${to} \${dmode}" && \ + echo " (cd \${from} && tar -cf - *) | (cd \${to} && tar -xf -)" && \ + echo " " && \ + echo " if test \"X\${fmode}\" != X ; then" && \ + echo " find \${to} -type f -print | xargs chmod \${fmode}" && \ + echo " fi" && \ + echo " if test \"X\${dmode}\" != X ; then" && \ + echo " find \${to} -type d -print | xargs chmod \${dmode}" && \ + echo " fi" && \ + echo "}" && \ + echo " " && \ + echo "##" && \ + echo "## determine path to (optional) Perl interpreter" && \ + echo "##" && \ + echo "PERL=no-perl5-on-this-system" && \ + echo "perls='perl5 perl'" && \ + echo "path=\`echo \$PATH | sed -e 's/:/ /g'\`" && \ + echo " " && \ + echo "for dir in \${path} ; do" && \ + echo " for pperl in \${perls} ; do" && \ + echo " if test -f \"\${dir}/\${pperl}\" ; then" && \ + echo " if \`\${dir}/\${pperl} -v | grep 'version 5\.' >/dev/null 2>&1\` ; then" && \ + echo " PERL=\"\${dir}/\${pperl}\"" && \ + echo " break" && \ + echo " fi" && \ + echo " fi" && \ + echo " done" && \ + echo "done" && \ + echo " " && \ echo "if [ .\$1 = . ]" && \ echo "then" && \ echo " SR=/usr/local/apache" && \ @@ -127,41 +195,46 @@ cp README.bindist ../apache-$VER-$OS.README echo "fi" && \ echo "echo \"Installing binary distribution for platform $OS\"" && \ echo "echo \"into directory \$SR ...\"" && \ - echo "./src/helpers/mkdir.sh \$SR" && \ - echo "cp -r bindist/proxy \$SR/proxy" && \ - echo "cp -r bindist/man \$SR/man" && \ - echo "cp -r bindist/logs \$SR/logs" && \ - echo "cp -r bindist/libexec \$SR/libexec" && \ - echo "cp -r bindist/include \$SR/include" && \ - echo "cp -r bindist/icons \$SR/icons" && \ - echo "cp -r bindist/cgi-bin \$SR/cgi-bin" && \ - echo "cp -r bindist/bin \$SR/bin" && \ + echo "lmkdir \$SR 755" && \ + echo "lmkdir \$SR/proxy 750" && \ + echo "lmkdir \$SR/logs 750" && \ + echo "lcopy bindist/man \$SR/man 755 644" && \ + echo "lcopy bindist/libexec \$SR/libexec 750 644" && \ + echo "lcopy bindist/include \$SR/include 755 644" && \ + echo "lcopy bindist/icons \$SR/icons 755 644" && \ + echo "lcopy bindist/cgi-bin \$SR/cgi-bin 750 750" && \ + echo "lcopy bindist/bin \$SR/bin 750 750" && \ echo "if [ -d \$SR/conf ]" && \ echo "then" && \ echo " echo \"[Preserving existing configuration files.]\"" && \ - echo " cp -r bindist/conf/*.default \$SR/conf/" && \ + echo " cp bindist/conf/*.default \$SR/conf/" && \ echo "else" && \ - echo " cp -r bindist/conf \$SR/conf" && \ + echo " lcopy bindist/conf \$SR/conf 750 640" && \ echo "fi" && \ echo "if [ -d \$SR/htdocs ]" && \ echo "then" && \ echo " echo \"[Preserving existing htdocs directory.]\"" && \ echo "else" && \ - echo " cp -r bindist/htdocs \$SR/htdocs" && \ + echo " lcopy bindist/htdocs \$SR/htdocs 755 644" && \ echo "fi" && \ - echo "sed -e s%/usr/local/apache%\$SR/% \$SR/conf/httpd.conf.default > \$SR/conf/httpd.conf" && \ - echo "sed -e s%PIDFILE=%PIDFILE=\$SR/% -e s%HTTPD=%HTTPD=\\\"\$SR/% -e \"s%/httpd$%/httpd -d \$SR\\\"%\" bindist/bin/apachectl > \$SR/bin/apachectl" && \ + echo " " && \ + echo "sed -e \"s;^#!/.*;#!\$PERL;\" -e \"s;\@prefix\@;\$SR;\" -e \"s;\@sbindir\@;\$SR/bin;\" \\" && \ + echo " -e \"s;\@libexecdir\@;\$SR/libexec;\" -e \"s;\@includedir\@;\$SR/include;\" \\" && \ + echo " -e \"s;\@sysconfdir\@;\$SR/conf;\" bindist/bin/apxs > \$SR/bin/apxs" && \ + echo "sed -e \"s;^#!/.*;#!\$PERL;\" bindist/bin/dbmmanage > \$SR/bin/dbmmanage" && \ + echo "sed -e \"s%/usr/local/apache%\$SR%\" \$SR/conf/httpd.conf.default > \$SR/conf/httpd.conf" && \ + echo "sed -e \"s%PIDFILE=%PIDFILE=\$SR/%\" -e \"s%HTTPD=%HTTPD=\\\"\$SR/%\" -e \"s%httpd\$%httpd -d \$SR -R \$SR/libexec\\\"%\" bindist/bin/apachectl > \$SR/bin/apachectl" && \ echo " " && \ echo "echo \"Ready.\"" && \ echo "echo \" +--------------------------------------------------------+\"" && \ echo "echo \" | You now have successfully installed the Apache $VER |\"" && \ echo "echo \" | HTTP server. To verify that Apache actually works |\"" && \ - echo "echo \" | correctly you now should first check the (initially |\"" && \ - echo "echo \" | created or preserved) configuration files |\"" && \ + echo "echo \" | correctly you should first check the (initially |\"" && \ + echo "echo \" | created or preserved) configuration files: |\"" && \ echo "echo \" | |\"" && \ echo "echo \" | \$SR/conf/httpd.conf\"" && \ echo "echo \" | |\"" && \ - echo "echo \" | and then you should be able to immediately fire up |\"" && \ + echo "echo \" | You should then be able to immediately fire up |\"" && \ echo "echo \" | Apache the first time by running: |\"" && \ echo "echo \" | |\"" && \ echo "echo \" | \$SR/bin/apachectl start \"" &&\ @@ -173,9 +246,10 @@ cp README.bindist ../apache-$VER-$OS.README ) > install-bindist.sh chmod 755 install-bindist.sh -sed -e "s%\"/htdocs%\"/usr/local/apache/htdocs%" \ - -e "s%\"/icons%\"/usr/local/apache/icons%" \ - -e "s%\"/cgi-bin%\"/usr/local/apache/cgi-bin%" \ +sed -e "s%\"htdocs%\"/usr/local/apache/htdocs%" \ + -e "s%\"icons%\"/usr/local/apache/icons%" \ + -e "s%\"cgi-bin%\"/usr/local/apache/cgi-bin%" \ + -e "s%\"proxy%\"/usr/local/apache/proxy%" \ -e "s%^ServerAdmin.*%ServerAdmin you@your.address%" \ -e "s%#ServerName.*%#ServerName localhost%" \ -e "s%Port 8080%Port 80%" \ @@ -189,30 +263,30 @@ then echo "ERROR: Failed to build Apache. See \"build.log\" for details." exit 1; else - if [ ".$GTAR" != . ] + if [ "x$GTAR" != "x" ] then - $GTAR -zcf ../apache-$VER-$OS.tar.gz -C .. --owner=root --group=root apache-$VER + $GTAR -zcf ../apache_$VER-$OS.tar.gz -C .. apache_$VER else - if [ ".$TAR" != . ] + if [ "x$TAR" != "x" ] then - $TAR -cf ../apache-$VER-$OS.tar -C .. apache-$VER - if [ ".$GZIP" != . ] + $TAR -cf ../apache_$VER-$OS.tar -C .. apache_$VER + if [ "x$GZIP" != "x" ] then - $GZIP ../apache-$VER-$OS.tar + $GZIP ../apache_$VER-$OS.tar fi else echo "ERROR: Could not find a 'tar' program!" echo " Please execute the following commands manually:" - echo " tar -cf ../apache-$VER-$OS.tar ." - echo " gzip ../apache-$VER-$OS.tar" + echo " tar -cf ../apache_$VER-$OS.tar ." + echo " gzip ../apache_$VER-$OS.tar" fi fi - if [ -f ../apache-$VER-$OS.tar.gz ] && [ -f ../apache-$VER-$OS.README ] + if [ -f ../apache_$VER-$OS.tar.gz ] && [ -f ../apache_$VER-$OS.README ] then echo "Ready." - echo "You can find the binary archive (apache-$VER-$OS.tar.gz)" - echo "and the readme file (apache-$VER-$OS.README) in the" + echo "You can find the binary archive (apache_$VER-$OS.tar.gz)" + echo "and the readme file (apache_$VER-$OS.README) in the" echo "parent directory." exit 0; else diff --git a/usr.sbin/httpd/src/helpers/buildinfo.sh b/usr.sbin/httpd/src/helpers/buildinfo.sh index 8aa0541c206..5c2a72d6b35 100644 --- a/usr.sbin/httpd/src/helpers/buildinfo.sh +++ b/usr.sbin/httpd/src/helpers/buildinfo.sh @@ -1,7 +1,7 @@ #!/bin/sh ## ## buildinfo.sh -- Determine Build Information -## Written by Ralf S. Engelschall <rse@apache.org> +## Initially written by Ralf S. Engelschall <rse@apache.org> ## for the Apache's Autoconf-style Interface (APACI) ## # @@ -16,10 +16,10 @@ error=no if [ $# -ne 1 -a $# -ne 2 ]; then error=yes fi -if [ $# -eq 2 -a ".$1" != ".-n" ]; then +if [ $# -eq 2 -a "x$1" != "x-n" ]; then error=yes fi -if [ $error = yes ]; then +if [ "x$error" = "xyes" ]; then echo "$0:Error: invalid argument line" echo "$0:Usage: $0 [-n] <format-string>" echo "Where <format-string> can contain:" @@ -55,15 +55,15 @@ time_monthname='' # determine username # username="$LOGNAME" -if [ ".$username" = . ]; then +if [ "x$username" = "x" ]; then username="$USER" - if [ ".$username" = . ]; then - username="`whoami 2>/dev/null |\ + if [ "x$username" = "x" ]; then + username="`(whoami) 2>/dev/null |\ awk '{ printf("%s", $1); }'`" - if [ ".$username" = . ]; then - username="`who am i 2>/dev/null |\ + if [ "x$username" = "x" ]; then + username="`(who am i) 2>/dev/null |\ awk '{ printf("%s", $1); }'`" - if [ ".$username" = . ]; then + if [ "x$username" = "x" ]; then username='unknown' fi fi @@ -73,12 +73,12 @@ fi # # determine hostname and domainname # -hostname="`uname -n 2>/dev/null |\ +hostname="`(uname -n) 2>/dev/null |\ awk '{ printf("%s", $1); }'`" -if [ ".$hostname" = . ]; then - hostname="`hostname 2>/dev/null |\ +if [ "x$hostname" = "x" ]; then + hostname="`(hostname) 2>/dev/null |\ awk '{ printf("%s", $1); }'`" - if [ ".$hostname" = . ]; then + if [ "x$hostname" = "x" ]; then hostname='unknown' fi fi @@ -88,14 +88,14 @@ case $hostname in hostname="`echo $hostname | cut -d. -f1`" ;; esac -if [ ".$domainname" = . ]; then +if [ "x$domainname" = "x" ]; then if [ -f /etc/resolv.conf ]; then domainname="`egrep '^[ ]*domain' /etc/resolv.conf | head -1 |\ sed -e 's/.*domain//' \ -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ -e 's/^\.//' -e 's/^/./' |\ awk '{ printf("%s", $1); }'`" - if [ ".$domainname" = . ]; then + if [ "x$domainname" = "x" ]; then domainname="`egrep '^[ ]*search' /etc/resolv.conf | head -1 |\ sed -e 's/.*search//' \ -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ @@ -112,11 +112,11 @@ fi time_day="`date '+%d' | awk '{ printf("%s", $1); }'`" time_month="`date '+%m' | awk '{ printf("%s", $1); }'`" time_year="`date '+%Y' 2>/dev/null | awk '{ printf("%s", $1); }'`" -if test ".$time_year" = .; then +if [ "x$time_year" = "x" ]; then time_year="`date '+%y' | awk '{ printf("%s", $1); }'`" case $time_year in - 9[0-9]*) time_year="19$time_year" ;; - *) time_year="20$time_year" ;; + [5-9][0-9]) time_year="19$time_year" ;; + [0-4][0-9]) time_year="20$time_year" ;; esac fi case $time_month in @@ -137,7 +137,7 @@ esac # # create result string # -if [ ".$newline" = .yes ]; then +if [ "x$newline" = "xyes" ]; then echo $format_string |\ sed -e "s;%u;$username;g" \ -e "s;%h;$hostname;g" \ diff --git a/usr.sbin/httpd/src/helpers/checkheader.sh b/usr.sbin/httpd/src/helpers/checkheader.sh index 4f3fd064d64..26cd176c682 100644 --- a/usr.sbin/httpd/src/helpers/checkheader.sh +++ b/usr.sbin/httpd/src/helpers/checkheader.sh @@ -1,7 +1,8 @@ #!/bin/sh ## ## checkheader.sh -- Check whether a C header file exists -## Written by Ralf S. Engelschall for the Apache configuration mechanism +## Initially written by Ralf S. Engelschall for the Apache +## configuration mechanism ## # # This script falls under the Apache License. @@ -10,10 +11,10 @@ header=$1 rc=1 -if [ ".$CPP" = . ]; then +if [ "x$CPP" = "x" ]; then CPP='NOT-AVAILABLE' fi -if [ ".$CPP" != ".NOT-AVAILABLE" ]; then +if [ "x$CPP" != "xNOT-AVAILABLE" ]; then # create a test C source cat >conftest.c <<EOF #include <$header> @@ -21,7 +22,7 @@ Syntax Error EOF (eval "$CPP conftest.c >/dev/null") 2>conftest.out my_error=`grep -v '^ *+' conftest.out` - if [ ".$my_error" = . ]; then + if [ "x$my_error" = "x" ]; then rc=0 fi else diff --git a/usr.sbin/httpd/src/helpers/dummy.c b/usr.sbin/httpd/src/helpers/dummy.c index b1e4964cbbf..cf938b8402c 100644 --- a/usr.sbin/httpd/src/helpers/dummy.c +++ b/usr.sbin/httpd/src/helpers/dummy.c @@ -6,7 +6,7 @@ int foo ( const char *c ) return *c; } int main(void) { - const char *c = '\0'; + const char *c = ""; (void)foo(c); return 0; } diff --git a/usr.sbin/httpd/src/helpers/find-dbm-lib b/usr.sbin/httpd/src/helpers/find-dbm-lib index 0355965af59..3792d9301eb 100644 --- a/usr.sbin/httpd/src/helpers/find-dbm-lib +++ b/usr.sbin/httpd/src/helpers/find-dbm-lib @@ -18,13 +18,13 @@ if [ "x$found_dbm" = "x" ]; then elif ./helpers/TestCompile lib ndbm dbm_open; then DBM_LIB="-lndbm" fi - if [ "X$DBM_LIB" != "X" ]; then + if [ "x$DBM_LIB" != "x" ]; then LIBS="$LIBS $DBM_LIB" found_dbm=1 fi ;; *) - if [ "X$DBM_LIB" != "X" ]; then + if [ "x$DBM_LIB" != "x" ]; then oldLIBS="$LIBS" LIBS="$LIBS $DBM_LIB" if ./helpers/TestCompile func dbm_open; then @@ -33,10 +33,21 @@ if [ "x$found_dbm" = "x" ]; then found_dbm=0 LIBS="$oldLIBS" fi + else + for dblib in dbm ndbm db + do + DBM_LIB="" + if ./helpers/TestCompile lib $dblib dbm_open; then + DBM_LIB="-l${dblib}" + LIBS="$LIBS $DBM_LIB" + found_dbm=1 + break + fi + done fi ;; esac - if [ "X$found_dbm" = "X1" ]; then + if [ "x$found_dbm" = "x1" ]; then echo " + using $DBM_LIB for DBM support" fi fi diff --git a/usr.sbin/httpd/src/helpers/findcpp.sh b/usr.sbin/httpd/src/helpers/findcpp.sh index f5a261f34eb..a870f7371ae 100644 --- a/usr.sbin/httpd/src/helpers/findcpp.sh +++ b/usr.sbin/httpd/src/helpers/findcpp.sh @@ -1,7 +1,8 @@ #!/bin/sh ## ## findcpp.sh -- Find out how to _directly_ run the C Pre-Processor (CPP) -## Written by Ralf S. Engelschall for the Apache configuration mechanism +## Initially written by Ralf S. Engelschall for the Apache configuration +## mechanism ## # # This script falls under the Apache License. @@ -19,16 +20,16 @@ Syntax Error EOF # some braindead systems have a CPP define for a directory :-( -if [ ".$CPP" != . ]; then +if [ "x$CPP" != "x" ]; then if [ -d "$CPP" ]; then CPP='' fi fi -if [ ".$CPP" != . ]; then +if [ "x$CPP" != "x" ]; then # case 1: user provided a default CPP variable (we only check) (eval "$CPP conftest.c >/dev/null") 2>conftest.out my_error=`grep -v '^ *+' conftest.out` - if [ ".$my_error" != . ]; then + if [ "x$my_error" != "x" ]; then CPP='' fi else @@ -37,21 +38,21 @@ else CPP="${CC-cc} -E" (eval "$CPP conftest.c >/dev/null") 2>conftest.out my_error=`grep -v '^ *+' conftest.out` - if [ ".$my_error" != . ]; then + if [ "x$my_error" != "x" ]; then # 2. try the -E option and GCC's -traditional-ccp option CPP="${CC-cc} -E -traditional-cpp" (eval "$CPP conftest.c >/dev/null") 2>conftest.out my_error=`grep -v '^ *+' conftest.out` - if [ ".$my_error" != . ]; then + if [ "x$my_error" != "x" ]; then # 3. try a standalone cpp command in $PATH and lib dirs CPP="`./helpers/PrintPath cpp`" - if [ ".$CPP" = . ]; then + if [ "x$CPP" = "x" ]; then CPP="`./helpers/PrintPath -p/lib:/usr/lib:/usr/local/lib cpp`" fi - if [ ".$CPP" != . ]; then + if [ "x$CPP" != "x" ]; then (eval "$CPP conftest.c >/dev/null") 2>conftest.out my_error=`grep -v '^ *+' conftest.out` - if [ ".$my_error" != . ]; then + if [ "x$my_error" != "x" ]; then # ok, we gave up... CPP='' fi @@ -64,7 +65,7 @@ fi rm -f conftest.* # Ok, empty CPP variable now means it's not available -if [ ".$CPP" = . ]; then +if [ "x$CPP" = "x" ]; then CPP='NOT-AVAILABLE' fi diff --git a/usr.sbin/httpd/src/helpers/findprg.sh b/usr.sbin/httpd/src/helpers/findprg.sh deleted file mode 100644 index 8b2f391c976..00000000000 --- a/usr.sbin/httpd/src/helpers/findprg.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# Usage: findprg.sh <program-name> -# Return value is the absolute path of the program if it was found. -# Initially written by Lars Eilebrecht <lars@apache.org>. -# -# This script falls under the Apache License. -# See http://www.apache.org/docs/LICENSE - - -if [ ".`which $1`" != . ] -then - echo `which $1` - exit 0 -else - PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" - if [ ".`which $1`" != . ] - then - echo `which $1` - exit 0 - else - exit 1 - fi -fi diff --git a/usr.sbin/httpd/src/helpers/fmn.sh b/usr.sbin/httpd/src/helpers/fmn.sh index b8fd39ede45..0f17b55a08b 100644 --- a/usr.sbin/httpd/src/helpers/fmn.sh +++ b/usr.sbin/httpd/src/helpers/fmn.sh @@ -2,8 +2,7 @@ ## ## fmn.sh -- find a modules (structure) name ## -## Extracted from the Configure script by -## Ralf S. Engelschall <rse@apache.org> for use with +## Extracted from the Configure script for use with ## Apache's Autoconf-style Interface (APACI). ## # @@ -20,9 +19,9 @@ rm -f $tmpfile modname='' ext=`echo $modfile | sed 's/^.*\.//'` modbase=`echo $modfile | sed 's/\.[^.]*$//'` -if [ x$ext = x$modfile ]; then ext=o; modbase=$modfile; modfile=$modbase.o; fi -if [ x$ext = x ] ; then ext=o; modbase=$modfile; fi -if [ x$ext = xc ] ; then ext=o; fi +if [ "x$ext" = "x$modfile" ]; then ext=o; modbase=$modfile; modfile=$modbase.o; fi +if [ "x$ext" = "x" ] ; then ext=o; modbase=$modfile; fi +if [ "x$ext" = "xc" ] ; then ext=o; fi if [ -r $modbase.module ] ; then cat $modbase.module >$tmpfile else diff --git a/usr.sbin/httpd/src/helpers/fp2rp b/usr.sbin/httpd/src/helpers/fp2rp index 6c594ba7234..68d5adb6d19 100644 --- a/usr.sbin/httpd/src/helpers/fp2rp +++ b/usr.sbin/httpd/src/helpers/fp2rp @@ -2,7 +2,7 @@ ## ## fp2rp -- convert a standard forward path to a reverse dotted path ## -if [ "x$1" = x. ]; then +if [ "x$1" = "x." ]; then rp="." else rp="" diff --git a/usr.sbin/httpd/src/helpers/install.sh b/usr.sbin/httpd/src/helpers/install.sh index 19e8badad6e..9a8821fa290 100644 --- a/usr.sbin/httpd/src/helpers/install.sh +++ b/usr.sbin/httpd/src/helpers/install.sh @@ -34,9 +34,10 @@ chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" +ext="" src="" dst="" -while [ ".$1" != . ]; do +while [ "x$1" != "x" ]; do case $1 in -c) instcmd="$cpprog" shift; continue @@ -51,8 +52,15 @@ while [ ".$1" != . ]; do shift; shift; continue ;; -s) stripcmd="$stripprog" - shift; continue;; - *) if [ ".$src" = . ]; then + shift; continue + ;; + -S) stripcmd="$stripprog $2" + shift; shift; continue + ;; + -e) ext="$2" + shift; shift; continue + ;; + *) if [ "x$src" = "x" ]; then src=$1 else dst=$1 @@ -61,11 +69,11 @@ while [ ".$1" != . ]; do ;; esac done -if [ ".$src" = . ]; then +if [ "x$src" = "x" ]; then echo "install.sh: no input file specified" exit 1 fi -if [ ".$dst" = . ]; then +if [ "x$dst" = "x" ]; then echo "install.sh: no destination specified" exit 1 fi @@ -79,6 +87,10 @@ if [ -d $dst ]; then dst="$dst/`basename $src`" fi +# Add a possible extension (such as ".exe") to src and dst +src="$src$ext" +dst="$dst$ext" + # Make a temp file name in the proper directory. dstdir=`dirname $dst` dsttmp=$dstdir/#inst.$$# @@ -87,10 +99,10 @@ dsttmp=$dstdir/#inst.$$# $instcmd $src $dsttmp # And set any options; do chmod last to preserve setuid bits -if [ ".$chowncmd" != . ]; then $chowncmd $dsttmp; fi -if [ ".$chgrpcmd" != . ]; then $chgrpcmd $dsttmp; fi -if [ ".$stripcmd" != . ]; then $stripcmd $dsttmp; fi -if [ ".$chmodcmd" != . ]; then $chmodcmd $dsttmp; fi +if [ "x$chowncmd" != "x" ]; then $chowncmd $dsttmp; fi +if [ "x$chgrpcmd" != "x" ]; then $chgrpcmd $dsttmp; fi +if [ "x$stripcmd" != "x" ]; then $stripcmd $dsttmp; fi +if [ "x$chmodcmd" != "x" ]; then $chmodcmd $dsttmp; fi # Now rename the file to the real destination. $rmcmd $dst diff --git a/usr.sbin/httpd/src/helpers/mkshadow.sh b/usr.sbin/httpd/src/helpers/mkshadow.sh index 448a09455cf..00b0e3a2a41 100644 --- a/usr.sbin/httpd/src/helpers/mkshadow.sh +++ b/usr.sbin/httpd/src/helpers/mkshadow.sh @@ -2,7 +2,7 @@ ## ## mkshadow.sh -- create a shadow tree ## -## Written by Ralf S. Engelschall <rse@apache.org> +## Initially written by Ralf S. Engelschall <rse@apache.org> ## for the shadow tree generation option (--shadow) of ## Apache's Autoconf-style Interface (APACI) ## @@ -37,7 +37,7 @@ esac # determine reverse directory for destination directory dstrevdir='' -if [ $oneisabs = 0 ]; then +if [ "x$oneisabs" = "x0" ]; then # (inlined fp2rp) OIFS2="$IFS"; IFS='/' for pe in $dst; do @@ -52,7 +52,7 @@ fi if [ ! -d $dst ]; then mkdir $dst fi -DIRS="`cd $src +DIRS="`cd $src; \ find . -type d -print |\ sed -e '/\/CVS/d' \ -e '/^\.$/d' \ @@ -64,7 +64,7 @@ done IFS="$OIFS" # fill directory tree with symlinks to files -FILES="`cd $src +FILES="`cd $src; \ find . -depth -print |\ sed -e '/\.o$/d' \ -e '/\.a$/d' \ @@ -81,15 +81,15 @@ FILES="`cd $src OIFS="$IFS" IFS="$DIFS" for file in $FILES; do # don't use `-type f' above for find because of symlinks - if [ -d $file ]; then + if [ -d "$src/$file" ]; then continue fi basename=`echo $file | sed -e 's:^.*/::'` dir=`echo $file | sed -e 's:[^/]*$::' -e 's:/$::' -e 's:$:/:' -e 's:^/$::'` from="$src/$file" to="$dst/$dir$basename" - if [ $oneisabs = 0 ]; then - if [ ".$dir" != . ]; then + if [ "x$oneisabs" = "x0" ]; then + if [ "x$dir" != "x" ]; then subdir=`echo $dir | sed -e 's:/$::'` # (inlined fp2rp) revdir='' diff --git a/usr.sbin/httpd/src/helpers/ppl.sh b/usr.sbin/httpd/src/helpers/ppl.sh index a53b0c45558..e83ab4793fc 100644 --- a/usr.sbin/httpd/src/helpers/ppl.sh +++ b/usr.sbin/httpd/src/helpers/ppl.sh @@ -4,7 +4,7 @@ ## `tr' and `fmt' because these tools are different ## between Unix platforms ## -## Written by Ralf S. Engelschall <rse@apache.org> +## Initially written by Ralf S. Engelschall <rse@apache.org> ## for pretty printing lists in the --help option of ## Apache's Autoconf-style Interface (APACI) ## @@ -16,7 +16,7 @@ list=` IFS=: for entry in $*; do - if [ ".$entry" != . ]; then + if [ "x$entry" != "x" ]; then echo $entry fi done |\ diff --git a/usr.sbin/httpd/src/helpers/slo.sh b/usr.sbin/httpd/src/helpers/slo.sh index 10820f5f1cb..e9d0e588134 100644 --- a/usr.sbin/httpd/src/helpers/slo.sh +++ b/usr.sbin/httpd/src/helpers/slo.sh @@ -1,7 +1,7 @@ #!/bin/sh ## ## slo.h -- (S)eparate (L)inker (O)ptions by library class -## Written by Ralf S. Engelschall <rse@apache.org> +## Initially written by Ralf S. Engelschall <rse@apache.org> ## # # This script falls under the Apache License. @@ -22,12 +22,12 @@ OIFS="$IFS" IFS="$DIFS" for opt do # concatenate with previous option if exists - if [ ".$optprev" != . ]; then + if [ "x$optprev" != "x" ]; then opt="${optprev}${opt}"; optprev='' fi # remember options for arg when used stand-alone - if [ ".$opt" = ".-L" -o ".$opt" = ".-l" ]; then + if [ "x$opt" = "x-L" -o "x$opt" = "x-l" ]; then optprev="$opt" continue; fi @@ -47,7 +47,7 @@ IFS="$OIFS" # set linker default directories # DIRS_DEFAULT='/lib:/usr/lib' -if [ ".$LD_LIBRARY_PATH" != . ]; then +if [ "x$LD_LIBRARY_PATH" != "x" ]; then DIRS_DEFAULT="$DIRS_DEFAULT:$LD_LIBRARY_PATH" fi @@ -64,7 +64,7 @@ LIBS_DSO='' # for each library... OIFS="$IFS" IFS=':' for lib in $LIBS; do - [ ".$lib" = . ] && continue + [ "x$lib" = "x" ] && continue found='no' found_indefdir='no' @@ -74,14 +74,14 @@ for lib in $LIBS; do # for each directory... OIFS2="$IFS" IFS=":$DIFS" for dir in ${DIRS} switch-to-defdirs ${DIRS_DEFAULT}; do - [ ".$dir" = . ] && continue - [ ".$dir" = .switch-to-defdirs ] && found_indefdir=yes + [ "x$dir" = "x" ] && continue + [ "x$dir" = "xswitch-to-defdirs" ] && found_indefdir=yes [ ! -d $dir ] && continue # search the file OIFS3="$IFS" IFS="$DIFS" for file in '' `cd $dir && ls lib${lib}.* 2>/dev/null`; do - [ ".$file" = . ] && continue + [ "x$file" = "x" ] && continue case $file in *.so|*.so.[0-9]*|*.sl|*.sl.[0-9]* ) found=yes; @@ -93,7 +93,7 @@ for lib in $LIBS; do found_type=PIC ;; *.a ) - if [ ".$found_type" = . ]; then + if [ "x$found_type" = "x" ]; then found=yes found_type=OBJ fi @@ -101,15 +101,15 @@ for lib in $LIBS; do esac done IFS="$OIFS3" - if [ ".$found" = .yes ]; then + if [ "x$found" = "xyes" ]; then found_dir="$dir" break fi done IFS="$OIFS2" - if [ ".$found" = .yes ]; then - if [ ".$found_indefdir" != .yes ]; then + if [ "x$found" = "xyes" ]; then + if [ "x$found_indefdir" != "xyes" ]; then eval "dirlist=\"\${DIRS_${found_type}}:\"" if [ ".`echo \"$dirlist\" | fgrep :$found_dir:`" = . ]; then eval "DIRS_${found_type}=\"\$DIRS_${found_type}:${found_dir}\"" @@ -148,7 +148,7 @@ for type in OBJ PIC DSO; do eval "libs=\"\$LIBS_${type}\"" opts='' for lib in $libs; do - [ ".$lib" = . ] && continue + [ "x$lib" = "x" ] && continue opts="$opts -l$lib" done eval "LIBS_${type}=\"$opts\"" @@ -156,7 +156,7 @@ for type in OBJ PIC DSO; do eval "dirs=\"\$DIRS_${type}\"" opts='' for dir in $dirs; do - [ ".$dir" = . ] && continue + [ "x$dir" = "x" ] && continue opts="$opts -L$dir" done eval "DIRS_${type}=\"$opts\"" diff --git a/usr.sbin/httpd/src/include/alloc.h b/usr.sbin/httpd/src/include/alloc.h index b68a89dc192..bc2777acd8d 100644 --- a/usr.sbin/httpd/src/include/alloc.h +++ b/usr.sbin/httpd/src/include/alloc.h @@ -93,10 +93,53 @@ typedef struct pool ap_pool; pool * ap_init_alloc(void); /* Set up everything */ API_EXPORT(pool *) ap_make_sub_pool(pool *); /* All pools are subpools of permanent_pool */ +#if defined(EAPI) +typedef enum { AP_POOL_RD, AP_POOL_RW } ap_pool_lock_mode; +int ap_shared_pool_possible(void); +void ap_init_alloc_shared(int); +void ap_kill_alloc_shared(void); +API_EXPORT(pool *) ap_make_shared_sub_pool(pool *); +API_EXPORT(int) ap_acquire_pool(pool *, ap_pool_lock_mode); +API_EXPORT(int) ap_release_pool(pool *); +#endif API_EXPORT(void) ap_destroy_pool(pool *); -/* used to guarantee to the pool debugging code that the sub pool will not be - * destroyed before the parent pool +/* pools have nested lifetimes -- sub_pools are destroyed when the + * parent pool is cleared. We allow certain liberties with operations + * on things such as tables (and on other structures in a more general + * sense) where we allow the caller to insert values into a table which + * were not allocated from the table's pool. The table's data will + * remain valid as long as all the pools from which its values are + * allocated remain valid. + * + * For example, if B is a sub pool of A, and you build a table T in + * pool B, then it's safe to insert data allocated in A or B into T + * (because B lives at most as long as A does, and T is destroyed when + * B is cleared/destroyed). On the other hand, if S is a table in + * pool A, it is safe to insert data allocated in A into S, but it + * is *not safe* to insert data allocated from B into S... because + * B can be cleared/destroyed before A is (which would leave dangling + * pointers in T's data structures). + * + * In general we say that it is safe to insert data into a table T + * if the data is allocated in any ancestor of T's pool. This is the + * basis on which the POOL_DEBUG code works -- it tests these ancestor + * relationships for all data inserted into tables. POOL_DEBUG also + * provides tools (ap_find_pool, and ap_pool_is_ancestor) for other + * folks to implement similar restrictions for their own data + * structures. + * + * However, sometimes this ancestor requirement is inconvenient -- + * sometimes we're forced to create a sub pool (such as through + * ap_sub_req_lookup_uri), and the sub pool is guaranteed to have + * the same lifetime as the parent pool. This is a guarantee implemented + * by the *caller*, not by the pool code. That is, the caller guarantees + * they won't destroy the sub pool individually prior to destroying the + * parent pool. + * + * In this case the caller must call ap_pool_join() to indicate this + * guarantee to the POOL_DEBUG code. There are a few examples spread + * through the standard modules. */ #ifndef POOL_DEBUG #ifdef ap_pool_join @@ -342,7 +385,7 @@ enum kill_conditions { }; typedef struct child_info child_info; -API_EXPORT(void) ap_note_subprocess(pool *a, int pid, +API_EXPORT(void) ap_note_subprocess(pool *a, pid_t pid, enum kill_conditions how); API_EXPORT(int) ap_spawn_child(pool *, int (*)(void *, child_info *), void *, enum kill_conditions, diff --git a/usr.sbin/httpd/src/include/ap.h b/usr.sbin/httpd/src/include/ap.h index ed18dbd002c..a04c90596a7 100644 --- a/usr.sbin/httpd/src/include/ap.h +++ b/usr.sbin/httpd/src/include/ap.h @@ -69,6 +69,7 @@ API_EXPORT(char *) ap_cpystrn(char *, const char *, size_t); int ap_slack(int, int); int ap_execle(const char *, const char *, ...); int ap_execve(const char *, const char *argv[], const char *envp[]); +API_EXPORT(int) ap_getpass(const char *prompt, char *pwbuf, size_t bufsiz); /* small utility macros to make things easier to read */ @@ -158,6 +159,31 @@ API_EXPORT(int) ap_snprintf(char *buf, size_t len, const char *format,...) __attribute__((format(printf,3,4))); API_EXPORT(int) ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap); +/* Simple BASE64 encode/decode functions. + * + * As we might encode binary strings, hence we require the length of + * the incoming plain source. And return the length of what we decoded. + * + * The decoding function takes any non valid char (i.e. whitespace, \0 + * or anything non A-Z,0-9 etc as terminal. + * + * plain strings/binary sequences are not assumed '\0' terminated. Encoded + * strings are neither. But propably should. + * + */ +API_EXPORT(int) ap_base64encode_len(int len); +API_EXPORT(int) ap_base64encode(char * coded_dst, const char *plain_src,int len_plain_src); +API_EXPORT(int) ap_base64encode_binary(char * coded_dst, const unsigned char *plain_src,int len_plain_src); + +API_EXPORT(int) ap_base64decode_len(const char * coded_src); +API_EXPORT(int) ap_base64decode(char * plain_dst, const char *coded_src); +API_EXPORT(int) ap_base64decode_binary(unsigned char * plain_dst, const char *coded_src); + +/* Password validation, as used in AuthType Basic which is able to cope + * (based on the prexix) with the SHA1, Apache's internal MD5 and (depending + * on your platform either plain or crypt(3) passwords. + */ +API_EXPORT(char *) ap_validate_password(const char *passwd, const char *hash); #ifdef __cplusplus } diff --git a/usr.sbin/httpd/src/include/ap_compat.h b/usr.sbin/httpd/src/include/ap_compat.h index 4da74a61d07..ec0c753bca5 100644 --- a/usr.sbin/httpd/src/include/ap_compat.h +++ b/usr.sbin/httpd/src/include/ap_compat.h @@ -23,6 +23,7 @@ extern "C" { #define acquire_mutex ap_acquire_mutex #define add_cgi_vars ap_add_cgi_vars #define add_common_vars ap_add_common_vars +#define add_file_conf ap_add_file_conf #define add_module ap_add_module #define add_named_module ap_add_named_module #define add_per_dir_conf ap_add_per_dir_conf @@ -118,6 +119,7 @@ extern "C" { #define escape_html ap_escape_html #define escape_path_segment ap_escape_path_segment #define escape_shell_cmd ap_escape_shell_cmd +#define escape_uri ap_escape_uri #define excess_requests_per_child ap_excess_requests_per_child #define exists_scoreboard_image ap_exists_scoreboard_image #define finalize_request_protocol ap_finalize_request_protocol @@ -303,6 +305,8 @@ extern "C" { #define rationalize_mtime ap_rationalize_mtime #define read_config ap_read_config #define read_request ap_read_request +#define regexec ap_regexec +#define regerror ap_regerror #define register_cleanup ap_register_cleanup #define register_other_child ap_register_other_child #define release_mutex ap_release_mutex @@ -349,6 +353,7 @@ extern "C" { #define server_root_relative ap_server_root_relative #define set_byterange ap_set_byterange #define set_callback_and_alarm ap_set_callback_and_alarm +#define set_config_vectors ap_set_config_vectors #define set_content_length ap_set_content_length #define set_etag ap_set_etag #define set_file_slot ap_set_file_slot diff --git a/usr.sbin/httpd/src/include/ap_config.h b/usr.sbin/httpd/src/include/ap_config.h index 1b98de0a394..e7219cf892e 100644 --- a/usr.sbin/httpd/src/include/ap_config.h +++ b/usr.sbin/httpd/src/include/ap_config.h @@ -95,7 +95,9 @@ stat() properly */ * means. In particular it's missing inline and the __attribute__ * stuff. So we hack around it. PR#1613. -djg */ -#if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7 || defined(NEXT) +#if !defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ||\ + defined(NEXT) #define ap_inline #define __attribute__(__x) #define ENUM_BITFIELD(e,n,w) signed int n : w @@ -316,11 +318,34 @@ typedef int rlim_t; typedef int rlim_t; #elif defined(SEQUENT) -#define HAVE_GMTOFF 1 -#undef NO_KILLPG -#define NO_SETSID -#define NEED_STRDUP +#define DEFAULT_USER "nobody" +#define DEFAULT_GROUP "nobody" +#define NO_SHMGET 1 +#define HAVE_MMAP 1 #define HAVE_SYSLOG 1 +#define USE_MMAP_FILES 1 +#define USE_MMAP_SCOREBOARD 1 +#define USE_FCNTL_SERIALIZED_ACCEPT 1 +#define JMP_BUF sigjmp_buf +#undef NO_SETSID +#if SEQUENT < 40 +typedef int rlim_t; +#define NO_GETTIMEOFDAY +#undef HAVE_SYS_RESOURCE_H /* exists but does not provide *rlimit funcs */ +#include <sys/times.h> +#endif +#if SEQUENT < 42 +#define NEED_STRCASECMP +#define NEED_STRNCASECMP +#endif +#if SEQUENT < 44 +#define NO_KILLPG 1 +#define NET_SIZE_T int +#endif +#if SEQUENT >= 44 +#undef NO_KILLPG +#define NET_SIZE_T size_t +#endif #elif defined(NEXT) typedef unsigned short mode_t; @@ -365,10 +390,6 @@ typedef unsigned short mode_t; #endif #ifndef S_IWOTH #define S_IWOTH 000002 -#ifndef rlim_t -typedef int rlim_t; -#endif -typedef u_long n_long; #endif #define STDIN_FILENO 0 @@ -386,12 +407,29 @@ typedef int pid_t; #define NO_USE_SIGACTION #define HAVE_SYSLOG 1 -#elif defined(RHAPSODY) /* Mac OS X Server */ +#if defined(__DYNAMIC__) +#define HAVE_DYLD +#define DYLD_CANT_UNLOAD +#endif + +#elif defined(MAC_OS) || defined(MAC_OS_X_SERVER) /* Mac OS (>= 10.0) and Mac OS X Server (<= 5.x) */ +#undef PLATFORM +#ifdef MAC_OS_X_SERVER +#define PLATFORM "Mac OS X Server" +#else +#define PLATFORM "Mac OS" +#endif +#define HAVE_DYLD +#ifdef MAC_OS_X_SERVER +#define DYLD_CANT_UNLOAD +#endif /* MAC_OS_X_SERVER */ #define HAVE_GMTOFF #define HAVE_MMAP #define USE_MMAP_FILES #define USE_MMAP_SCOREBOARD +#ifdef MAC_OS_X_SERVER #define MAP_TMPFILE +#endif /* MAC_OS_X_SERVER */ #define HAVE_RESOURCE #define HAVE_SNPRINTF #define JMP_BUF jmp_buf @@ -399,26 +437,52 @@ typedef int pid_t; #define USE_FLOCK_SERIALIZED_ACCEPT #define SINGLE_LISTEN_UNSERIALIZED_ACCEPT /* - * If you are using APACI, (you should be on Rhapsody) these - * values are set at configure time. These are here as reference; - * the apache that is built into Rhapsody is configured with - * these values. + * If you are using APACI, (you probably should be on Mac OS) these + * values are set at configure time. */ -#if 0 +#ifndef HTTPD_ROOT #define HTTPD_ROOT "/Local/Library/WebServer" +#endif +#ifndef DOCUMENT_LOCATION #define DOCUMENT_LOCATION HTTPD_ROOT "/Documents" +#endif +#ifndef DEFAULT_XFERLOG #define DEFAULT_XFERLOG "Logs/Access" +#endif +#ifndef DEFAULT_ERRORLOG #define DEFAULT_ERRORLOG "Logs/Errors" +#endif +#ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "Logs/Process" +#endif +#ifndef DEFAULT_SCOREBOARD #define DEFAULT_SCOREBOARD "Logs/Status" +#endif +#ifndef DEFAULT_LOCKFILE #define DEFAULT_LOCKFILE "Logs/Lock" +#endif +#ifndef SERVER_CONFIG_FILE #define SERVER_CONFIG_FILE "Configuration/Server" +#endif +#ifndef RESOURCE_CONFIG_FILE #define RESOURCE_CONFIG_FILE "Configuration/Resources" +#endif +#ifndef TYPES_CONFIG_FILE #define TYPES_CONFIG_FILE "Configuration/MIME" +#endif +#ifndef ACCESS_CONFIG_FILE #define ACCESS_CONFIG_FILE "Configuration/Access" +#endif +#ifndef DEFAULT_USER_DIR #define DEFAULT_USER_DIR "Library/Web Documents" -#define DEFAULT_USER "nobody" -#define DEFAULT_GROUP "nogroup" +#endif +#ifndef DEFAULT_USER +#define DEFAULT_USER "www" +#endif +#ifndef DEFAULT_GROUP +#define DEFAULT_GROUP "www" +#endif +#ifndef DEFAULT_PATH #define DEFAULT_PATH "/bin:/usr/bin:/usr/local/bin" #endif @@ -458,7 +522,13 @@ typedef int pid_t; #define USE_MMAP_FILES /* flock is faster ... but hasn't been tested on 1.x systems */ -#define USE_FLOCK_SERIALIZED_ACCEPT +/* PR#3531 indicates flock() may not be stable, probably depends on + * kernel version. Go back to using fcntl, but provide a way for + * folks to tweak their Configuration to get flock. + */ +#ifndef USE_FLOCK_SERIALIZED_ACCEPT +#define USE_FCNTL_SERIALIZED_ACCEPT +#endif #define SYS_SIGLIST _sys_siglist @@ -559,12 +629,10 @@ extern char *crypt(); #define HAVE_SHMGET 1 #define USE_SHMGET_SCOREBOARD #ifdef _OSD_POSIX /* BS2000-POSIX mainframe needs initgroups */ -#define NEED_INITGROUPS #define NEED_HASHBANG_EMUL /* execve() doesn't start shell scripts by default */ -#undef HAVE_SHMGET +#define _KMEMUSER /* Enable SHM_R/SHM_W defines in <shm.h> */ #undef NEED_STRCASECMP #undef NEED_STRNCASECMP -#undef USE_SHMGET_SCOREBOARD #undef bzero #endif /*_OSD_POSIX*/ @@ -738,13 +806,14 @@ typedef int rlim_t; #define NO_KILLPG #define NEED_STRCASECMP #define NEED_STRNCASECMP +#define NEED_PROCESS_H #define NO_SETSID #define NO_TIMES #define CASE_BLIND_FILESYSTEM /* Add some drive name support */ #define chdir _chdir2 #include <sys/time.h> -#define MAXSOCKETS 4096 +#define MAXSOCKETS 2048 #define USE_OS2_SCOREBOARD #define NO_RELIABLE_PIPED_LOGS #define USE_OS2SEM_SERIALIZED_ACCEPT @@ -844,10 +913,16 @@ typedef int rlim_t; #include <sysgtime.h> #define PRIMECRAS 0x010000 #define JMP_BUF jmp_buf +#define HAVE_SHMGET +#undef HAVE_SYS_RESOURCE_H #define NEED_INITGROUPS +#define NEED_SIGNAL_INTERRUPT +#include <strings.h> +#ifndef __strings_h #define NEED_STRCASECMP -#define NEED_STRDUP #define NEED_STRNCASECMP +#endif +#define NEED_STRDUP #define NO_DBM_REWRITEMAP #define NO_GETTIMEOFDAY #define NO_KILLPG @@ -856,16 +931,26 @@ typedef int rlim_t; #define NO_OTHER_CHILD #define NO_RELIABLE_PIPED_LOGS #define NO_SETSID -#define NO_SHMGET #define NO_SLACK #define NO_TIMES #define NO_USE_SIGACTION #define NO_WRITEV #define USE_LONGJMP +/*#define USE_SHMGET_SCOREBOARD*/ +#define USE_TPF_ACCEPT +#define USE_TPF_CORE_SERIALIZED_ACCEPT +/*#define USE_TPF_DAEMON*/ +#define USE_TPF_SCOREBOARD #define USE_TPF_SELECT #undef offsetof #define offsetof(s_type,field) ((size_t)&(((s_type*)0)->field)) +#elif defined(__TANDEM) +#define NO_WRITEV +#define NO_KILLPG +#define NEED_INITGROUPS +#define NO_SLACK + #else /* Unknown system - Edit these to match */ #ifdef BSD @@ -919,7 +1004,7 @@ typedef int rlim_t; * __private_extern__. * For other systems, make that a no-op. */ -#if defined(RHAPSODY) +#if (defined(MAC_OS) || defined(MAC_OS_X_SERVER)) && defined(__DYNAMIC__) #define ap_private_extern __private_extern__ #else #define ap_private_extern @@ -949,8 +1034,11 @@ typedef int rlim_t; #include <stdio.h> #include <stdlib.h> #include <string.h> +#ifdef __TANDEM +#include <strings.h> +#endif #include "ap_ctype.h" -#if !defined(MPE) && !defined(WIN32) && !defined(TPF) +#if !defined(MPE) && !defined(WIN32) && !defined(TPF) && !defined(__TANDEM) #include <sys/file.h> #endif #ifndef WIN32 @@ -970,24 +1058,26 @@ typedef int rlim_t; #include <pwd.h> #include <grp.h> #include <fcntl.h> -#include <limits.h> #define closesocket(s) close(s) #ifndef O_BINARY #define O_BINARY (0) #endif #else /* WIN32 */ -#include <winsock.h> +#include <winsock2.h> #include <malloc.h> #include <io.h> #include <fcntl.h> #endif /* ndef WIN32 */ - +#include <limits.h> #include <time.h> /* for ctime */ #ifdef WIN32 #define strftime(s,max,format,tm) os_strftime(s,max,format,tm) #endif #include <signal.h> +#if defined(TPF) && defined(NSIG) +#undef NSIG +#endif #include <errno.h> #if !defined(QNX) && !defined(CONVEXOS11) && !defined(NEXT) && !defined(TPF) #include <memory.h> @@ -1090,13 +1180,32 @@ Sigfunc *signal(int signo, Sigfunc * func); #endif #endif -#ifdef SELECT_NEEDS_CAST +/* Majority of os's want to verify FD_SETSIZE */ +#if !defined(WIN32) && !defined(TPF) +#define CHECK_FD_SETSIZE +#endif + +#ifdef USE_TPF_SELECT #define ap_select(_a, _b, _c, _d, _e) \ + tpf_select(_a, _b, _c, _d, _e) +#elif defined(SELECT_NEEDS_CAST) +#define ap_select(_a, _b, _c, _d, _e) \ select((_a), (int *)(_b), (int *)(_c), (int *)(_d), (_e)) -#elif defined(USE_TPF_SELECT) -#define ap_select tpf_select #else -#define ap_select select +#define ap_select(_a, _b, _c, _d, _e) \ + select(_a, _b, _c, _d, _e) +#endif + +#ifdef USE_TPF_ACCEPT +#define ap_accept(_fd, _sa, _ln) tpf_accept(_fd, _sa, _ln) +#else +#define ap_accept(_fd, _sa, _ln) accept(_fd, _sa, _ln) +#endif + +#ifdef NEED_SIGNAL_INTERRUPT +#define ap_check_signals() tpf_process_signals() +#else +#define ap_check_signals() #endif #ifdef ULTRIX_BRAIN_DEATH diff --git a/usr.sbin/httpd/src/include/ap_ctx.h b/usr.sbin/httpd/src/include/ap_ctx.h index 85a8ae93322..18f0f334e7f 100644 --- a/usr.sbin/httpd/src/include/ap_ctx.h +++ b/usr.sbin/httpd/src/include/ap_ctx.h @@ -60,6 +60,8 @@ ** Written by Ralf S. Engelschall <rse@engelschall.com> */ +#ifdef EAPI + #ifndef AP_CTX_H #define AP_CTX_H @@ -87,11 +89,22 @@ typedef struct { typedef ap_ctx_rec ap_ctx; /* + * Some convinience macros for storing _numbers_ 0...n in contexts, i.e. + * treating numbers as pointers but keeping track of the NULL return code of + * ap_ctx_get. + */ +#define AP_CTX_NUM2PTR(n) (void *)((unsigned int)(n)+1) +#define AP_CTX_PTR2NUM(p) (unsigned int)(((char *)(p))-1) + +/* * Prototypes for Context Handling Functions */ API_EXPORT(ap_ctx *)ap_ctx_new(pool *p); API_EXPORT(void) ap_ctx_set(ap_ctx *ctx, char *key, void *val); API_EXPORT(void *) ap_ctx_get(ap_ctx *ctx, char *key); +API_EXPORT(ap_ctx *)ap_ctx_overlay(pool *p, ap_ctx *over, ap_ctx *base); #endif /* AP_CTX_H */ + +#endif /* EAPI */ diff --git a/usr.sbin/httpd/src/include/ap_ctype.h b/usr.sbin/httpd/src/include/ap_ctype.h index c4ff812d5ee..e0a6abcaa07 100644 --- a/usr.sbin/httpd/src/include/ap_ctype.h +++ b/usr.sbin/httpd/src/include/ap_ctype.h @@ -79,6 +79,7 @@ extern "C" { #define ap_ispunct(c) (ispunct(((unsigned char)(c)))) #define ap_isspace(c) (isspace(((unsigned char)(c)))) #define ap_isupper(c) (isupper(((unsigned char)(c)))) +#define ap_isxdigit(c) (isxdigit(((unsigned char)(c)))) #define ap_tolower(c) (tolower(((unsigned char)(c)))) #define ap_toupper(c) (toupper(((unsigned char)(c)))) diff --git a/usr.sbin/httpd/src/include/ap_hook.h b/usr.sbin/httpd/src/include/ap_hook.h index 532dec8bc8d..d00bfec924b 100644 --- a/usr.sbin/httpd/src/include/ap_hook.h +++ b/usr.sbin/httpd/src/include/ap_hook.h @@ -1,3 +1,6 @@ +#if 0 +=cut +#endif /* ==================================================================== * Copyright (c) 1998 The Apache Group. All rights reserved. * @@ -56,183 +59,21 @@ */ /* -** Generic Hook Interface for Apache +** Implementation of a Generic Hook Interface for Apache ** Written by Ralf S. Engelschall <rse@engelschall.com> ** -** SYNOPSIS -** -** Main Setup: -** void ap_hook_init (void); -** void ap_hook_kill (void); -** -** Hook Configuration and Registration: -** int ap_hook_configure (char *hook, int sig, int modeid, ap_hook_value modeval); -** int ap_hook_register (char *hook, void *func, void *ctx); -** int ap_hook_unregister(char *hook, void *func); -** -** Hook Usage: -** int ap_hook_configured(char *hook); -** int ap_hook_registered(char *hook); -** int ap_hook_call (char *hook, ...); -** -** DESCRIPTION -** -** This implements a generic hook interface for Apache which can be used -** for loosely couple code through arbitrary hooks. There are two use cases -** for this mechanism: -** -** 1. Inside a specific code section you want to perform a specific -** function call. But you want to allow one or even more modules to -** override this function call by registering hook functions. Those -** functions are registered on a stack and can be configured to have a -** `decline' return value. As long as there are functions which return -** the `decline' value the next function on the stack is tried. When a -** function doesn't return the `decline' value the hook call stops. The -** intent of this usage is to not hard-code function calls. -** -** 2. Inside a specific code you have a function you want to export. -** But you first want to allow other code to override this function. -** And second you want to export this function without real linker -** symbol references. Instead you want to register the function and let -** the users call this function via name. The intent of this usage is to -** allow inter-module communication without direct symbol references, -** which are a big NO-NO for the DSO situation. -** -** And we have one major design goal: The hook call should be very similar -** to the corresponding direct function call while still providing maximum -** flexiblity, i.e. any function signature (the set of types for the return -** value and the arguments) should be supported. And it should be possible -** to register always a context (ctx) variable with a function which is -** passed to the corresponding function when the hook call is performed. -** -** Using this hook interface is always a four-step process: -** -** 1. Initialize or destroy the hook mechanism inside your main program: -** -** ap_hook_init(); -** : -** ap_hook_kill(); -** -** 2. Configure a particular hook by specifing its name, signature -** and return type semantic: -** -** ap_hook_configure("lookup", AP_HOOK_SIG2(ptr,ptr,ctx), AP_HOOK_DECLINE(NULL)); -** ap_hook_configure("echo", AP_HOOK_SIG2(int,ptr), AP_HOOK_TOPMOST); -** -** This configures two hooks: -** - A hook named "lookup" with the signature "void *lookup(void *)" -** and a return code semantic which says: As long as a registered hook -** function returns NULL and more registered functions exists we we -** proceed. -** - A hook named "echo" with the signature "int echo(void *)" and a -** return code semantic which says: Only the top most function on the -** registered function stack is tried, independed what value it -** returns. -** -** 3. Register the actual functions which should be used by the hook: -** -** ap_hook_register("lookup", mylookup, mycontext); -** ap_hook_register("echo", myecho); -** -** This registers the function mylookup() under the "lookup" hook with -** the context given by the variable mycontext. And it registers the -** function myecho() under the "echo" hook without any context. -** -** 4. Finally use the hook, i.e. instead of using direct function calls -** like -** -** vp = mylookup("foo", mycontext); -** n = myecho("bar"); -** -** you now can use: -** -** ap_hook_call("lookup", &vp, "foo"); -** ap_hook_call("echo", &n, "bar"); -** -** Notice two things: First the context for the mylookup() function is -** automatically added by the hook mechanism. And it is a different and -** not fixed context for each registered function, of course. Second, -** return values always have to be pushed into variables and they a -** pointer to them has to be given as the second argument (except for -** functions which have a void return type, of course). -** -** BTW, the return value of ap_hook_call() is TRUE or FALSE. TRUE when -** at least one function call was successful (always the case for -** AP_HOOK_TOPMOST). FALSE when all functions returned the decline -** value or no functions are registered at all. -** -** RESTRICTIONS -** -** To make the hook implementation efficient and to not bloat up the code a -** few restrictions have to make: -** -** 1. Only function calls with up to 4 arguments are supported. -** When more are needed you can either extend the hook implementation by -** using more bits for the signature configuration or you can do a -** workaround when the functions is your own one: Put the remaining -** (N-5) arguments into a structure and pass only a pointer (one -** argument) as the forth argument. -** -** 2. Only the following types are supported: -** - For the return value: -** void (= none), char, int, float, double, ptr (= void*) -** - For the arguments: -** ctx (= context), char, int, float, double, ptr (= void*) -** This means in theory there are 6^5 (=7776) signature combinations are -** possible. But because we don't need all of them inside Apache and it -** would bloat up the code dramatically we implement only a subset of -** those combinations. The to be implemented signatures can be specified -** inside ap_hook.c and the corresponding code can be automatically -** generated by running `perl ap_hook.c' (yeah, no joke ;-). So when -** you need a hook with a different still not implemented signature you -** either have to again use a workaround as above (i.e. use a structure) -** or just add the signature to the ap_hook.c file. -** -** EXAMPLE -** -** We want to call `ssize_t read(int, void *, size_t)' through hooks in -** order to allow modules to override this call. So, somewhere we have a -** replacement function for read() defined: -** -** ssize_t my_read(int, void *, size_t); -** -** We now configure a `read' hook. Here the AP_HOOK_SIGx() macro defines -** the signature of the read()-like callback functions and has to match the -** prototype of read(). But we have to replace typedefs with the physical -** types. And AP_HOOK_DECLINE() sets the return value of the read()-like -** functions which forces the next hook to be called (here -1). And we -** register the original read function. -** -** ap_hook_configure("read", AP_HOOK_SIG4(int,int,ptr,int), -** AP_HOOK_DECLINE(-1)); -** ap_hook_register("read", read); -** -** Now a module wants to override the read() call and registers one more -** function (which has to match the same prototype as read() of course): -** -** ap_hook_register("read", my_read); +** See POD document at end of this file for description. +** View it with the command ``pod2man ap_hook.h | nroff -man | more'' ** -** The function logically gets pushed onto a stack, so the execution order -** is the reverse register order, i.e. last registered - first called. Now -** we can replace the standard read() call -** -** bytes = read(fd, buf, bufsize); -** if (bytes == -1) -** ...error... -** -** with the hook-call: -** -** rc = ap_hook_call("read", &bytes, fd, buf, bufsize); -** if (rc == FALSE) -** ...error... -** -** Now internally the following is done: The call "bytes = my_read(fd, buf, -** bufsize)" is done. When it returns not -1 (the decline value) nothing -** more is done. But when my_read() returned -1 the next function is tried: -** "bytes = read(fd, buf, bufsize)". When this one returns -1 again you get -** rc == FALSE. When it finally returns not -1 you get rc == TRUE. +** Attention: This header file is a little bit tricky. +** It's a combination of a C source and an embedded POD document +** The purpose of this is to have both things together at one +** place. So you can both pass this file to the C compiler and +** the pod2man translater. */ +#ifdef EAPI + #ifndef AP_HOOK_H #define AP_HOOK_H @@ -414,11 +255,13 @@ typedef unsigned int ap_hook_mode; #define AP_HOOK_MODE_UNKNOWN 0 #define AP_HOOK_MODE_TOPMOST 1 #define AP_HOOK_MODE_DECLINE 2 -#define AP_HOOK_MODE_ALL 3 +#define AP_HOOK_MODE_DECLTMP 3 +#define AP_HOOK_MODE_ALL 4 /* the constructors for the return value modes */ #define AP_HOOK_TOPMOST AP_HOOK_MODE_TOPMOST #define AP_HOOK_DECLINE(val) AP_HOOK_MODE_DECLINE, (val) +#define AP_HOOK_DECLTMP(val) AP_HOOK_MODE_DECLTMP, (val) #define AP_HOOK_ALL AP_HOOK_MODE_ALL /* @@ -543,3 +386,325 @@ API_EXPORT(int) ap_hook_use (char *hook, ap_hook_sig sig, ap_ API_EXPORT(int) ap_hook_call (char *hook, ...); #endif /* AP_HOOK_H */ + +#endif /* EAPI */ +/* +=pod +## +## Embedded POD document +## + +=head1 NAME + +B<ap_hook> - B<Generic Hook Interface for Apache> + +=head1 SYNOPSIS + +B<Hook Library Setup:> + + void ap_hook_init(void); + void ap_hook_kill(void); + +B<Hook Configuration and Registration:> + + int ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode mode); + int ap_hook_register(char *hook, void *func, void *ctx); + int ap_hook_unregister(char *hook, void *func); + +B<Hook Usage:> + + ap_hook_state ap_hook_status(char *hook); + int ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode mode, ...); + int ap_hook_call(char *hook, ...); + +B<Hook Signature Constructors> (ap_hook_sig): + + AP_HOOK_SIG1(rc) + AP_HOOK_SIG2(rc,a1) + AP_HOOK_SIG3(rc,a1,a2) + AP_HOOK_SIG4(rc,a1,a2,a3) + AP_HOOK_SIG5(rc,a1,a2,a3,a4) + AP_HOOK_SIG6(rc,a1,a2,a3,a4,a5) + AP_HOOK_SIG7(rc,a1,a2,a3,a4,a5,a6) + AP_HOOK_SIG8(rc,a1,a2,a3,a4,a5,a6,a7) + +B<Hook Modes Constructors> (ap_hook_mode): + + AP_HOOK_TOPMOST + AP_HOOK_DECLINE(value) + AP_HOOK_DECLTMP(value) + AP_HOOK_ALL + +B<Hook States> (ap_hook_state): + + AP_HOOK_STATE_UNDEF + AP_HOOK_STATE_NOTEXISTANT + AP_HOOK_STATE_ESTABLISHED + AP_HOOK_STATE_CONFIGURED + AP_HOOK_STATE_REGISTERED + +=head1 DESCRIPTION + +This library implements a generic hook interface for Apache which can be used +to loosely couple code through arbitrary hooks. There are two use cases for +this mechanism: + +=over 3 + +=item B<1. Extension and Overrides> + +Inside a specific code section you want to perform a specific function call +for extension reasons. But you want to allow one or more modules to implement +this function by registering hooks. Those hooks are registered on a stack and +can be even configured to have a I<decline> return value. As long as there are +functions which return the decline value the next function on the stack is +tried. When the first function doesn't return the decline value the hook call +stops. + +The original intent of this use case is to provide a flexible extension +mechanism where modules can override functionality. + +=item B<2. Intercommunication> + +Inside a specific code you have a function you want to export. But you first +want to allow other code to override this function. And second you want to +export this function without real object file symbol references. Instead you +want to register the function and let the users call this function by name. + +The original intent of this use case is to allow inter-module communication +without direct symbol references, which are a big I<no-no> for the I<Dynamic +Shared Object> (DSO) situation. + +=back + +And the following design goals existed: + +=over 3 + +=item B<1. Minimum code changes> + +The hook calls should look very similar to the corresponding direct function +call to allow one to easily translate it. And the total amount of changes for +the hook registration, hook configuration and hook usage should be as small as +possible to minimize the total code changes. Additionally a shorthand API +function (ap_hook_use) should be provided which lets one trivially add a hook +by just changing the code at a single location. + +=item B<2. The hook call has to be maximum flexible> + +In order to avoid nasty hacks, maximum flexiblity for the hook calls is +needed, i.e. any function signature (the set of types for the return value and +the arguments) should be supported. And it should be possible to +register always a context (ctx) variable with a function which is passed to +the corresponding function when the hook call is performed. + +=back + +The implementation of this library directly followed these two design goals. + +=head1 USAGE + +Using this hook API is a four-step process: + +=over 3 + +=item B<1. Initialization> + +Initialize or destroy the hook mechanism inside your application program: + + ap_hook_init(); + : + ap_hook_kill(); + +=item B<2. Configuration> + +Configure a particular hook by specifing its name, signature and return type +semantic: + + ap_hook_configure("lookup", AP_HOOK_SIG2(ptr,ptr,ctx), AP_HOOK_DECLINE(NULL)); + ap_hook_configure("setup", AP_HOOK_SIG2(int,ptr,char), AP_HOOK_DECLTMP(FALSE)); + ap_hook_configure("read", AP_HOOK_SIG2(void,ptr), AP_HOOK_TOPMOST); + ap_hook_configure("logit", AP_HOOK_SIG2(void,ptr), AP_HOOK_ALL); + +This configures four hooks: + +A hook named C<lookup> with the signature C<void *lookup(void *, void *)> +(where the second argument is C<NULL> or the private context pointer of the +hook function which can be optionally provided at the registration step +later) and a return code semantic which says: Proceed as long as the +registered lookup functions return C<NULL> or no more registered functions +exists. A call for this hook has to provide 2 argument only (a pointer to the +return variable and the first argument), because the context is +implicitly provided by the hook mechanism. Sample idea: I<The first function +who was successful in looking up a variable provides the value>. + +A hook named C<setup> with the signature C<int setup(void *, char)" and a +return code semantic equal to the one of the C<lookup> hook. But the decline +return value is implemented by a temporay variable of the hook mechanism and +only used for the decline decision. So a call to this hook has to provide 2 +arguments only (the first and second argument, but no address to a return +value). Sample idea: I<Any function can handle the setup and when one +function handled it stops the processing by indicating this with the return +value>. + +A hook named C<read> with the signature C<void read(void *)> and a return code +semantic which says: Only the top most function on the registered function +stack is tried (and independet of a possible return value in non-void +context). A call to this hook has to provide exactly 1 argument (the +single argument to the hook function). Sample idea: I<We want to +use a read function and allow others to override it, but independent how much +registered functions exists, only top most (= last registered) function +overrides and is used>. + +A hook named C<logit> with the signature C<void logit(void *)> and a return +code semantic which says: All registered functions on the hook functioin stack +are tried. Sample idea: I<We pass a FILE pointer to the logging functions and +any function can log whatever it wants>. + +=item B<3. Registration> + +Register the actual functions which should be used by the hook: + + ap_hook_register("lookup", mylookup, mycontext); + ap_hook_register("setup", mysetup); + ap_hook_register("read", myread); + ap_hook_register("logit", mylogit); + +This registers the function C<mylookup()> under the C<lookup> hook with the +private context given by the variable C<mycontext>. And it registers the +function C<mysetup()> under the C<setup> hook without any context. Same for +C<myread> and C<mylogit>. + +=item B<4. Usage> + +Finally use the hooks, i.e. instead of using direct function calls like + + rc = mylookup(a1, a2); + rc = mysetup(a1, a2); + myread(a1); + mylogit(a1); + +you now use: + + ap_hook_call("lookup", &rc, a1, a2); + ap_hook_call("setup", &rc, a1, a2); + ap_hook_call("read", a1); + ap_hook_call("logit", a1); + +which are internally translated to: + + rc = mylookup(a1, a2, mycontext); + rc = mysetup(a1, a2); + myread(a1); + mylogit(a1); + +Notice two things here: First the context (C<mycontext>) for the C<mylookup()> +function is automatically added by the hook mechanism. And it is a different +(and not fixed) context for each registered function, of course. Second, +return values always have to be pushed into variables and a pointer to them +has to be given as the second argument to C<ap_hook_call> (except for +functions which have a void return type, of course). + +BTW, the return value of C<ap_hook_call()> is always C<TRUE> or C<FALSE>. +C<TRUE> when at least one function call was successful (always the case for +C<AP_HOOK_TOPMOST> and C<AP_HOOK_ALL>). C<FALSE> when all functions +returned the decline value or no functions are registered at all. + +=back + +=head1 RESTRICTIONS + +To make the hook implementation efficient and to not bloat up the code too +much a few restrictions have to make: + +=over 3 + +=item 1. + +Only function calls with up to 4 arguments are implemented. When more are +needed you can either extend the hook implementation by using more bits for +the signature configuration or you can do a workaround when the function is +your own one: Put the remaining (N-4-1) arguments into a structure and pass +only a pointer (one argument) as the forth argument. + +=item 2. + +Only the following ANSI C variable types are supported: + + - For the return value: + void (= none), char, int, float, double, ptr (= void *) + - For the arguments: + ctx (= context), char, int, float, double, ptr (= void *) + +This means in theory that 6^5 (=7776) signature combinations are possible. But +because we don't need all of them inside Apache and it would bloat up the code +too dramatically we implement only a subset of those combinations. The +implemented signatures can be specified inside C<ap_hook.c> and the +corresponding code can be automatically generated by running ``C<perl +ap_hook.c>'' (yeah, no joke ;-). So when you need a hook with a different +still not implemented signature you either have to again use a workaround as +above (i.e. use a structure) or just add the signature to the C<ap_hook.c> +file. + +=head1 EXAMPLE + +We want to call `C<ssize_t read(int, void *, size_t)>' through hooks in order +to allow modules to override this call. So, somewhere we have a replacement +function for C<read()> defined (same signature, of course): + + ssize_t my_read(int, void *, size_t); + +We now configure a C<read> hook. Here the C<AP_HOOK_SIGx()> macro defines the +signature of the C<read()>-like callback functions and has to match the +prototype of C<read()>. But we have to replace typedefs with the physical +underlaying ANSI C types. And C<AP_HOOK_DECLINE()> sets the return value of +the read()-like functions which forces the next hook to be called (here -1). +And we register the original C<read()> function as the default hook. + + ap_hook_configure("read", + AP_HOOK_SIG4(int,int,ptr,int), + AP_HOOK_DECLINE(-1)); + ap_hook_register("read", read); + +Now a module wants to override the C<read()> call and registers the +C<my_read()> function: + + ap_hook_register("read", my_read); + +The function logically gets pushed onto a stack, so the execution order is the +reverse registering order, i.e. I<last registered - first called>. Now we can +replace the standard C<read()> call + + bytes = read(fd, buf, bufsize); + if (bytes == -1) + ...error... + +with the hook based call: + + rc = ap_hook_call("read", &bytes, fd, buf, bufsize); + if (rc == FALSE) + ...error... + +Now internally the following is done: The call `C<bytes = my_read(fd, buf, +bufsize)>' is done. When it returns not -1 (the decline value) nothing +more is done. But when C<my_read()> returns -1 the next function is tried: +`C<bytes = read(fd, buf, bufsize)>'. When this one also returns -1 you get +`rc == FALSE'. When it finally returns not -1 you get `rc == TRUE'. + +=head1 SEE ALSO + +ap_ctx(3) + +=head1 HISTORY + +The ap_hook(3) interface was originally designed and implemented in October +1998 by Ralf S. Engelschall as part of the mod_ssl project. + +=head1 AUTHOR + + Ralf S. Engelschall + rse@engelschall.com + www.engelschall.com + +=cut +*/ diff --git a/usr.sbin/httpd/src/include/ap_md5.h b/usr.sbin/httpd/src/include/ap_md5.h index 0da983c62fd..1e5b9cdaa8a 100644 --- a/usr.sbin/httpd/src/include/ap_md5.h +++ b/usr.sbin/httpd/src/include/ap_md5.h @@ -104,10 +104,21 @@ typedef struct { unsigned char buffer[64]; /* input buffer */ } AP_MD5_CTX; -API_EXPORT(void) ap_MD5Init(AP_MD5_CTX * context); -API_EXPORT(void) ap_MD5Update(AP_MD5_CTX * context, const unsigned char *input, - unsigned int inputLen); -API_EXPORT(void) ap_MD5Final(unsigned char digest[16], AP_MD5_CTX * context); +/* + * Define the Magic String prefix that identifies a password as being + * hashed using our algorithm. + */ +#define AP_MD5PW_ID "$apr1$" +#define AP_MD5PW_IDLEN 6 + +API_EXPORT(void) ap_MD5Init(AP_MD5_CTX *context); +API_EXPORT(void) ap_MD5Update(AP_MD5_CTX *context, const unsigned char *input, + unsigned int inputLen); +API_EXPORT(void) ap_MD5Final(unsigned char digest[16], AP_MD5_CTX *context); +API_EXPORT(void) ap_MD5Encode(const unsigned char *password, + const unsigned char *salt, + char *result, size_t nbytes); +API_EXPORT(void) ap_to64(char *s, unsigned long v, int n); #ifdef __cplusplus } diff --git a/usr.sbin/httpd/src/include/ap_mmn.h b/usr.sbin/httpd/src/include/ap_mmn.h index 4a4316027d1..e34607926f6 100644 --- a/usr.sbin/httpd/src/include/ap_mmn.h +++ b/usr.sbin/httpd/src/include/ap_mmn.h @@ -203,6 +203,29 @@ * scan_script_header -> ap_scan_script_header_err * - reordered entries in request_rec that were waiting * for a non-binary-compatible release. + * (1.3.5-dev) + * 19990108.1 - add ap_MD5Encode() for MD5 password handling. + * 19990108.2 - add ap_validate_password() and change ap_MD5Encode() + * to use a stronger algorithm. + * 19990108.4 - add ap_size_list_item(), ap_get_list_item(), and + * ap_find_list_item() + * 19990108.5 - added ap_sub_req_method_uri() and added const to the + * definition of method in request_rec. + * 19990108.6 - SIGPIPE is now ignored by the core server. + * 19990108.7 - ap_isxdigit added + * 19990320 - METHODS and M_INVALID symbol values modified + * 19990320.1 - add ap_vrprintf() + * 19990320.2 - add cmd_parms.context, ap_set_config_vectors, + * export ap_add_file_conf + * 19990320.3 - add ap_regexec() and ap_regerror() + * 19990320.4 - add ap_field_noparam() + * 19990320.5 - add local_ip/host to conn_rec for mass-vhost + * 19990320.6 - add ap_SHA1Final(), ap_SHA1Init(), + * ap_SHA1Update_binary(), ap_SHA1Update(), + * ap_base64encode(), ap_base64encode_binary(), + * ap_base64encode_len(), ap_base64decode(), + * ap_base64decode_binary(), ap_base64decode_len(), + * ap_pbase64decode(), ap_pbase64encode() */ /* @@ -224,9 +247,9 @@ #endif #ifndef MODULE_MAGIC_NUMBER_MAJOR -#define MODULE_MAGIC_NUMBER_MAJOR 19990108 +#define MODULE_MAGIC_NUMBER_MAJOR 19990320 #endif -#define MODULE_MAGIC_NUMBER_MINOR 0 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 6 /* 0...n */ #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR /* backward compat */ /* Useful for testing for features. */ diff --git a/usr.sbin/httpd/src/include/buff.h b/usr.sbin/httpd/src/include/buff.h index e2e00a5f126..229f2c615d4 100644 --- a/usr.sbin/httpd/src/include/buff.h +++ b/usr.sbin/httpd/src/include/buff.h @@ -180,6 +180,10 @@ API_EXPORT(int) ap_vbprintf(BUFF *fb, const char *fmt, va_list vlist); API_EXPORT(int) ap_bflsbuf(int c, BUFF *fb); API_EXPORT(int) ap_bfilbuf(BUFF *fb); +#ifdef EAPI +#define ap_bpeekc(fb) ( ((fb)->incnt == 0) ? EOF : *((fb)->inptr) ) +#endif + #ifndef CHARSET_EBCDIC #define ap_bgetc(fb) ( ((fb)->incnt == 0) ? ap_bfilbuf(fb) : \ diff --git a/usr.sbin/httpd/src/include/hsregex.h b/usr.sbin/httpd/src/include/hsregex.h index e5b24e60f77..1d76e5b41d3 100644 --- a/usr.sbin/httpd/src/include/hsregex.h +++ b/usr.sbin/httpd/src/include/hsregex.h @@ -16,7 +16,7 @@ extern "C" { #endif #endif -#if defined(RHAPSODY) +#if defined(MAC_OS) || defined(MAC_OS_X_SERVER) #define ap_private_extern __private_extern__ #else #define ap_private_extern diff --git a/usr.sbin/httpd/src/include/http_conf_globals.h b/usr.sbin/httpd/src/include/http_conf_globals.h index 53c429421be..7ba0abed370 100644 --- a/usr.sbin/httpd/src/include/http_conf_globals.h +++ b/usr.sbin/httpd/src/include/http_conf_globals.h @@ -67,6 +67,8 @@ extern "C" { */ extern int ap_standalone; +extern int ap_configtestonly; +extern int ap_docrootcheck; extern uid_t ap_user_id; extern char *ap_user_name; extern gid_t ap_group_id; diff --git a/usr.sbin/httpd/src/include/http_config.h b/usr.sbin/httpd/src/include/http_config.h index 21b51ddf8bc..271eff1d7eb 100644 --- a/usr.sbin/httpd/src/include/http_config.h +++ b/usr.sbin/httpd/src/include/http_config.h @@ -170,6 +170,8 @@ typedef struct { */ const command_rec *cmd; /* configuration command */ const char *end_token; /* end token required to end a nested section */ + void *context; /* per_dir_config vector passed + * to handle_command */ } cmd_parms; /* This structure records the existence of handlers in a module... */ @@ -309,17 +311,27 @@ typedef struct module_struct { * ap_read_request(). It is mainly intended to be used to setup/run * connection dependent things like sending start headers for * on-the-fly compression, etc. + * + * close_connection: + * Called from within the Apache dispatching loop just before any + * ap_bclose() is performed on the socket connection, but a long time + * before any pool cleanups are done for the connection (which can be + * too late for some applications). It is mainly intended to be used + * to close/finalize connection dependent things like sending end + * headers for on-the-fly compression, etc. */ #ifdef ULTRIX_BRAIN_DEATH void (*add_module) (); void (*remove_module) (); char *(*rewrite_command) (); void (*new_connection) (); + void (*close_connection) (); #else void (*add_module) (struct module_struct *); void (*remove_module) (struct module_struct *); char *(*rewrite_command) (cmd_parms *, void *config, const char *); void (*new_connection) (conn_rec *); + void (*close_connection) (conn_rec *); #endif #endif /* EAPI */ } module; @@ -393,7 +405,6 @@ extern API_VAR_EXPORT module **ap_loaded_modules; /* For mod_so.c... */ void ap_single_module_configure(pool *p, server_rec *s, module *m); -void ap_single_module_init(pool *p, server_rec *s, module *m); /* For http_main.c... */ @@ -450,6 +461,7 @@ int ap_run_post_read_request(request_rec *); CORE_EXPORT(const command_rec *) ap_find_command(const char *name, const command_rec *cmds); CORE_EXPORT(const command_rec *) ap_find_command_in_modules(const char *cmd_name, module **mod); +CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module *mod); CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l); #endif diff --git a/usr.sbin/httpd/src/include/http_core.h b/usr.sbin/httpd/src/include/http_core.h index 3eeda2e8fde..459fd248f35 100644 --- a/usr.sbin/httpd/src/include/http_core.h +++ b/usr.sbin/httpd/src/include/http_core.h @@ -128,8 +128,8 @@ API_EXPORT(const char *) ap_get_remote_logname(request_rec *r); /* Used for constructing self-referencing URLs, and things like SERVER_PORT, * and SERVER_NAME. */ -API_EXPORT(char *) ap_construct_url(pool *p, const char *uri, const request_rec *r); -API_EXPORT(const char *) ap_get_server_name(const request_rec *r); +API_EXPORT(char *) ap_construct_url(pool *p, const char *uri, request_rec *r); +API_EXPORT(const char *) ap_get_server_name(request_rec *r); API_EXPORT(unsigned) ap_get_server_port(const request_rec *r); API_EXPORT(unsigned long) ap_get_limit_req_body(const request_rec *r); API_EXPORT(void) ap_custom_response(request_rec *r, int status, char *string); @@ -152,6 +152,17 @@ API_EXPORT(const char *) ap_auth_name (request_rec *); API_EXPORT(int) ap_satisfies (request_rec *r); API_EXPORT(const array_header *) ap_requires (request_rec *); +#ifdef WIN32 +/* + * CGI Script stuff for Win32... + */ +typedef enum { eFileTypeUNKNOWN, eFileTypeBIN, eFileTypeEXE16, eFileTypeEXE32, + eFileTypeSCRIPT } file_type_e; +typedef enum { INTERPRETER_SOURCE_UNSET, INTERPRETER_SOURCE_REGISTRY, + INTERPRETER_SOURCE_SHEBANG } interpreter_source_e; +API_EXPORT(file_type_e) ap_get_win32_interpreter(const request_rec *, char **); +#endif + #ifdef CORE_PRIVATE /* @@ -220,7 +231,11 @@ typedef struct { signed int content_md5 : 2; /* calculate Content-MD5? */ - unsigned use_canonical_name : 2; /* bit 0 = on/off, bit 1 = unset/set */ +#define USE_CANONICAL_NAME_OFF (0) +#define USE_CANONICAL_NAME_ON (1) +#define USE_CANONICAL_NAME_DNS (2) +#define USE_CANONICAL_NAME_UNSET (3) + unsigned use_canonical_name : 2; /* since is_fnmatch(conf->d) was being called so frequently in * directory_walk() and its relatives, this field was created and @@ -241,13 +256,19 @@ typedef struct { unsigned long limit_req_body; /* limit on bytes in request msg body */ /* logging options */ - enum { srv_sig_off, srv_sig_on, srv_sig_withmail } server_signature; + enum { srv_sig_unset, srv_sig_off, srv_sig_on, + srv_sig_withmail } server_signature; int loglevel; /* Access control */ array_header *sec; regex_t *r; +#ifdef WIN32 + /* Where to find interpreter to run scripts */ + interpreter_source_e script_interpreter_source; +#endif + } core_dir_config; /* Per-server core configuration */ @@ -277,6 +298,7 @@ void ap_core_reorder_directories(pool *, server_rec *); /* for mod_perl */ CORE_EXPORT(void) ap_add_per_dir_conf (server_rec *s, void *dir_config); CORE_EXPORT(void) ap_add_per_url_conf (server_rec *s, void *url_config); +CORE_EXPORT(void) ap_add_file_conf(core_dir_config *conf, void *url_config); CORE_EXPORT_NONSTD(const char *) ap_limit_section (cmd_parms *cmd, void *dummy, const char *arg); #endif diff --git a/usr.sbin/httpd/src/include/http_protocol.h b/usr.sbin/httpd/src/include/http_protocol.h index bd57fd813c6..3824c1aba06 100644 --- a/usr.sbin/httpd/src/include/http_protocol.h +++ b/usr.sbin/httpd/src/include/http_protocol.h @@ -148,6 +148,7 @@ API_EXPORT(int) ap_rputc(int c, request_rec *r); API_EXPORT(int) ap_rputs(const char *str, request_rec *r); API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r); API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...); +API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list vlist); API_EXPORT_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt,...) __attribute__((format(printf,2,3))); API_EXPORT(int) ap_rflush(request_rec *r); diff --git a/usr.sbin/httpd/src/include/http_request.h b/usr.sbin/httpd/src/include/http_request.h index bc3e938a983..4d83c543d6a 100644 --- a/usr.sbin/httpd/src/include/http_request.h +++ b/usr.sbin/httpd/src/include/http_request.h @@ -86,6 +86,9 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, const request_rec *r); API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, const request_rec *r); +API_EXPORT(request_rec *) ap_sub_req_method_uri(const char *method, + const char *new_file, + const request_rec *r); API_EXPORT(int) ap_run_sub_req(request_rec *r); API_EXPORT(void) ap_destroy_sub_req(request_rec *r); diff --git a/usr.sbin/httpd/src/include/httpd.h b/usr.sbin/httpd/src/include/httpd.h index 581836ec522..fdf93d3c8a2 100644 --- a/usr.sbin/httpd/src/include/httpd.h +++ b/usr.sbin/httpd/src/include/httpd.h @@ -69,6 +69,9 @@ extern "C" { /* Headers in which EVERYONE has an interest... */ #include "ap_config.h" +#ifdef EAPI +#include "ap_mm.h" +#endif #include "alloc.h" /* * Include the Extended API headers. @@ -94,8 +97,10 @@ extern "C" { #elif defined(WIN32) /* Set default for Windows file system */ #define HTTPD_ROOT "/apache" +#elif defined(BEOS) +#define HTTPD_ROOT "/boot/home/apache" #else -#define HTTPD_ROOT "/var/www" +#define HTTPD_ROOT "/usr/local/apache" #endif #endif /* HTTPD_ROOT */ @@ -165,8 +170,7 @@ extern "C" { /* The name of the log files */ #ifndef DEFAULT_XFERLOG -#ifdef OS2 -/* Set default for OS/2 file system */ +#if defined(OS2) || defined(WIN32) #define DEFAULT_XFERLOG "logs/access.log" #else #define DEFAULT_XFERLOG "logs/access_log" @@ -174,8 +178,7 @@ extern "C" { #endif /* DEFAULT_XFERLOG */ #ifndef DEFAULT_ERRORLOG -#ifdef OS2 -/* Set default for OS/2 file system */ +#if defined(OS2) || defined(WIN32) #define DEFAULT_ERRORLOG "logs/error.log" #else #define DEFAULT_ERRORLOG "logs/error_log" @@ -322,8 +325,12 @@ extern "C" { * the overhead. */ #ifndef HARD_SERVER_LIMIT +#ifdef WIN32 +#define HARD_SERVER_LIMIT 1024 +#else #define HARD_SERVER_LIMIT 256 #endif +#endif /* * Special Apache error codes. These are basically used @@ -361,6 +368,19 @@ extern "C" { #define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 #endif +/* + * Unix only: + * Path to Shared Memory Files + */ +#ifdef EAPI +#ifndef EAPI_MM_CORE_PATH +#define EAPI_MM_CORE_PATH "logs/mm" +#endif +#ifndef EAPI_MM_CORE_MAXSIZE +#define EAPI_MM_CORE_MAXSIZE 1024*1024*1 /* max. 1MB */ +#endif +#endif + /* Number of requests to try to handle in a single process. If <= 0, * the children don't die off. That's the default here, since I'm still * interested in finding and stanching leaks. @@ -429,7 +449,7 @@ extern "C" { * Example: "Apache/1.1.0 MrWidget/0.1-alpha" */ -#define SERVER_BASEVERSION "Apache/1.3.4" /* SEE COMMENTS ABOVE */ +#define SERVER_BASEVERSION "Apache/1.3.9" /* SEE COMMENTS ABOVE */ #define SERVER_VERSION SERVER_BASEVERSION enum server_token_type { SrvTk_MIN, /* eg: Apache/1.3.0 */ @@ -448,7 +468,7 @@ API_EXPORT(void) ap_add_config_define(const char *define); * Always increases along the same track as the source branch. * For example, Apache 1.4.2 would be '10402100', 2.5b7 would be '20500007'. */ -#define APACHE_RELEASE 10304100 +#define APACHE_RELEASE 10309100 #define SERVER_PROTOCOL "HTTP/1.1" #ifndef SERVER_SUPPORT @@ -574,9 +594,9 @@ API_EXPORT(void) ap_add_config_define(const char *define); #define M_MOVE 12 #define M_LOCK 13 #define M_UNLOCK 14 +#define M_INVALID 15 -#define METHODS 15 -#define M_INVALID 31 +#define METHODS 16 #define CGI_MAGIC_TYPE "application/x-httpd-cgi" #define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html" @@ -589,6 +609,23 @@ API_EXPORT(void) ap_add_config_define(const char *define); #define DIR_MAGIC_TYPE "httpd/unix-directory" #define STATUS_MAGIC_TYPE "application/x-httpd-status" +/* + * Define the HTML doctype strings centrally. + */ +#define DOCTYPE_HTML_2_0 "<!DOCTYPE HTML PUBLIC \"-//IETF//" \ + "DTD HTML 2.0//EN\">\n" +#define DOCTYPE_HTML_3_2 "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 3.2 Final//EN\">\n" +#define DOCTYPE_HTML_4_0S "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 4.0//EN\"\n" \ + "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +#define DOCTYPE_HTML_4_0T "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 4.0 Transitional//EN\"\n" \ + "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n" +#define DOCTYPE_HTML_4_0F "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 4.0 Frameset//EN\"\n" \ + "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" + /* Just in case your linefeed isn't the one the other end is expecting. */ #ifndef CHARSET_EBCDIC #define LF 10 @@ -680,14 +717,14 @@ struct request_rec { time_t request_time; /* When the request started */ - char *status_line; /* Status line, if set by script */ + const char *status_line; /* Status line, if set by script */ int status; /* In any case */ /* Request method, two ways; also, protocol, etc.. Outside of protocol.c, * look, but don't touch. */ - char *method; /* GET, HEAD, POST, etc. */ + const char *method; /* GET, HEAD, POST, etc. */ int method_number; /* M_GET, M_POST, etc. */ /* @@ -845,7 +882,10 @@ struct conn_rec { signed int double_reverse:2;/* have we done double-reverse DNS? * -1 yes/failure, 0 not yet, 1 yes/success */ int keepalives; /* How many times have we used it? */ - + char *local_ip; /* server IP address */ + char *local_host; /* used for ap_get_server_name when + * UseCanonicalName is set to DNS + * (ignores setting of HostnameLookups) */ #ifdef EAPI ap_ctx *ctx; #endif /* EAPI */ @@ -947,6 +987,7 @@ extern API_VAR_EXPORT const char ap_day_snames[7][4]; API_EXPORT(struct tm *) ap_get_gmtoff(int *tz); API_EXPORT(char *) ap_get_time(void); +API_EXPORT(char *) ap_field_noparam(pool *p, const char *intype); API_EXPORT(char *) ap_ht_time(pool *p, time_t t, const char *fmt, int gmt); API_EXPORT(char *) ap_gm_timestr_822(pool *p, time_t t); @@ -963,6 +1004,10 @@ API_EXPORT(char *) ap_getword_nulls_nc(pool *p, char **line, char stop); API_EXPORT(char *) ap_getword_conf(pool *p, const char **line); API_EXPORT(char *) ap_getword_conf_nc(pool *p, char **line); +API_EXPORT(const char *) ap_size_list_item(const char **field, int *len); +API_EXPORT(char *) ap_get_list_item(pool *p, const char **field); +API_EXPORT(int) ap_find_list_item(pool *p, const char *line, const char *tok); + API_EXPORT(char *) ap_get_token(pool *p, const char **accept_line, int accept_white); API_EXPORT(int) ap_find_token(pool *p, const char *line, const char *tok); API_EXPORT(int) ap_find_last_token(pool *p, const char *line, const char *tok); @@ -989,14 +1034,22 @@ API_EXPORT(char *) ap_make_full_path(pool *a, const char *dir, const char *f); API_EXPORT(int) ap_is_matchexp(const char *str); API_EXPORT(int) ap_strcmp_match(const char *str, const char *exp); API_EXPORT(int) ap_strcasecmp_match(const char *str, const char *exp); -API_EXPORT(char *) ap_uudecode(pool *, const char *); +API_EXPORT(char *) ap_pbase64decode(pool *p, const char *bufcoded); +API_EXPORT(char *) ap_pbase64encode(pool *p, char *string); +API_EXPORT(char *) ap_uudecode(pool *p, const char *bufcoded); API_EXPORT(char *) ap_uuencode(pool *p, char *string); + #ifdef OS2 void os2pathname(char *path); +char *ap_double_quotes(pool *p, char *str); #endif +API_EXPORT(int) ap_regexec(const regex_t *preg, const char *string, + size_t nmatch, regmatch_t pmatch[], int eflags); +API_EXPORT(size_t) ap_regerror(int errcode, const regex_t *preg, + char *errbuf, size_t errbuf_size); API_EXPORT(char *) ap_pregsub(pool *p, const char *input, const char *source, - size_t nmatch, regmatch_t pmatch[]); + size_t nmatch, regmatch_t pmatch[]); API_EXPORT(void) ap_content_type_tolower(char *); API_EXPORT(void) ap_str_tolower(char *); diff --git a/usr.sbin/httpd/src/include/scoreboard.h b/usr.sbin/httpd/src/include/scoreboard.h index 177b3bde4b8..a8f88e3f394 100644 --- a/usr.sbin/httpd/src/include/scoreboard.h +++ b/usr.sbin/httpd/src/include/scoreboard.h @@ -183,6 +183,10 @@ typedef struct { } scoreboard; #define SCOREBOARD_SIZE sizeof(scoreboard) +#ifdef TPF +#define SCOREBOARD_NAME "SCOREBRD" +#define SCOREBOARD_FRAMES SCOREBOARD_SIZE/4095 + 1 +#endif API_EXPORT(void) ap_sync_scoreboard_image(void); API_EXPORT(int) ap_exists_scoreboard_image(void); diff --git a/usr.sbin/httpd/src/include/util_md5.h b/usr.sbin/httpd/src/include/util_md5.h index 3fc35dc7e0f..0a0dc9c9b3c 100644 --- a/usr.sbin/httpd/src/include/util_md5.h +++ b/usr.sbin/httpd/src/include/util_md5.h @@ -67,7 +67,11 @@ extern "C" { API_EXPORT(char *) ap_md5(pool *a, const unsigned char *string); API_EXPORT(char *) ap_md5_binary(pool *a, const unsigned char *buf, int len); API_EXPORT(char *) ap_md5contextTo64(pool *p, AP_MD5_CTX * context); +#ifdef CHARSET_EBCDIC +API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile, int convert); +#else API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile); +#endif /* CHARSET_EBCDIC */ #ifdef __cplusplus } diff --git a/usr.sbin/httpd/src/main/Makefile.tmpl b/usr.sbin/httpd/src/main/Makefile.tmpl index be3400ecacc..0d774c3abb0 100644 --- a/usr.sbin/httpd/src/main/Makefile.tmpl +++ b/usr.sbin/httpd/src/main/Makefile.tmpl @@ -11,7 +11,7 @@ OBJS= alloc.o buff.o \ http_config.o http_core.o http_log.o \ http_main.o http_protocol.o http_request.o http_vhost.o \ util.o util_date.o util_script.o util_uri.o util_md5.o \ - md5c.o rfc1413.o + rfc1413.o .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< @@ -131,9 +131,6 @@ http_vhost.o: http_vhost.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ $(INCDIR)/http_log.h $(INCDIR)/http_vhost.h \ $(INCDIR)/http_protocol.h -md5c.o: md5c.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ - $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(INCDIR)/ap_ctype.h \ - $(INCDIR)/hsregex.h $(INCDIR)/ap_md5.h rfc1413.o: rfc1413.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/alloc.h \ diff --git a/usr.sbin/httpd/src/main/alloc.c b/usr.sbin/httpd/src/main/alloc.c index 550f5f75c46..8086df2a6db 100644 --- a/usr.sbin/httpd/src/main/alloc.c +++ b/usr.sbin/httpd/src/main/alloc.c @@ -63,11 +63,20 @@ */ #include "httpd.h" +#ifdef EAPI +#include "http_config.h" +#include "http_conf_globals.h" +#endif #include "multithread.h" #include "http_log.h" #include <stdarg.h> +#ifdef OS2 +#define INCL_DOS +#include <os2.h> +#endif + /* debugging support, define this to enable code which helps detect re-use * of freed memory and other such nonsense. * @@ -111,6 +120,11 @@ */ /* #define MAKE_TABLE_PROFILE */ +/* Provide some statistics on the cost of allocations. It requires a + * bit of an understanding of how alloc.c works. + */ +/* #define ALLOC_STATS */ + #ifdef POOL_DEBUG #ifdef ALLOC_USE_MALLOC # error "sorry, no support for ALLOC_USE_MALLOC and POOL_DEBUG at the same time" @@ -127,6 +141,10 @@ #define BLOCK_MINALLOC 0 #endif +#if defined(EAPI) && defined(EAPI_MM) +static AP_MM *mm = NULL; +#endif + /***************************************************************** * * Managing free storage blocks... @@ -155,6 +173,9 @@ union block_hdr { char *endp; union block_hdr *next; char *first_avail; +#if defined(EAPI) && defined(EAPI_MM) + int is_shm; +#endif #ifdef POOL_DEBUG union block_hdr *global_next; struct pool *owning_pool; @@ -171,6 +192,13 @@ static int stack_direction; static union block_hdr *global_block_list; #define FREE_POOL ((struct pool *)(-1)) #endif +#ifdef ALLOC_STATS +static unsigned long long num_free_blocks_calls; +static unsigned long long num_blocks_freed; +static unsigned max_blocks_in_one_free; +static unsigned num_malloc_calls; +static unsigned num_malloc_bytes; +#endif #ifdef ALLOC_DEBUG #define FILL_BYTE ((char)(0xa5)) @@ -198,7 +226,11 @@ static ap_inline void debug_verify_filled(const char *ptr, /* Get a completely new block from the system pool. Note that we rely on malloc() to provide aligned memory. */ +#if defined(EAPI) && defined(EAPI_MM) +static union block_hdr *malloc_block(int size, int is_shm) +#else static union block_hdr *malloc_block(int size) +#endif { union block_hdr *blok; @@ -208,12 +240,24 @@ static union block_hdr *malloc_block(int size) */ size += CLICK_SZ; #endif +#ifdef ALLOC_STATS + ++num_malloc_calls; + num_malloc_bytes += size + sizeof(union block_hdr); +#endif +#if defined(EAPI) && defined(EAPI_MM) + if (is_shm) + blok = (union block_hdr *)ap_mm_malloc(mm, size + sizeof(union block_hdr)); + else +#endif blok = (union block_hdr *) malloc(size + sizeof(union block_hdr)); if (blok == NULL) { fprintf(stderr, "Ouch! malloc failed in malloc_block()\n"); exit(1); } debug_fill(blok, size + sizeof(union block_hdr)); +#if defined(EAPI) && defined(EAPI_MM) + blok->h.is_shm = is_shm; +#endif blok->h.next = NULL; blok->h.first_avail = (char *) (blok + 1); blok->h.endp = size + blok->h.first_avail; @@ -261,6 +305,9 @@ static void free_blocks(union block_hdr *blok) free(blok); } #else +#ifdef ALLOC_STATS + unsigned num_blocks; +#endif /* First, put new blocks at the head of the free list --- * we'll eventually bash the 'next' pointer of the last block * in the chain to point to the free blocks we already had. @@ -271,6 +318,10 @@ static void free_blocks(union block_hdr *blok) if (blok == NULL) return; /* Sanity check --- freeing empty pool? */ +#if defined(EAPI) && defined(EAPI_MM) + if (blok->h.is_shm) + (void)ap_mm_lock(mm, AP_MM_LOCK_RW); +#endif (void) ap_acquire_mutex(alloc_mutex); old_free_list = block_freelist; block_freelist = blok; @@ -281,7 +332,13 @@ static void free_blocks(union block_hdr *blok) * now. */ +#ifdef ALLOC_STATS + num_blocks = 1; +#endif while (blok->h.next != NULL) { +#ifdef ALLOC_STATS + ++num_blocks; +#endif chk_on_blk_list(blok, old_free_list); blok->h.first_avail = (char *) (blok + 1); debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail); @@ -301,7 +358,20 @@ static void free_blocks(union block_hdr *blok) /* Finally, reset next pointer to get the old free blocks back */ blok->h.next = old_free_list; + +#ifdef ALLOC_STATS + if (num_blocks > max_blocks_in_one_free) { + max_blocks_in_one_free = num_blocks; + } + ++num_free_blocks_calls; + num_blocks_freed += num_blocks; +#endif + (void) ap_release_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + if (blok->h.is_shm) + (void)ap_mm_unlock(mm); +#endif #endif } @@ -310,7 +380,11 @@ static void free_blocks(union block_hdr *blok) * if necessary. Must be called with alarms blocked. */ +#if defined(EAPI) && defined(EAPI_MM) +static union block_hdr *new_block(int min_size, int is_shm) +#else static union block_hdr *new_block(int min_size) +#endif { union block_hdr **lastptr = &block_freelist; union block_hdr *blok = block_freelist; @@ -320,7 +394,12 @@ static union block_hdr *new_block(int min_size) */ while (blok != NULL) { +#if defined(EAPI) && defined(EAPI_MM) + if (blok->h.is_shm == is_shm && + min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) { +#else if (min_size + BLOCK_MINFREE <= blok->h.endp - blok->h.first_avail) { +#endif *lastptr = blok->h.next; blok->h.next = NULL; debug_verify_filled(blok->h.first_avail, blok->h.endp, @@ -336,7 +415,11 @@ static union block_hdr *new_block(int min_size) /* Nope. */ min_size += BLOCK_MINFREE; +#if defined(EAPI) && defined(EAPI_MM) + blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC, is_shm); +#else blok = malloc_block((min_size > BLOCK_MINALLOC) ? min_size : BLOCK_MINALLOC); +#endif return blok; } @@ -386,6 +469,9 @@ struct pool { #ifdef POOL_DEBUG struct pool *joined; #endif +#if defined(EAPI) && defined(EAPI_MM) + int is_shm; +#endif }; static pool *permanent_pool; @@ -400,16 +486,28 @@ static pool *permanent_pool; #define POOL_HDR_CLICKS (1 + ((sizeof(struct pool) - 1) / CLICK_SZ)) #define POOL_HDR_BYTES (POOL_HDR_CLICKS * CLICK_SZ) +#if defined(EAPI) && defined(EAPI_MM) +static struct pool *make_sub_pool_internal(struct pool *p, int is_shm) +#else API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p) +#endif { union block_hdr *blok; pool *new_pool; ap_block_alarms(); +#if defined(EAPI) && defined(EAPI_MM) + if (is_shm) + (void)ap_mm_lock(mm, AP_MM_LOCK_RW); +#endif (void) ap_acquire_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + blok = new_block(POOL_HDR_BYTES, is_shm); +#else blok = new_block(POOL_HDR_BYTES); +#endif new_pool = (pool *) blok->h.first_avail; blok->h.first_avail += POOL_HDR_BYTES; #ifdef POOL_DEBUG @@ -428,12 +526,38 @@ API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p) p->sub_pools = new_pool; } +#if defined(EAPI) && defined(EAPI_MM) + new_pool->is_shm = is_shm; +#endif + (void) ap_release_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + if (is_shm) + (void)ap_mm_unlock(mm); +#endif ap_unblock_alarms(); return new_pool; } +#if defined(EAPI) +#if defined(EAPI_MM) +API_EXPORT(struct pool *) ap_make_sub_pool(struct pool *p) +{ + return make_sub_pool_internal(p, 0); +} +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p) +{ + return make_sub_pool_internal(p, 1); +} +#else +API_EXPORT(struct pool *) ap_make_shared_sub_pool(struct pool *p) +{ + return NULL; +} +#endif +#endif + #ifdef POOL_DEBUG static void stack_var_init(char *s) { @@ -448,6 +572,27 @@ static void stack_var_init(char *s) } #endif +#if defined(EAPI) +int ap_shared_pool_possible(void) +{ + return ap_mm_useable(); +} +#endif + +#ifdef ALLOC_STATS +static void dump_stats(void) +{ + fprintf(stderr, + "alloc_stats: [%d] #free_blocks %llu #blocks %llu max %u #malloc %u #bytes %u\n", + (int)getpid(), + num_free_blocks_calls, + num_blocks_freed, + max_blocks_in_one_free, + num_malloc_calls, + num_malloc_bytes); +} +#endif + pool *ap_init_alloc(void) { #ifdef POOL_DEBUG @@ -459,18 +604,80 @@ pool *ap_init_alloc(void) alloc_mutex = ap_create_mutex(NULL); spawn_mutex = ap_create_mutex(NULL); permanent_pool = ap_make_sub_pool(NULL); +#ifdef ALLOC_STATS + atexit(dump_stats); +#endif return permanent_pool; } +#if defined(EAPI) +void ap_init_alloc_shared(int early) +{ +#if defined(EAPI_MM) + int mm_size; + char *mm_path; + char *err1, *err2; + + if (early) { + /* process very early on startup */ + mm_size = ap_mm_maxsize(); + if (mm_size > EAPI_MM_CORE_MAXSIZE) + mm_size = EAPI_MM_CORE_MAXSIZE; + mm_path = ap_server_root_relative(permanent_pool, EAPI_MM_CORE_PATH); + if ((mm = ap_mm_create(mm_size, mm_path)) == NULL) { + fprintf(stderr, "Ouch! ap_mm_create(%d, \"%s\") failed\n", mm_size, mm_path); + err1 = ap_mm_error(); + if (err1 == NULL) + err1 = "-unknown-"; + err2 = strerror(errno); + if (err2 == NULL) + err2 = "-unknown-"; + fprintf(stderr, "Error: MM: %s: OS: %s\n", err1, err2); + abort(); + exit(1); + } + } + else { + /* process a lot later on startup */ +#ifdef WIN32 + ap_mm_permission(mm, (_S_IREAD|_S_IWRITE), ap_user_id, -1); +#else + ap_mm_permission(mm, (S_IRUSR|S_IWUSR), ap_user_id, -1); +#endif + } +#endif /* EAPI_MM */ + return; +} + +void ap_kill_alloc_shared(void) +{ +#if defined(EAPI_MM) + if (mm != NULL) { + ap_mm_destroy(mm); + mm = NULL; + } +#endif /* EAPI_MM */ + return; +} +#endif /* EAPI */ + API_EXPORT(void) ap_clear_pool(struct pool *a) { ap_block_alarms(); +#if defined(EAPI) && defined(EAPI_MM) + if (a->is_shm) + (void)ap_mm_lock(mm, AP_MM_LOCK_RW); +#endif (void) ap_acquire_mutex(alloc_mutex); while (a->sub_pools) ap_destroy_pool(a->sub_pools); (void) ap_release_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + if (a->is_shm) + (void)ap_mm_unlock(mm); +#endif /* Don't hold the mutex during cleanups. */ run_cleanups(a->cleanups); a->cleanups = NULL; @@ -504,6 +711,10 @@ API_EXPORT(void) ap_destroy_pool(pool *a) ap_block_alarms(); ap_clear_pool(a); +#if defined(EAPI) && defined(EAPI_MM) + if (a->is_shm) + (void)ap_mm_lock(mm, AP_MM_LOCK_RW); +#endif (void) ap_acquire_mutex(alloc_mutex); if (a->parent) { if (a->parent->sub_pools == a) @@ -514,6 +725,10 @@ API_EXPORT(void) ap_destroy_pool(pool *a) a->sub_next->sub_prev = a->sub_prev; } (void) ap_release_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + if (a->is_shm) + (void)ap_mm_unlock(mm); +#endif free_blocks(a->first); ap_unblock_alarms(); @@ -528,6 +743,30 @@ API_EXPORT(long) ap_bytes_in_free_blocks(void) return bytes_in_block_list(block_freelist); } +#if defined(EAPI) +API_EXPORT(int) ap_acquire_pool(pool *p, ap_pool_lock_mode mode) +{ +#if defined(EAPI_MM) + if (!p->is_shm) + return 1; + return ap_mm_lock(mm, mode == AP_POOL_RD ? AP_MM_LOCK_RD : AP_MM_LOCK_RW); +#else + return 1; +#endif +} + +API_EXPORT(int) ap_release_pool(pool *p) +{ +#if defined(EAPI_MM) + if (!p->is_shm) + return 1; + return ap_mm_unlock(mm); +#else + return 1; +#endif +} +#endif /* EAPI */ + /***************************************************************** * POOL_DEBUG support */ @@ -693,16 +932,31 @@ API_EXPORT(void *) ap_palloc(struct pool *a, int reqsize) ap_block_alarms(); +#if defined(EAPI) && defined(EAPI_MM) + if (a->is_shm) + (void)ap_mm_lock(mm, AP_MM_LOCK_RW); +#endif (void) ap_acquire_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + blok = new_block(size, a->is_shm); +#else blok = new_block(size); +#endif a->last->h.next = blok; a->last = blok; #ifdef POOL_DEBUG blok->h.owning_pool = a; #endif +#if defined(EAPI) && defined(EAPI_MM) + blok->h.is_shm = a->is_shm; +#endif (void) ap_release_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + if (a->is_shm) + (void)ap_mm_unlock(mm); +#endif ap_unblock_alarms(); @@ -814,6 +1068,11 @@ static int psprintf_flush(ap_vformatter_buff *vbuff) char *ptr; size = (char *)ps->vbuff.curpos - ps->base; +#if defined(EAPI) && defined(EAPI_MM) + if (ps->block->h.is_shm) + ptr = ap_mm_realloc(ps->base, 2*size); + else +#endif ptr = realloc(ps->base, 2*size); if (ptr == NULL) { fputs("Ouch! Out of memory!\n", stderr); @@ -834,9 +1093,21 @@ static int psprintf_flush(ap_vformatter_buff *vbuff) cur_len = strp - blok->h.first_avail; /* must try another blok */ +#if defined(EAPI) && defined(EAPI_MM) + if (blok->h.is_shm) + (void)ap_mm_lock(mm, AP_MM_LOCK_RW); +#endif (void) ap_acquire_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + nblok = new_block(2 * cur_len, blok->h.is_shm); +#else nblok = new_block(2 * cur_len); +#endif (void) ap_release_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + if (blok->h.is_shm) + (void)ap_mm_unlock(mm); +#endif memcpy(nblok->h.first_avail, blok->h.first_avail, cur_len); ps->vbuff.curpos = nblok->h.first_avail + cur_len; /* save a byte for the NUL terminator */ @@ -845,10 +1116,18 @@ static int psprintf_flush(ap_vformatter_buff *vbuff) /* did we allocate the current blok? if so free it up */ if (ps->got_a_new_block) { debug_fill(blok->h.first_avail, blok->h.endp - blok->h.first_avail); +#if defined(EAPI) && defined(EAPI_MM) + if (blok->h.is_shm) + (void)ap_mm_lock(mm, AP_MM_LOCK_RW); +#endif (void) ap_acquire_mutex(alloc_mutex); blok->h.next = block_freelist; block_freelist = blok; (void) ap_release_mutex(alloc_mutex); +#if defined(EAPI) && defined(EAPI_MM) + if (blok->h.is_shm) + (void)ap_mm_unlock(mm); +#endif } ps->blok = nblok; ps->got_a_new_block = 1; @@ -867,6 +1146,11 @@ API_EXPORT(char *) ap_pvsprintf(pool *p, const char *fmt, va_list ap) void *ptr; ap_block_alarms(); +#if defined(EAPI) && defined(EAPI_MM) + if (p->is_shm) + ps.base = ap_mm_malloc(mm, 512); + else +#endif ps.base = malloc(512); if (ps.base == NULL) { fputs("Ouch! Out of memory!\n", stderr); @@ -879,6 +1163,11 @@ API_EXPORT(char *) ap_pvsprintf(pool *p, const char *fmt, va_list ap) *ps.vbuff.curpos++ = '\0'; ptr = ps.base; /* shrink */ +#if defined(EAPI) && defined(EAPI_MM) + if (p->is_shm) + ptr = ap_mm_realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr); + else +#endif ptr = realloc(ptr, (char *)ps.vbuff.curpos - (char *)ptr); if (ptr == NULL) { fputs("Ouch! Out of memory!\n", stderr); @@ -1671,9 +1960,9 @@ static void cleanup_pool_for_exec(pool *p) API_EXPORT(void) ap_cleanup_for_exec(void) { -#ifndef WIN32 +#if !defined(WIN32) && !defined(OS2) /* - * Don't need to do anything on NT, because I + * Don't need to do anything on NT or OS/2, because I * am actually going to spawn the new process - not * exec it. All handles that are not inheritable, will * be automajically closed. The only problem is with @@ -1998,8 +2287,8 @@ struct process_chain { struct process_chain *next; }; -API_EXPORT(void) ap_note_subprocess(pool *a, int pid, enum kill_conditions how) -{ +API_EXPORT(void) ap_note_subprocess(pool *a, pid_t pid, enum kill_conditions +how) { struct process_chain *new = (struct process_chain *) ap_palloc(a, sizeof(struct process_chain)); @@ -2022,11 +2311,11 @@ API_EXPORT(void) ap_note_subprocess(pool *a, int pid, enum kill_conditions how) #define BINMODE #endif -static int spawn_child_core(pool *p, int (*func) (void *, child_info *), +static pid_t spawn_child_core(pool *p, int (*func) (void *, child_info *), void *data,enum kill_conditions kill_how, int *pipe_in, int *pipe_out, int *pipe_err) { - int pid; + pid_t pid; int in_fds[2]; int out_fds[2]; int err_fds[2]; @@ -2141,6 +2430,60 @@ static int spawn_child_core(pool *p, int (*func) (void *, child_info *), */ } +#elif defined(OS2) + { + int save_in=-1, save_out=-1, save_err=-1; + + if (pipe_out) { + save_out = dup(STDOUT_FILENO); + dup2(out_fds[1], STDOUT_FILENO); + close(out_fds[1]); + DosSetFHState(out_fds[0], OPEN_FLAGS_NOINHERIT); + } + + if (pipe_in) { + save_in = dup(STDIN_FILENO); + dup2(in_fds[0], STDIN_FILENO); + close(in_fds[0]); + DosSetFHState(in_fds[1], OPEN_FLAGS_NOINHERIT); + } + + if (pipe_err) { + save_err = dup(STDERR_FILENO); + dup2(err_fds[1], STDERR_FILENO); + close(err_fds[1]); + DosSetFHState(err_fds[0], OPEN_FLAGS_NOINHERIT); + } + + pid = func(data, NULL); + + if ( pid ) + ap_note_subprocess(p, pid, kill_how); + + if (pipe_out) { + close(STDOUT_FILENO); + dup2(save_out, STDOUT_FILENO); + close(save_out); + *pipe_out = out_fds[0]; + } + + if (pipe_in) { + close(STDIN_FILENO); + dup2(save_in, STDIN_FILENO); + close(save_in); + *pipe_in = in_fds[1]; + } + + if (pipe_err) { + close(STDERR_FILENO); + dup2(save_err, STDERR_FILENO); + close(save_err); + *pipe_err = err_fds[0]; + } + } +#elif defined(TPF) + return (pid = ap_tpf_spawn_child(p, func, data, kill_how, + pipe_in, pipe_out, pipe_err, out_fds, in_fds, err_fds)); #else if ((pid = fork()) < 0) { @@ -2220,7 +2563,8 @@ API_EXPORT(int) ap_spawn_child(pool *p, int (*func) (void *, child_info *), FILE **pipe_err) { int fd_in, fd_out, fd_err; - int pid, save_errno; + pid_t pid; + int save_errno; ap_block_alarms(); @@ -2280,7 +2624,7 @@ API_EXPORT(int) ap_bspawn_child(pool *p, int (*func) (void *, child_info *), voi HANDLE hPipeOutputReadDup = NULL; HANDLE hPipeErrorReadDup = NULL; HANDLE hCurrentProcess; - int pid = 0; + pid_t pid = 0; child_info info; @@ -2452,7 +2796,8 @@ API_EXPORT(int) ap_bspawn_child(pool *p, int (*func) (void *, child_info *), voi #else int fd_in, fd_out, fd_err; - int pid, save_errno; + pid_t pid; + int save_errno; ap_block_alarms(); @@ -2560,7 +2905,7 @@ static void free_proc_chain(struct process_chain *procs) if ((p->kill_how == kill_after_timeout) || (p->kill_how == kill_only_once)) { /* Subprocess may be dead already. Only need the timeout if not. */ - if (kill(p->pid, SIGTERM) != -1) + if (ap_os_kill(p->pid, SIGTERM) != -1) need_timeout = 1; } else if (p->kill_how == kill_always) { diff --git a/usr.sbin/httpd/src/main/buff.c b/usr.sbin/httpd/src/main/buff.c index 85006a92478..33555a75763 100644 --- a/usr.sbin/httpd/src/main/buff.c +++ b/usr.sbin/httpd/src/main/buff.c @@ -272,11 +272,16 @@ static ap_inline int buff_read(BUFF *fb, void *buf, int nbyte) } else rv = ap_read(fb, buf, nbyte); +#elif defined (BEOS) + if (fb->flags & B_SOCKET) { + rv = recv(fb->fd_in, buf, nbyte, 0); + } else + rv = ap_read(fb,buf,nbyte); #elif defined(TPF) fd_set fds; struct timeval tv; - tpf_process_signals(); + ap_check_signals(); if (fb->flags & B_SOCKET) { alarm(rv = alarm(0)); FD_ZERO(&fds); @@ -284,11 +289,10 @@ static ap_inline int buff_read(BUFF *fb, void *buf, int nbyte) tv.tv_sec = rv+1; tv.tv_usec = 0; rv = ap_select(fb->fd_in + 1, &fds, NULL, NULL, &tv); - if (rv < 1) { - tpf_process_signals(); - return(rv); - } + if (rv > 0) + rv = ap_read(fb, buf, nbyte); } + else rv = ap_read(fb, buf, nbyte); #else rv = ap_read(fb, buf, nbyte); @@ -335,6 +339,11 @@ static ap_inline int buff_write(BUFF *fb, const void *buf, int nbyte) } else rv = ap_write(fb, buf, nbyte); +#elif defined(BEOS) + if(fb->flags & B_SOCKET) { + rv = send(fb->fd, buf, nbyte, 0); + } else + rv = ap_write(fb, buf,nbyte); #else rv = ap_write(fb, buf, nbyte); #endif /* WIN32 */ @@ -705,6 +714,7 @@ static int read_with_errors(BUFF *fb, void *buf, int nbyte) return rv; } + /* * Read up to nbyte bytes into buf. * If fewer than byte bytes are currently available, then return those. @@ -1259,8 +1269,10 @@ API_EXPORT(int) ap_bwrite(BUFF *fb, const void *buf, int nbyte) if (cbuf != NULL) free(cbuf); cbuf = malloc(csize = nbyte+HUGE_STRING_LEN); - if (cbuf == NULL) + if (cbuf == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_bwrite()!\n"); csize = 0; + } } ebcdic2ascii((cbuf) ? cbuf : (void*)buf, buf, nbyte); buf = (cbuf) ? cbuf : buf; @@ -1461,6 +1473,16 @@ API_EXPORT(int) ap_bclose(BUFF *fb) rc3 = 0; } else { +#elif defined(BEOS) + if (fb->flags & B_SOCKET) { + rc2 = ap_pclosesocket(fb->pool, fb->fd); + if (fb->fd_in != fb->fd) { + rc3 = ap_pclosesocket(fb->pool, fb->fd_in); + } + else { + rc3 = 0; + } + } else { #endif rc2 = ap_pclosef(fb->pool, fb->fd); if (fb->fd_in != fb->fd) { @@ -1469,7 +1491,7 @@ API_EXPORT(int) ap_bclose(BUFF *fb) else { rc3 = 0; } -#ifdef WIN32 +#if defined(WIN32) || defined (BEOS) } #endif diff --git a/usr.sbin/httpd/src/main/http_config.c b/usr.sbin/httpd/src/main/http_config.c index 2159c448550..8525b841103 100644 --- a/usr.sbin/httpd/src/main/http_config.c +++ b/usr.sbin/httpd/src/main/http_config.c @@ -99,7 +99,7 @@ static int total_modules = 0; */ static int dynamic_modules = 0; API_VAR_EXPORT module *top_module = NULL; -API_VAR_EXPORT module **ap_loaded_modules; +API_VAR_EXPORT module **ap_loaded_modules=NULL; typedef int (*handler_func) (request_rec *); typedef void *(*dir_maker_func) (pool *, char *); @@ -327,6 +327,9 @@ static void build_method_shortcuts(void) } } method_ptrs = malloc((how_many_ptrs + NMETHODS) * sizeof(handler_func)); + if (method_ptrs == NULL) { + fprintf(stderr, "Ouch! Out of memory in build_method_shortcuts()!\n"); + } next_ptr = 0; for (i = 0; i < NMETHODS; ++i) { /* XXX: This is an itsy bit presumptuous about the alignment @@ -651,6 +654,7 @@ API_EXPORT(void) ap_remove_module(module *m) m->module_index = -1; /* simulate being unloaded, should * be unnecessary */ dynamic_modules--; + total_modules--; } API_EXPORT(void) ap_add_loaded_module(module *mod) @@ -722,6 +726,9 @@ void ap_setup_prelinked_modules() */ ap_loaded_modules = (module **)malloc( sizeof(module *)*(total_modules+DYNAMIC_MODULE_LIMIT+1)); + if (ap_loaded_modules == NULL) { + fprintf(stderr, "Ouch! Out of memory in ap_setup_prelinked_modules()!\n"); + } for (m = ap_preloaded_modules, m2 = ap_loaded_modules; *m != NULL; ) *m2++ = *m++; *m2 = NULL; @@ -983,8 +990,26 @@ CORE_EXPORT(const command_rec *) ap_find_command_in_modules(const char *cmd_name return NULL; } +CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module *mod) +{ + void *mconfig = ap_get_module_config(config, mod); + void *sconfig = ap_get_module_config(parms->server->module_config, mod); + + if (!mconfig && mod->create_dir_config) { + mconfig = (*mod->create_dir_config) (parms->pool, parms->path); + ap_set_module_config(config, mod, mconfig); + } + + if (!sconfig && mod->create_server_config) { + sconfig = (*mod->create_server_config) (parms->pool, parms->server); + ap_set_module_config(parms->server->module_config, mod, sconfig); + } + return mconfig; +} + CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l) { + void *oldconfig; const char *args, *cmd_name, *retval; const command_rec *cmd; module *mod = top_module; @@ -1018,6 +1043,8 @@ CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, cons if (*cmd_name == '\0') return NULL; + oldconfig = parms->context; + parms->context = config; do { if (!(cmd = ap_find_command_in_modules(cmd_name, &mod))) { errno = EINVAL; @@ -1026,25 +1053,13 @@ CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, cons "not included in the server configuration", NULL); } else { - void *mconfig = ap_get_module_config(config, mod); - void *sconfig = - ap_get_module_config(parms->server->module_config, mod); - - if (!mconfig && mod->create_dir_config) { - mconfig = (*mod->create_dir_config) (parms->pool, parms->path); - ap_set_module_config(config, mod, mconfig); - } - - if (!sconfig && mod->create_server_config) { - sconfig = - (*mod->create_server_config) (parms->pool, parms->server); - ap_set_module_config(parms->server->module_config, mod, sconfig); - } + void *mconfig = ap_set_config_vectors(parms,config, mod); retval = invoke_cmd(cmd, parms, mconfig, args); mod = mod->next; /* Next time around, skip this one */ } } while (retval && !strcmp(retval, DECLINE_CMD)); + parms->context = oldconfig; return retval; } @@ -1119,7 +1134,7 @@ API_EXPORT_NONSTD(const char *) ap_set_file_slot(cmd_parms *cmd, char *struct_pt */ static cmd_parms default_parms = -{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL}; +{NULL, 0, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; API_EXPORT(char *) ap_server_root_relative(pool *p, char *file) { @@ -1544,14 +1559,6 @@ void ap_single_module_configure(pool *p, server_rec *s, module *m) (*m->create_dir_config)(p, NULL)); } -void ap_single_module_init(pool *p, server_rec *s, module *m) -{ - if (m->init) - (*m->init)(s, p); - build_method_shortcuts(); - init_handlers(p); -} - void ap_init_modules(pool *p, server_rec *s) { module *m; diff --git a/usr.sbin/httpd/src/main/http_core.c b/usr.sbin/httpd/src/main/http_core.c index 979f475122a..e02d32ec5f4 100644 --- a/usr.sbin/httpd/src/main/http_core.c +++ b/usr.sbin/httpd/src/main/http_core.c @@ -90,6 +90,9 @@ #endif #endif #endif +#ifndef MMAP_LIMIT +#define MMAP_LIMIT (4*1024*1024) +#endif /* Server core module... This module provides support for really basic * server operations, including options and commands which control the @@ -127,7 +130,7 @@ static void *create_core_dir_config(pool *a, char *dir) conf->content_md5 = 2; - conf->use_canonical_name = 1 | 2; /* 2 = unset, default on */ + conf->use_canonical_name = USE_CANONICAL_NAME_UNSET; conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET; conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */ @@ -145,6 +148,11 @@ static void *create_core_dir_config(pool *a, char *dir) conf->limit_req_body = 0; conf->sec = ap_make_array(a, 2, sizeof(void *)); +#ifdef WIN32 + conf->script_interpreter_source = INTERPRETER_SOURCE_UNSET; +#endif + + conf->server_signature = srv_sig_unset; return (void *)conf; } @@ -234,7 +242,7 @@ static void *merge_core_dir_configs(pool *a, void *basev, void *newv) if ((new->content_md5 & 2) == 0) { conf->content_md5 = new->content_md5; } - if ((new->use_canonical_name & 2) == 0) { + if (new->use_canonical_name != USE_CANONICAL_NAME_UNSET) { conf->use_canonical_name = new->use_canonical_name; } @@ -262,6 +270,17 @@ static void *merge_core_dir_configs(pool *a, void *basev, void *newv) if (new->satisfy != SATISFY_NOSPEC) { conf->satisfy = new->satisfy; } + +#ifdef WIN32 + if (new->script_interpreter_source != INTERPRETER_SOURCE_UNSET) { + conf->script_interpreter_source = new->script_interpreter_source; + } +#endif + + if (new->server_signature != srv_sig_unset) { + conf->server_signature = new->server_signature; + } + return (void*)conf; } @@ -324,7 +343,7 @@ CORE_EXPORT(void) ap_add_per_url_conf(server_rec *s, void *url_config) *new_space = url_config; } -static void add_file_conf(core_dir_config *conf, void *url_config) +CORE_EXPORT(void) ap_add_file_conf(core_dir_config *conf, void *url_config) { void **new_space = (void **)ap_push_array(conf->sec); @@ -339,7 +358,7 @@ static void add_file_conf(core_dir_config *conf, void *url_config) * See directory_walk(). */ -#if defined(OS2) || defined(WIN32) +#ifdef HAVE_DRIVE_LETTERS #define IS_SPECIAL(entry_core) \ ((entry_core)->r != NULL \ || ((entry_core)->d[0] != '/' && (entry_core)->d[1] != ':')) @@ -398,18 +417,16 @@ void ap_core_reorder_directories(pool *p, server_rec *s) int nelts; void **elts; int i; + pool *tmp; - /* XXX: we are about to waste some ram ... we will build a new array - * and we need some scratch space to do it. The old array and the - * scratch space are never freed. - */ sconf = ap_get_module_config(s->module_config, &core_module); sec = sconf->sec; nelts = sec->nelts; elts = (void **)sec->elts; - /* build our sorting space */ - sortbin = ap_palloc(p, sec->nelts * sizeof(*sortbin)); + /* we have to allocate tmp space to do a stable sort */ + tmp = ap_make_sub_pool(p); + sortbin = ap_palloc(tmp, sec->nelts * sizeof(*sortbin)); for (i = 0; i < nelts; ++i) { sortbin[i].orig_index = i; sortbin[i].elt = elts[i]; @@ -417,15 +434,12 @@ void ap_core_reorder_directories(pool *p, server_rec *s) qsort(sortbin, nelts, sizeof(*sortbin), reorder_sorter); - /* and now build a new array */ - /* XXX: uh I don't see why we can't reuse the old array, what - * was I thinking? -djg */ - sec = ap_make_array(p, nelts, sizeof(void *)); + /* and now copy back to the original array */ for (i = 0; i < nelts; ++i) { - *(void **)ap_push_array(sec) = sortbin[i].elt; + elts[i] = sortbin[i].elt; } - sconf->sec = sec; + ap_destroy_pool(tmp); } /***************************************************************** @@ -658,17 +672,50 @@ API_EXPORT(const char *) ap_get_remote_logname(request_rec *r) * name" as supplied by a possible Host: header or full URI. We never * trust the port passed in the client's headers, we always use the * port of the actual socket. + * + * The DNS option to UseCanonicalName causes this routine to do a + * reverse lookup on the local IP address of the connectiona and use + * that for the ServerName. This makes its value more reliable while + * at the same time allowing Demon's magic virtual hosting to work. + * The assumption is that DNS lookups are sufficiently quick... + * -- fanf 1998-10-03 */ -API_EXPORT(const char *) ap_get_server_name(const request_rec *r) +API_EXPORT(const char *) ap_get_server_name(request_rec *r) { + conn_rec *conn = r->connection; core_dir_config *d; d = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - if (d->use_canonical_name & 1) { - return r->server->server_hostname; + + if (d->use_canonical_name == USE_CANONICAL_NAME_OFF) { + return r->hostname ? r->hostname : r->server->server_hostname; + } + if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) { + if (conn->local_host == NULL) { + struct in_addr *iaddr; + struct hostent *hptr; + int old_stat; + old_stat = ap_update_child_status(conn->child_num, + SERVER_BUSY_DNS, r); + iaddr = &(conn->local_addr.sin_addr); + hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), + AF_INET); + if (hptr != NULL) { + conn->local_host = ap_pstrdup(conn->pool, + (void *)hptr->h_name); + ap_str_tolower(conn->local_host); + } + else { + conn->local_host = ap_pstrdup(conn->pool, + r->server->server_hostname); + } + (void) ap_update_child_status(conn->child_num, old_stat, r); + } + return conn->local_host; } - return r->hostname ? r->hostname : r->server->server_hostname; + /* default */ + return r->server->server_hostname; } API_EXPORT(unsigned) ap_get_server_port(const request_rec *r) @@ -679,38 +726,21 @@ API_EXPORT(unsigned) ap_get_server_port(const request_rec *r) port = r->server->port ? r->server->port : ap_default_port(r); - if (d->use_canonical_name & 1) { - return port; + if (d->use_canonical_name == USE_CANONICAL_NAME_OFF + || d->use_canonical_name == USE_CANONICAL_NAME_DNS) { + return r->hostname ? ntohs(r->connection->local_addr.sin_port) + : port; } - return r->hostname ? ntohs(r->connection->local_addr.sin_port) - : port; + /* default */ + return port; } API_EXPORT(char *) ap_construct_url(pool *p, const char *uri, - const request_rec *r) + request_rec *r) { - unsigned port; - const char *host; - core_dir_config *d = - (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - - if (d->use_canonical_name & 1) { - port = r->server->port ? r->server->port : ap_default_port(r); - host = r->server->server_hostname; - } - else { - if (r->hostname) { - port = ntohs(r->connection->local_addr.sin_port); - } - else if (r->server->port) { - port = r->server->port; - } - else { - port = ap_default_port(r); - } + unsigned port = ap_get_server_port(r); + const char *host = ap_get_server_name(r); - host = r->hostname ? r->hostname : r->server->server_hostname; - } if (ap_is_default_port(port, r)) { return ap_pstrcat(p, ap_http_method(r), "://", host, uri, NULL); } @@ -725,6 +755,196 @@ API_EXPORT(unsigned long) ap_get_limit_req_body(const request_rec *r) return d->limit_req_body; } +#ifdef WIN32 +static char* get_interpreter_from_win32_registry(pool *p, const char* ext) +{ + char extension_path[] = "SOFTWARE\\Classes\\"; + char executable_path[] = "\\SHELL\\OPEN\\COMMAND"; + + HKEY hkeyOpen; + DWORD type; + int size; + int result; + char *keyName; + char *buffer; + char *s; + + if (!ext) + return NULL; + /* + * Future optimization: + * When the registry is successfully searched, store the interpreter + * string in a table to make subsequent look-ups faster + */ + + /* Open the key associated with the script extension */ + keyName = ap_pstrcat(p, extension_path, ext, NULL); + + result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, + &hkeyOpen); + + if (result != ERROR_SUCCESS) + return NULL; + + /* Read to NULL buffer to find value size */ + size = 0; + result = RegQueryValueEx(hkeyOpen, "", NULL, &type, NULL, &size); + + if (result == ERROR_SUCCESS) { + buffer = ap_palloc(p, size); + result = RegQueryValueEx(hkeyOpen, "", NULL, &type, buffer, &size); + } + + RegCloseKey(hkeyOpen); + + if (result != ERROR_SUCCESS) + return NULL; + + /* Open the key associated with the interpreter path */ + keyName = ap_pstrcat(p, extension_path, buffer, executable_path, NULL); + + result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, + &hkeyOpen); + + if (result != ERROR_SUCCESS) + return NULL; + + /* Read to NULL buffer to find value size */ + size = 0; + result = RegQueryValueEx(hkeyOpen, "", 0, &type, NULL, &size); + + if (result == ERROR_SUCCESS) { + buffer = ap_palloc(p, size); + result = RegQueryValueEx(hkeyOpen, "", 0, &type, buffer, &size); + } + + RegCloseKey(hkeyOpen); + + if (result != ERROR_SUCCESS) + return NULL; + + /* + * The canonical way shell command entries are entered in the Win32 + * registry is as follows: + * shell [options] "%1" + * where + * shell - full path name to interpreter or shell to run. + * E.g., c:\usr\local\ntreskit\perl\bin\perl.exe + * options - optional switches + * E.g., \C + * "%1" - Place holder for file to run the shell against. + * Typically quoted. + * + * If we find a %1 or a quoted %1, lop it off. + */ + if (buffer && *buffer) { + if ((s = strstr(buffer, "\"%1"))) + *s = '\0'; + else if ((s = strstr(buffer, "%1"))) + *s = '\0'; + } + + return buffer; +} + +API_EXPORT (file_type_e) ap_get_win32_interpreter(const request_rec *r, + char** interpreter ) +{ + HANDLE hFile; + DWORD nBytesRead; + BOOLEAN bResult; + char buffer[1024]; + core_dir_config *d; + int i; + file_type_e fileType = eFileTypeUNKNOWN; + char *ext = NULL; + char *exename = NULL; + + d = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + /* Find the file extension */ + exename = strrchr(r->filename, '/'); + if (!exename) { + exename = strrchr(r->filename, '\\'); + } + if (!exename) { + exename = r->filename; + } + else { + exename++; + } + ext = strrchr(exename, '.'); + + if (ext && (!strcasecmp(ext,".bat") || !strcasecmp(ext,".cmd"))) { + return eFileTypeEXE32; + } + + /* If the file has an extension and it is not .com and not .exe and + * we've been instructed to search the registry, then do it! + */ + if (ext && strcasecmp(ext,".exe") && strcasecmp(ext,".com") && + d->script_interpreter_source == INTERPRETER_SOURCE_REGISTRY) { + /* Check the registry */ + *interpreter = get_interpreter_from_win32_registry(r->pool, ext); + if (*interpreter) + return eFileTypeSCRIPT; + else { + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r->server, + "ScriptInterpreterSource config directive set to \"registry\".\n\t" + "Registry was searched but interpreter not found. Trying the shebang line."); + } + } + + /* Need to peek into the file figure out what it really is... */ + hFile = CreateFile(r->filename, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) { + return eFileTypeUNKNOWN; + } + bResult = ReadFile(hFile, (void*) &buffer, sizeof(buffer) - 1, + &nBytesRead, NULL); + if (!bResult || (nBytesRead == 0)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, + "ReadFile(%s) failed", r->filename); + CloseHandle(hFile); + return eFileTypeUNKNOWN; + } + CloseHandle(hFile); + buffer[nBytesRead] = '\0'; + + /* Script or executable, that is the question... */ + if ((buffer[0] == '#') && (buffer[1] == '!')) { + /* Assuming file is a script since it starts with a shebang */ + fileType = eFileTypeSCRIPT; + for (i = 2; i < sizeof(buffer); i++) { + if ((buffer[i] == '\r') + || (buffer[i] == '\n')) { + break; + } + } + buffer[i] = '\0'; + for (i = 2; buffer[i] == ' ' ; ++i) + ; + *interpreter = ap_pstrdup(r->pool, buffer + i ); + } + else { + /* Not a script, is it an executable? */ + IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer; + if ((nBytesRead >= sizeof(IMAGE_DOS_HEADER)) && (hdr->e_magic == IMAGE_DOS_SIGNATURE)) { + if (hdr->e_lfarlc < 0x40) + fileType = eFileTypeEXE16; + else + fileType = eFileTypeEXE32; + } + else + fileType = eFileTypeUNKNOWN; + } + + return fileType; +} +#endif + /***************************************************************** * * Commands... this module handles almost all of the NCSA httpd.conf @@ -827,7 +1047,7 @@ static const char *set_document_root(cmd_parms *cmd, void *dummy, char *arg) } arg = ap_os_canonical_filename(cmd->pool, arg); - if (!ap_is_directory(arg)) { + if (ap_configtestonly && ap_docrootcheck && !ap_is_directory(arg)) { if (cmd->server->is_virtual) { fprintf(stderr, "Warning: DocumentRoot [%s] does not exist\n", arg); @@ -893,7 +1113,7 @@ static const char *set_error_document(cmd_parms *cmd, core_dir_config *conf, if (error_number == 401 && line[0] != '/' && line[0] != '"') { /* Ignore it... */ - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, NULL, + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, cmd->server, "cannot use a full URL in a 401 ErrorDocument " "directive --- ignoring!"); } @@ -1064,6 +1284,7 @@ CORE_EXPORT_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, const char *arg) { const char *limited_methods = ap_getword(cmd->pool, &arg, '>'); + void *tog = cmd->cmd->cmd_data; int limited = 0; const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); @@ -1072,7 +1293,7 @@ CORE_EXPORT_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, } /* XXX: NB: Currently, we have no way of checking - * whether <Limit> sections are closed properly. + * whether <Limit> or <LimitExcept> sections are closed properly. * (If we would add a srm_command_loop() here we might...) */ @@ -1080,26 +1301,31 @@ CORE_EXPORT_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, void *dummy, char *method = ap_getword_conf(cmd->pool, &limited_methods); int methnum = ap_method_number_of(method); - if (methnum == M_TRACE) { + if (methnum == M_TRACE && !tog) { return "TRACE cannot be controlled by <Limit>"; } else if (methnum == M_INVALID) { - return ap_pstrcat(cmd->pool, "unknown method \"", - method, "\" in <Limit>", NULL); + return ap_pstrcat(cmd->pool, "unknown method \"", method, + "\" in <Limit", tog ? "Except>" : ">", NULL); } else { limited |= (1 << methnum); } } - cmd->limited = limited; + /* Killing two features with one function, + * if (tog == NULL) <Limit>, else <LimitExcept> + */ + cmd->limited = tog ? ~limited : limited; return NULL; } static const char *endlimit_section(cmd_parms *cmd, void *dummy, void *dummy2) { + void *tog = cmd->cmd->cmd_data; + if (cmd->limited == -1) { - return "</Limit> unexpected"; + return tog ? "</LimitExcept> unexpected" : "</Limit> unexpected"; } cmd->limited = -1; @@ -1183,10 +1409,6 @@ static const char *dirsection(cmd_parms *cmd, void *dummy, const char *arg) *endp = '\0'; cmd->path = ap_getword_conf(cmd->pool, &arg); -#ifdef OS2 - /* Fix OS/2 HPFS filename case problem. */ - cmd->path = strlwr(cmd->path); -#endif cmd->override = OR_ALL|ACCESS_CONF; if (thiscmd->cmd_data) { /* <DirectoryMatch> */ @@ -1360,7 +1582,7 @@ static const char *filesection(cmd_parms *cmd, core_dir_config *c, conf->d_is_fnmatch = ap_is_fnmatch(conf->d) != 0; conf->r = r; - add_file_conf(c, new_file_conf); + ap_add_file_conf(c, new_file_conf); if (*arg != '\0') { return ap_pstrcat(cmd->pool, "Multiple ", thiscmd->name, @@ -1719,7 +1941,7 @@ static const char *set_user(cmd_parms *cmd, void *dummy, char *arg) "Error:\tApache has not been designed to serve pages while\n" "\trunning as root. There are known race conditions that\n" "\twill allow any local user to read any file on the system.\n" - "\tShould you still desire to serve pages as root then\n" + "\tIf you still desire to serve pages as root then\n" "\tadd -DBIG_SECURITY_HOLE to the EXTRA_CFLAGS line in your\n" "\tsrc/Configuration file and rebuild the server. It is\n" "\tstrongly suggested that you instead modify the User\n" @@ -1923,15 +2145,25 @@ static const char *set_content_md5(cmd_parms *cmd, core_dir_config *d, int arg) } static const char *set_use_canonical_name(cmd_parms *cmd, core_dir_config *d, - int arg) + char *arg) { const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - if (err != NULL) { return err; } - - d->use_canonical_name = arg != 0; + + if (strcasecmp(arg, "on") == 0) { + d->use_canonical_name = USE_CANONICAL_NAME_ON; + } + else if (strcasecmp(arg, "off") == 0) { + d->use_canonical_name = USE_CANONICAL_NAME_OFF; + } + else if (strcasecmp(arg, "dns") == 0) { + d->use_canonical_name = USE_CANONICAL_NAME_DNS; + } + else { + return "parameter must be 'on', 'off', or 'dns'"; + } return NULL; } @@ -2300,7 +2532,8 @@ API_EXPORT(const char *) ap_psignature(const char *prefix, request_rec *r) conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - if (conf->server_signature == srv_sig_off) { + if ((conf->server_signature == srv_sig_off) + || (conf->server_signature == srv_sig_unset)) { return ""; } @@ -2452,6 +2685,21 @@ static const char *set_limit_req_body(cmd_parms *cmd, core_dir_config *conf, return NULL; } +#ifdef WIN32 +static const char *set_interpreter_source(cmd_parms *cmd, core_dir_config *d, + char *arg) +{ + if (!strcasecmp(arg, "registry")) { + d->script_interpreter_source = INTERPRETER_SOURCE_REGISTRY; + } else if (!strcasecmp(arg, "script")) { + d->script_interpreter_source = INTERPRETER_SOURCE_SHEBANG; + } else { + d->script_interpreter_source = INTERPRETER_SOURCE_SHEBANG; + } + return NULL; +} +#endif + /* Note --- ErrorDocument will now work from .htaccess files. * The AllowOverride of Fileinfo allows webmasters to turn it off */ @@ -2483,6 +2731,11 @@ static const command_rec core_cmds[] = { "authentication directives when accessed using specified HTTP methods" }, { "</Limit>", endlimit_section, NULL, OR_ALL, NO_ARGS, "Marks end of <Limit>" }, +{ "<LimitExcept", ap_limit_section, (void*)1, OR_ALL, RAW_ARGS, + "Container for authentication directives to be applied when any HTTP " + "method other than those specified is used to access the resource" }, +{ "</LimitExcept>", endlimit_section, (void*)1, OR_ALL, NO_ARGS, + "Marks end of <LimitExcept>" }, { "<IfModule", start_ifmod, NULL, OR_ALL, TAKE1, "Container for directives based on existance of specified modules" }, { end_ifmodule_section, end_ifmod, NULL, OR_ALL, NO_ARGS, @@ -2554,7 +2807,7 @@ static const command_rec core_cmds[] = { { "ServerName", set_server_string_slot, (void *)XtOffsetOf (server_rec, server_hostname), RSRC_CONF, TAKE1, "The hostname of the server" }, -{ "ServerSignature", set_signature_flag, NULL, ACCESS_CONF|RSRC_CONF, TAKE1, +{ "ServerSignature", set_signature_flag, NULL, OR_ALL, TAKE1, "En-/disable server signature (on|off|email)" }, { "ServerRoot", set_server_root, NULL, RSRC_CONF, TAKE1, "Common directory of server-related files (logs, confs, etc.)" }, @@ -2589,9 +2842,8 @@ static const command_rec core_cmds[] = { { "ContentDigest", set_content_md5, NULL, OR_OPTIONS, FLAG, "whether or not to send a Content-MD5 header with each request" }, { "UseCanonicalName", set_use_canonical_name, NULL, - OR_OPTIONS, FLAG, - "Whether or not to always use the canonical ServerName : Port when " - "constructing URLs" }, + RSRC_CONF, TAKE1, + "How to work out the ServerName : Port when constructing URLs" }, { "StartServers", set_daemons_to_start, NULL, RSRC_CONF, TAKE1, "Number of child processes launched at server startup" }, { "MinSpareServers", set_min_free_servers, NULL, RSRC_CONF, TAKE1, @@ -2656,6 +2908,10 @@ static const command_rec core_cmds[] = { { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1, "Name of server User's bs2000 logon account name" }, #endif +#ifdef WIN32 +{ "ScriptInterpreterSource", set_interpreter_source, NULL, OR_FILEINFO, TAKE1, + "Where to find interpreter to run Win32 scripts (Registry or script shebang line)" }, +#endif { "ServerTokens", set_serv_tokens, NULL, RSRC_CONF, TAKE1, "Determine tokens displayed in the Server: header - Min(imal), OS or Full" }, { "LimitRequestLine", set_limit_req_line, NULL, RSRC_CONF, TAKE1, @@ -2668,7 +2924,7 @@ static const command_rec core_cmds[] = { (void*)XtOffsetOf(core_dir_config, limit_req_body), OR_ALL, TAKE1, "Limit (in bytes) on maximum size of request message body" }, -{ NULL }, +{ NULL } }; /***************************************************************** @@ -2721,16 +2977,20 @@ static int core_translate(request_rec *r) static int do_nothing(request_rec *r) { return OK; } #ifdef USE_MMAP_FILES -struct mmap { +struct mmap_rec { void *mm; size_t length; }; static void mmap_cleanup(void *mmv) { - struct mmap *mmd = mmv; + struct mmap_rec *mmd = mmv; - munmap(mmd->mm, mmd->length); + if (munmap(mmd->mm, mmd->length) == -1) { + ap_log_error(APLOG_MARK, APLOG_ERR, NULL, + "Failed to munmap memory of length %ld at 0x%lx", + (long) mmd->length, (long) mmd->mm); + } } #endif @@ -2751,6 +3011,9 @@ static int default_handler(request_rec *r) #ifdef USE_MMAP_FILES caddr_t mm; #endif +#ifdef CHARSET_EBCDIC + int convert_flag; +#endif /* This handler has no use for a request body (yet), but we still * need to read and discard it if the client sent one. @@ -2815,6 +3078,7 @@ static int default_handler(request_rec *r) #ifdef USE_MMAP_FILES ap_block_alarms(); if ((r->finfo.st_size >= MMAP_THRESHOLD) + && (r->finfo.st_size < MMAP_LIMIT) && (!r->header_only || (d->content_md5 & 1))) { /* we need to protect ourselves in case we die while we've got the * file mmapped */ @@ -2833,22 +3097,27 @@ static int default_handler(request_rec *r) ap_unblock_alarms(); #endif - if (d->content_md5 & 1) { - ap_table_setn(r->headers_out, "Content-MD5", - ap_md5digest(r->pool, f)); - } - - rangestatus = ap_set_byterange(r); #ifdef CHARSET_EBCDIC - /* To make serving of "raw ASCII text" files easy (they serve faster + /* To make serving of "raw ASCII text" files easy (they serve faster * since they don't have to be converted from EBCDIC), a new * "magic" type prefix was invented: text/x-ascii-{plain,html,...} * If we detect one of these content types here, we simply correct * the type to the real text/{plain,html,...} type. Otherwise, we * set a flag that translation is required later on. */ - ap_checkconv(r); -#endif /*CHARSET_EBCDIC*/ + convert_flag = ap_checkconv(r); + if (d->content_md5 & 1) { + ap_table_setn(r->headers_out, "Content-MD5", + ap_md5digest(r->pool, f, convert_flag)); + } +#else + if (d->content_md5 & 1) { + ap_table_setn(r->headers_out, "Content-MD5", + ap_md5digest(r->pool, f)); + } +#endif /* CHARSET_EBCDIC */ + + rangestatus = ap_set_byterange(r); ap_send_http_header(r); @@ -2859,8 +3128,18 @@ static int default_handler(request_rec *r) else { long offset, length; while (ap_each_byterange(r, &offset, &length)) { - fseek(f, offset, SEEK_SET); - ap_send_fd_length(f, r, length); + /* + * Non zero returns are more portable than checking + * for a return of -1. + */ + if (fseek(f, offset, SEEK_SET)) { + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "Failed to fseek for byterange (%ld, %ld)", + offset, length); + } + else { + ap_send_fd_length(f, r, length); + } } } } @@ -2868,7 +3147,7 @@ static int default_handler(request_rec *r) #ifdef USE_MMAP_FILES } else { - struct mmap *mmd; + struct mmap_rec *mmd; mmd = ap_palloc(r->pool, sizeof(*mmd)); mmd->mm = mm; @@ -2880,7 +3159,7 @@ static int default_handler(request_rec *r) AP_MD5_CTX context; ap_MD5Init(&context); - ap_MD5Update(&context, (void *)mm, r->finfo.st_size); + ap_MD5Update(&context, (void *)mm, (unsigned int)r->finfo.st_size); ap_table_setn(r->headers_out, "Content-MD5", ap_md5contextTo64(r->pool, &context)); } @@ -2909,7 +3188,7 @@ static int default_handler(request_rec *r) static const handler_rec core_handlers[] = { { "*/*", default_handler }, { "default-handler", default_handler }, -{ NULL } +{ NULL, NULL } }; API_VAR_EXPORT module core_module = { diff --git a/usr.sbin/httpd/src/main/http_log.c b/usr.sbin/httpd/src/main/http_log.c index 02424e748e4..7a1e0ea5d0c 100644 --- a/usr.sbin/httpd/src/main/http_log.c +++ b/usr.sbin/httpd/src/main/http_log.c @@ -172,8 +172,10 @@ static int error_log_child(void *cmd, child_info *pinfo) child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); return(child_pid); #elif defined(OS2) - /* For OS/2 we need to use a '/' */ - execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + /* For OS/2 we need to use a '/' and spawn the child rather than exec as + * we haven't forked */ + child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + return(child_pid); #else execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); #endif @@ -188,9 +190,17 @@ static void open_error_log(server_rec *s, pool *p) if (*s->error_fname == '|') { FILE *dummy; - +#ifdef TPF + TPF_FORK_CHILD cld; + cld.filename = s->error_fname+1; + cld.subprocess_env = NULL; + cld.prog_type = FORK_NAME; + if (!ap_spawn_child(p, NULL, &cld, + kill_after_timeout, &dummy, NULL, NULL)) { +#else if (!ap_spawn_child(p, error_log_child, (void *)(s->error_fname+1), kill_after_timeout, &dummy, NULL, NULL)) { +#endif /* TPF */ perror("ap_spawn_child"); fprintf(stderr, "Couldn't fork child for ErrorLog process\n"); exit(1); @@ -311,6 +321,18 @@ static void log_error_core(const char *file, int line, int level, return; logf = s->error_log; } +#ifdef TPF + else if (tpf_child) { + /* + * If we are doing normal logging, don't log messages that are + * above the server log level unless it is a startup/shutdown notice + */ + if (((level & APLOG_LEVELMASK) != APLOG_NOTICE) && + ((level & APLOG_LEVELMASK) > s->loglevel)) + return; + logf = stderr; + } +#endif /* TPF */ else { /* * If we are doing syslog logging, don't log messages that are @@ -322,8 +344,7 @@ static void log_error_core(const char *file, int line, int level, } if (logf) { - len = ap_snprintf(errstr, sizeof(errstr), "%s: [%s] ", - ap_server_argv0, ap_get_time()); + len = ap_snprintf(errstr, sizeof(errstr), "[%s] ", ap_get_time()); } else { len = 0; } @@ -331,6 +352,7 @@ static void log_error_core(const char *file, int line, int level, len += ap_snprintf(errstr + len, sizeof(errstr) - len, "[%s] ", priorities[level & APLOG_LEVELMASK].t_name); +#ifndef TPF if (file && (level & APLOG_LEVELMASK) == APLOG_DEBUG) { #ifdef _OSD_POSIX char tmp[256]; @@ -353,6 +375,7 @@ static void log_error_core(const char *file, int line, int level, len += ap_snprintf(errstr + len, sizeof(errstr) - len, "%s(%d): ", file, line); } +#endif /* TPF */ if (r) { /* XXX: TODO: add a method of selecting whether logged client * addresses are in dotted quad or resolved form... dotted @@ -456,6 +479,8 @@ API_EXPORT(void) ap_log_rerror(const char *file, int line, int level, * something, even an empty string, into the "error-notes" cell * before calling this routine. */ + va_end(args); + va_start(args,fmt); if (((level & APLOG_LEVELMASK) <= APLOG_WARNING) && (ap_table_get(r->notes, "error-notes") == NULL)) { ap_table_setn(r->notes, "error-notes", @@ -704,8 +729,10 @@ static int piped_log_child(void *cmd, child_info *pinfo) child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); return(child_pid); #elif defined(OS2) - /* For OS/2 we need to use a '/' */ - execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + /* For OS/2 we need to use a '/' and spawn the child rather than exec as + * we haven't forked */ + child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + return(child_pid); #else execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); #endif @@ -719,9 +746,18 @@ API_EXPORT(piped_log *) ap_open_piped_log(pool *p, const char *program) { piped_log *pl; FILE *dummy; - +#ifdef TPF + TPF_FORK_CHILD cld; + cld.filename = (char *)program; + cld.subprocess_env = NULL; + cld.prog_type = FORK_NAME; + + if (!ap_spawn_child (p, NULL, &cld, + kill_after_timeout, &dummy, NULL, NULL)){ +#else if (!ap_spawn_child(p, piped_log_child, (void *)program, kill_after_timeout, &dummy, NULL, NULL)) { +#endif /* TPF */ perror("ap_spawn_child"); fprintf(stderr, "Couldn't fork child for piped log process\n"); exit (1); diff --git a/usr.sbin/httpd/src/main/http_main.c b/usr.sbin/httpd/src/main/http_main.c index c197baa2191..469b3ebd8d9 100644 --- a/usr.sbin/httpd/src/main/http_main.c +++ b/usr.sbin/httpd/src/main/http_main.c @@ -180,6 +180,10 @@ void ap_force_library_loading(void) { #ifdef WIN32 #include "../os/win32/service.h" #include "../os/win32/registry.h" +#define DEFAULTSERVICENAME "Apache" +#define PATHSEPARATOR '\\' +#else +#define PATHSEPARATOR '/' #endif @@ -225,26 +229,28 @@ void *ap_dummy_mutex = &ap_dummy_mutex; * for the most part the only code that acts on 'em. (Hmmm... mod_main.c?) */ -int ap_standalone; -uid_t ap_user_id; -char *ap_user_name; -gid_t ap_group_id; +int ap_standalone=0; +int ap_configtestonly=0; +int ap_docrootcheck=1; +uid_t ap_user_id=0; +char *ap_user_name=NULL; +gid_t ap_group_id=0; #ifdef MULTIPLE_GROUPS gid_t group_id_list[NGROUPS_MAX]; #endif -int ap_max_requests_per_child; -int ap_threads_per_child; -int ap_excess_requests_per_child; -char *ap_pid_fname; -char *ap_scoreboard_fname; +int ap_max_requests_per_child=0; +int ap_threads_per_child=0; +int ap_excess_requests_per_child=0; +char *ap_pid_fname=NULL; +char *ap_scoreboard_fname=NULL; char *ap_lock_fname; -char *ap_server_argv0; +char *ap_server_argv0=NULL; struct in_addr ap_bind_address; -int ap_daemons_to_start; -int ap_daemons_min_free; -int ap_daemons_max_free; -int ap_daemons_limit; -time_t ap_restart_time; +int ap_daemons_to_start=0; +int ap_daemons_min_free=0; +int ap_daemons_max_free=0; +int ap_daemons_limit=0; +time_t ap_restart_time=0; int ap_suexec_enabled = 0; int ap_listenbacklog; int ap_dump_settings = 0; @@ -280,8 +286,8 @@ static int max_daemons_limit = -1; listen_rec *ap_listeners; static listen_rec *head_listener; -API_VAR_EXPORT char ap_server_root[MAX_STRING_LEN]; -char ap_server_confname[MAX_STRING_LEN]; +API_VAR_EXPORT char ap_server_root[MAX_STRING_LEN]=""; +char ap_server_confname[MAX_STRING_LEN]=""; char ap_coredump_dir[MAX_STRING_LEN]; array_header *ap_server_pre_read_config; @@ -332,7 +338,9 @@ struct other_child_rec { static other_child_rec *other_children; #endif +static pool *pglobal; /* Global pool */ static pool *pconf; /* Pool for config stuff */ +static pool *plog; /* Pool for error-logging files */ static pool *ptrans; /* Pool for per-transaction stuff */ static pool *pchild; /* Pool for httpd child stuff */ static pool *pcommands; /* Pool for -C and -c switches */ @@ -342,6 +350,11 @@ static int APACHE_TLS my_pid; /* it seems silly to call getpid all the time */ static int my_child_num; #endif +#ifdef TPF +int tpf_child = 0; +char tpf_server_name[INETD_SERVNAME_LENGTH+1]; +#endif /* TPF */ + scoreboard *ap_scoreboard_image = NULL; /* @@ -424,6 +437,20 @@ API_EXPORT(void) ap_add_config_define(const char *define) *var = ap_pstrdup(pcommands, define); return; } + +/* + * Invoke the `close_connection' hook of modules to let them do + * some connection dependent actions before we close it. + */ +static void ap_call_close_connection_hook(conn_rec *c) +{ + module *m; + for (m = top_module; m != NULL; m = m->next) + if (m->magic == MODULE_MAGIC_COOKIE_EAPI) + if (m->close_connection != NULL) + (*m->close_connection)(c); + return; +} #endif /* EAPI */ static APACHE_TLS int volatile exit_after_unblock = 0; @@ -745,17 +772,21 @@ static void accept_mutex_init(pool *p) static void accept_mutex_on(void) { - if (semop(sem_id, &op_on, 1) < 0) { - perror("accept_mutex_on"); - clean_child_exit(APEXIT_CHILDFATAL); + while (semop(sem_id, &op_on, 1) < 0) { + if (errno != EINTR) { + perror("accept_mutex_on"); + clean_child_exit(APEXIT_CHILDFATAL); + } } } static void accept_mutex_off(void) { - if (semop(sem_id, &op_off, 1) < 0) { - perror("accept_mutex_off"); - clean_child_exit(APEXIT_CHILDFATAL); + while (semop(sem_id, &op_off, 1) < 0) { + if (errno != EINTR) { + perror("accept_mutex_off"); + clean_child_exit(APEXIT_CHILDFATAL); + } } } @@ -911,9 +942,11 @@ static void accept_mutex_child_init(pool *p) int rc = DosOpenMutexSem(NULL, &lock_sem); if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "Child cannot open lock semaphore"); + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, + "Child cannot open lock semaphore, rc=%d", rc); clean_child_exit(APEXIT_CHILDINIT); + } else { + ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); } } @@ -926,8 +959,8 @@ static void accept_mutex_init(pool *p) int rc = DosCreateMutexSem(NULL, &lock_sem, DC_SEM_SHARED, FALSE); if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, - "Parent cannot create lock semaphore"); + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, + "Parent cannot create lock semaphore, rc=%d", rc); exit(APEXIT_INIT); } @@ -939,7 +972,7 @@ static void accept_mutex_on(void) int rc = DosRequestMutexSem(lock_sem, SEM_INDEFINITE_WAIT); if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, "OS2SEM: Error %d getting accept lock. Exiting!", rc); clean_child_exit(APEXIT_CHILDFATAL); } @@ -950,12 +983,44 @@ static void accept_mutex_off(void) int rc = DosReleaseMutexSem(lock_sem); if (rc != 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, server_conf, "OS2SEM: Error %d freeing accept lock. Exiting!", rc); clean_child_exit(APEXIT_CHILDFATAL); } } +#elif defined(USE_TPF_CORE_SERIALIZED_ACCEPT) + +static int tpf_core_held; + +static void accept_mutex_cleanup(void *foo) +{ + if(tpf_core_held) + coruc(RESOURCE_KEY); +} + +#define accept_mutex_init(x) + +static void accept_mutex_child_init(pool *p) +{ + ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); + tpf_core_held = 0; +} + +static void accept_mutex_on(void) +{ + corhc(RESOURCE_KEY); + tpf_core_held = 1; + ap_check_signals(); +} + +static void accept_mutex_off(void) +{ + coruc(RESOURCE_KEY); + tpf_core_held = 0; + ap_check_signals(); +} + #else /* Default --- no serialization. Other methods *could* go here, * as #elifs... @@ -991,12 +1056,15 @@ static void usage(char *bin) pad[i] = ' '; pad[i] = '\0'; #ifdef SHARED_CORE - fprintf(stderr, "Usage: %s [-R directory] [-d directory] [-f file]\n", bin); + fprintf(stderr, "Usage: %s [-R directory] [-D name] [-d directory] [-f file]\n", bin); #else - fprintf(stderr, "Usage: %s [-d directory] [-f file]\n", bin); + fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin); #endif fprintf(stderr, " %s [-C \"directive\"] [-c \"directive\"]\n", pad); - fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t]\n", pad); + fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]\n", pad); +#ifdef WIN32 + fprintf(stderr, " %s [-n service] [-k signal] [-i] [-u]\n", pad); +#endif fprintf(stderr, "Options:\n"); #ifdef SHARED_CORE fprintf(stderr, " -R directory : specify an alternate location for shared object files\n"); @@ -1012,10 +1080,15 @@ static void usage(char *bin) fprintf(stderr, " -l : list compiled-in modules\n"); fprintf(stderr, " -L : list available configuration directives\n"); fprintf(stderr, " -S : show parsed settings (currently only vhost settings)\n"); - fprintf(stderr, " -t : run syntax test for configuration files only\n"); + fprintf(stderr, " -t : run syntax check for config files (with docroot check)\n"); + fprintf(stderr, " -T : run syntax check for config files (without docroot check)\n"); #ifdef WIN32 + fprintf(stderr, " -n name : set service name and use its ServerConfigFile\n"); fprintf(stderr, " -k shutdown : tell running Apache to shutdown\n"); fprintf(stderr, " -k restart : tell running Apache to do a graceful restart\n"); + fprintf(stderr, " -k start : tell Apache to start\n"); + fprintf(stderr, " -i : install an Apache service\n"); + fprintf(stderr, " -u : uninstall an Apache service\n"); #endif exit(1); } @@ -1034,10 +1107,9 @@ static APACHE_TLS int volatile alarms_blocked = 0; static APACHE_TLS int volatile alarm_pending = 0; static void timeout(int sig) -{ /* Also called on SIGPIPE */ +{ void *dirconf; - signal(SIGPIPE, SIG_IGN); /* Block SIGPIPE */ if (alarms_blocked) { alarm_pending = 1; return; @@ -1055,20 +1127,10 @@ static void timeout(int sig) else dirconf = current_conn->server->lookup_defaults; if (!current_conn->keptalive) { - if (sig == SIGPIPE) { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, - current_conn->server, - "[client %s] stopped connection before %s completed", - current_conn->remote_ip, - timeout_name ? timeout_name : "request"); - } - else { - ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, - current_conn->server, - "[client %s] %s timed out", - current_conn->remote_ip, - timeout_name ? timeout_name : "request"); - } + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, + current_conn->server, "[client %s] %s timed out", + current_conn->remote_ip, + timeout_name ? timeout_name : "request"); } if (timeout_req) { @@ -1092,8 +1154,17 @@ static void timeout(int sig) log_req = log_req->prev; } - if (!current_conn->keptalive) + if (!current_conn->keptalive) { + /* in some cases we come here before setting the time */ + if (log_req->request_time == 0) { + log_req->request_time = time(0); + } ap_log_transaction(log_req); + } + +#ifdef EAPI + ap_call_close_connection_hook(save_req->connection); +#endif /* EAPI */ ap_bsetflag(save_req->connection->client, B_EOUT, 1); ap_bclose(save_req->connection->client); @@ -1104,6 +1175,9 @@ static void timeout(int sig) ap_longjmp(jmpbuffer, 1); } else { /* abort the connection */ +#ifdef EAPI + ap_call_close_connection_hook(current_conn); +#endif /* EAPI */ ap_bsetflag(current_conn->client, B_EOUT, 1); ap_bclose(current_conn->client); current_conn->aborted = 1; @@ -1196,6 +1270,7 @@ unsigned int ap_set_callback_and_alarm(void (*fn) (int), int x) /* Just note the timeout in our scoreboard, no need to call the system. * We also note that the virtual time has gone forward. */ + ap_check_signals(); old = ap_scoreboard_image->servers[my_child_num].timeout_len; ap_scoreboard_image->servers[my_child_num].timeout_len = x; ++ap_scoreboard_image->servers[my_child_num].cur_vtime; @@ -1281,6 +1356,7 @@ API_EXPORT(void) ap_soft_timeout(char *name, request_rec *r) API_EXPORT(void) ap_kill_timeout(request_rec *dummy) { + ap_check_signals(); ap_set_callback_and_alarm(NULL, 0); timeout_req = NULL; timeout_name = NULL; @@ -1379,10 +1455,16 @@ static void lingering_close(request_rec *r) /* Send any leftover data to the client, but never try to again */ if (ap_bflush(r->connection->client) == -1) { +#ifdef EAPI + ap_call_close_connection_hook(r->connection); +#endif /* EAPI */ ap_kill_timeout(r); ap_bclose(r->connection->client); return; } +#ifdef EAPI + ap_call_close_connection_hook(r->connection); +#endif /* EAPI */ ap_bsetflag(r->connection->client, B_EOUT, 1); /* Close our half of the connection --- send the client a FIN */ @@ -1561,6 +1643,9 @@ static void reinit_scoreboard(pool *p) { ap_assert(!ap_scoreboard_image); ap_scoreboard_image = (scoreboard *) malloc(SCOREBOARD_SIZE); + if (ap_scoreboard_image == NULL) { + fprintf(stderr, "Ouch! Out of memory reiniting scoreboard!\n"); + } memset(ap_scoreboard_image, 0, SCOREBOARD_SIZE); } @@ -1908,6 +1993,37 @@ static void reopen_scoreboard(pool *p) { } +#elif defined(USE_TPF_SCOREBOARD) + +static void cleanup_scoreboard_heap() +{ + int rv; + rv = rsysc(ap_scoreboard_image, SCOREBOARD_FRAMES, SCOREBOARD_NAME); + if(rv == RSYSC_ERROR) { + ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, + "rsysc() could not release scoreboard system heap"); + } +} + +static void setup_shared_mem(pool *p) +{ + cinfc(CINFC_WRITE, CINFC_CMMCTK2); + ap_scoreboard_image = (scoreboard *) gsysc(SCOREBOARD_FRAMES, SCOREBOARD_NAME); + + if (!ap_scoreboard_image) { + fprintf(stderr, "httpd: Could not create scoreboard system heap storage.\n"); + exit(APEXIT_INIT); + } + + ap_register_cleanup(p, NULL, cleanup_scoreboard_heap, ap_null_cleanup); + ap_scoreboard_image->global.running_generation = 0; +} + +static void reopen_scoreboard(pool *p) +{ + cinfc(CINFC_WRITE, CINFC_CMMCTK2); +} + #else #define SCOREBOARD_FILE static scoreboard _scoreboard_image; @@ -1956,6 +2072,9 @@ void reopen_scoreboard(pool *p) if (scoreboard_fd != -1) ap_pclosef(p, scoreboard_fd); +#ifdef TPF + ap_scoreboard_fname = ap_server_root_relative(p, ap_scoreboard_fname); +#endif /* TPF */ scoreboard_fd = ap_popenf(p, ap_scoreboard_fname, O_CREAT | O_BINARY | O_RDWR, 0666); if (scoreboard_fd == -1) { perror(ap_scoreboard_fname); @@ -2036,7 +2155,10 @@ static void clean_parent_exit(int code) __attribute__((noreturn)); static void clean_parent_exit(int code) { /* Clear the pool - including any registered cleanups */ - ap_destroy_pool(pconf); + ap_destroy_pool(pglobal); +#ifdef EAPI + ap_kill_alloc_shared(); +#endif exit(code); } @@ -2048,6 +2170,8 @@ int ap_update_child_status(int child_num, int status, request_rec *r) if (child_num < 0) return -1; + ap_check_signals(); + ap_sync_scoreboard_image(); ss = &ap_scoreboard_image->servers[child_num]; old_status = ss->status; @@ -2585,7 +2709,7 @@ static void usr1_handler(int sig) static int volatile shutdown_pending; static int volatile restart_pending; static int volatile is_graceful; -ap_generation_t volatile ap_my_generation; +ap_generation_t volatile ap_my_generation=0; #ifdef WIN32 /* @@ -2771,6 +2895,11 @@ static void set_signals(void) if (sigaction(SIGXFSZ, &sa, NULL) < 0) ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGXFSZ)"); #endif +#ifdef SIGPIPE + sa.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sa, NULL) < 0) + ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf, "sigaction(SIGPIPE)"); +#endif /* we want to ignore HUPs and USR1 while we're busy processing one */ sigaddset(&sa.sa_mask, SIGHUP); @@ -2810,6 +2939,10 @@ static void set_signals(void) #ifdef SIGUSR1 signal(SIGUSR1, restart); #endif /* SIGUSR1 */ +#ifdef SIGPIPE + signal(SIGPIPE, SIG_IGN); +#endif /* SIGPIPE */ + #endif } @@ -2849,7 +2982,7 @@ static void detach(void) exit(1); } #elif defined(OS2) || defined(TPF) - /* OS/2 don't support process group IDs */ + /* OS/2 and TPF don't support process group IDs */ pgrp = getpid(); #elif defined(MPE) /* MPE uses negative pid for process group */ @@ -2915,8 +3048,19 @@ static void set_group_privs(void) else name = ap_user_name; -#ifndef OS2 - /* OS/2 dosen't support groups. */ +#if !defined(OS2) && !defined(TPF) + /* OS/2 and TPF don't support groups. */ + + /* + * Set the GID before initgroups(), since on some platforms + * setgid() is known to zap the group list. + */ + if (setgid(ap_group_id) == -1) { + ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf, + "setgid: unable to set group id to Group %u", + (unsigned)ap_group_id); + clean_child_exit(APEXIT_CHILDFATAL); + } /* Reset `groups' attributes. */ @@ -2932,14 +3076,8 @@ static void set_group_privs(void) "getgroups: unable to get group list"); clean_child_exit(APEXIT_CHILDFATAL); } -#endif - if (setgid(ap_group_id) == -1) { - ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf, - "setgid: unable to set group id to Group %u", - (unsigned)ap_group_id); - clean_child_exit(APEXIT_CHILDFATAL); - } -#endif +#endif /* MULTIPLE_GROUPS */ +#endif /* !defined(OS2) && !defined(TPF) */ } #endif /* ndef WIN32 */ } @@ -2980,6 +3118,8 @@ static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout, conn->pool = p; conn->local_addr = *saddr; + conn->local_ip = ap_pstrdup(conn->pool, + inet_ntoa(conn->local_addr.sin_addr)); conn->server = server; /* just a guess for now */ ap_update_vhost_given_ip(conn); conn->base_server = conn->server; @@ -3010,7 +3150,7 @@ static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout, return conn; } -#if defined(TCP_NODELAY) && !defined(MPE) +#if defined(TCP_NODELAY) && !defined(MPE) && !defined(TPF) static void sock_disable_nagle(int s) { /* The Nagle algorithm says that we should delay sending partial @@ -3077,9 +3217,14 @@ static int make_sock(pool *p, const struct sockaddr_in *server) #endif #ifndef WORKAROUND_SOLARIS_BUG +#ifndef BEOS /* this won't work for BeOS sockets!! */ s = ap_slack(s, AP_SLACK_HIGH); +#endif ap_note_cleanups_for_socket(p, s); /* arrange to close on exec or restart */ +#ifdef TPF + os_note_additional_cleanups(p, s); +#endif /* TPF */ #endif #ifndef MPE @@ -3088,18 +3233,26 @@ static int make_sock(pool *p, const struct sockaddr_in *server) if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(int)) < 0) { ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf, "make_sock: for %s, setsockopt: (SO_REUSEADDR)", addr); +#ifdef BEOS + closesocket(s); +#else close(s); +#endif ap_unblock_alarms(); return -1; } #endif /*_OSD_POSIX*/ one = 1; -#ifndef BEOS -/* BeOS does not support SO_KEEPALIVE */ +#ifdef SO_KEEPALIVE if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(int)) < 0) { ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf, "make_sock: for %s, setsockopt: (SO_KEEPALIVE)", addr); +#ifdef BEOS + closesocket(s); +#else close(s); +#endif + ap_unblock_alarms(); return -1; } @@ -3145,6 +3298,7 @@ static int make_sock(pool *p, const struct sockaddr_in *server) if (ntohs(server->sin_port) < 1024) GETPRIVMODE(); #endif + if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) { ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf, "make_sock: could not bind to %s", addr); @@ -3152,7 +3306,12 @@ static int make_sock(pool *p, const struct sockaddr_in *server) if (ntohs(server->sin_port) < 1024) GETUSERMODE(); #endif + +#ifdef BEOS + closesocket(s); +#else close(s); +#endif ap_unblock_alarms(); exit(1); } @@ -3164,7 +3323,11 @@ static int make_sock(pool *p, const struct sockaddr_in *server) if (listen(s, ap_listenbacklog) == -1) { ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "make_sock: unable to listen for connections on %s", addr); +#ifdef BEOS + closesocket(s); +#else close(s); +#endif ap_unblock_alarms(); exit(1); } @@ -3176,7 +3339,7 @@ static int make_sock(pool *p, const struct sockaddr_in *server) #endif ap_unblock_alarms(); -#ifndef WIN32 +#ifdef CHECK_FD_SETSIZE /* protect various fd_sets */ if (s >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, @@ -3184,7 +3347,11 @@ static int make_sock(pool *p, const struct sockaddr_in *server) "larger than FD_SETSIZE (%u) " "found, you probably need to rebuild Apache with a " "larger FD_SETSIZE", addr, s, FD_SETSIZE); +#ifdef BEOS + closesocket(s); +#else close(s); +#endif return -1; } #endif @@ -3379,6 +3546,9 @@ static void show_compile_settings(void) #ifdef EAPI printf(" -D EAPI\n"); #endif +#ifdef EAPI_MM + printf(" -D EAPI_MM\n"); +#endif #ifdef BIG_SECURITY_HOLE printf(" -D BIG_SECURITY_HOLE\n"); #endif @@ -3465,7 +3635,7 @@ static void show_compile_settings(void) #ifdef SUEXEC_BIN printf(" -D SUEXEC_BIN=\"" SUEXEC_BIN "\"\n"); #endif -#ifdef SHARED_CORE_DIR +#if defined(SHARED_CORE) && defined(SHARED_CORE_DIR) printf(" -D SHARED_CORE_DIR=\"" SHARED_CORE_DIR "\"\n"); #endif #ifdef DEFAULT_PIDLOG @@ -3514,7 +3684,9 @@ static void common_init(void) AMCSocketInitialize(); #endif /* WIN32 */ - pconf = ap_init_alloc(); + pglobal = ap_init_alloc(); + pconf = ap_make_sub_pool(pglobal); + plog = ap_make_sub_pool(pglobal); ptrans = ap_make_sub_pool(pconf); ap_util_init(); @@ -3603,7 +3775,7 @@ static void child_main(int child_num_arg) if (setuid(ap_user_id) == -1) { GETUSERMODE(); ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf, - "setuid: unable to change uid"); + "setuid: unable to change to uid: %d", ap_user_id); exit(1); } GETUSERMODE(); @@ -3616,7 +3788,7 @@ static void child_main(int child_num_arg) #endif setuid(ap_user_id) == -1)) { ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf, - "setuid: unable to change uid"); + "setuid: unable to change to uid: %ld", (long) ap_user_id); clean_child_exit(APEXIT_CHILDFATAL); } #endif @@ -3629,8 +3801,7 @@ static void child_main(int child_num_arg) (void) ap_update_child_status(my_child_num, SERVER_READY, (request_rec *) NULL); /* - * Setup the jump buffers so that we can return here after - * a signal or a timeout (yeah, I know, same thing). + * Setup the jump buffers so that we can return here after a timeout */ ap_setjmp(jmpbuffer); #ifndef OS2 @@ -3638,8 +3809,12 @@ static void child_main(int child_num_arg) signal(SIGURG, timeout); #endif #endif - signal(SIGPIPE, timeout); signal(SIGALRM, alrm_handler); +#ifdef TPF + signal(SIGHUP, just_die); + signal(SIGTERM, just_die); + signal(SIGUSR1, just_die); +#endif /* TPF */ #ifdef OS2 /* Stop Ctrl-C/Ctrl-Break signals going to child processes */ @@ -3676,7 +3851,7 @@ static void child_main(int child_num_arg) #ifndef WIN32 if ((ap_max_requests_per_child > 0 - && ++requests_this_child >= ap_max_requests_per_child)) { + && requests_this_child++ >= ap_max_requests_per_child)) { clean_child_exit(0); } #else @@ -3729,7 +3904,7 @@ static void child_main(int child_num_arg) usr1_just_die = 0; for (;;) { clen = sizeof(sa_client); - csd = accept(sd, &sa_client, &clen); + csd = ap_accept(sd, &sa_client, &clen); if (csd >= 0 || errno != EINTR) break; if (deferred_die) { @@ -3793,11 +3968,43 @@ static void child_main(int child_num_arg) case ENETUNREACH: #endif break; +#ifdef ENETDOWN + case ENETDOWN: + /* + * When the network layer has been shut down, there + * is not much use in simply exiting: the parent + * would simply re-create us (and we'd fail again). + * Use the CHILDFATAL code to tear the server down. + * @@@ Martin's idea for possible improvement: + * A different approach would be to define + * a new APEXIT_NETDOWN exit code, the reception + * of which would make the parent shutdown all + * children, then idle-loop until it detected that + * the network is up again, and restart the children. + * Ben Hyde noted that temporary ENETDOWN situations + * occur in mobile IP. + */ + ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, + "accept: giving up."); + clean_child_exit(APEXIT_CHILDFATAL); +#endif /*ENETDOWN*/ +#ifdef TPF + case EINACT: + ap_log_error(APLOG_MARK, APLOG_EMERG, server_conf, + "offload device inactive"); + clean_child_exit(APEXIT_CHILDFATAL); + break; + default: + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, server_conf, + "select/accept error (%u)", errno); + clean_child_exit(APEXIT_CHILDFATAL); +#else default: ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "accept: (client socket)"); clean_child_exit(1); +#endif } } @@ -3818,6 +4025,11 @@ static void child_main(int child_num_arg) SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */ +#ifdef TPF + if (csd == 0) /* 0 is invalid socket for TPF */ + continue; +#endif + /* We've got a socket, let's at least process one request off the * socket before we accept a graceful restart request. */ @@ -3826,6 +4038,7 @@ static void child_main(int child_num_arg) ap_note_cleanups_for_fd(ptrans, csd); /* protect various fd_sets */ +#ifdef CHECK_FD_SETSIZE if (csd >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, "[csd] filedescriptor (%u) larger than FD_SETSIZE (%u) " @@ -3833,6 +4046,7 @@ static void child_main(int child_num_arg) "larger FD_SETSIZE", csd, FD_SETSIZE); continue; } +#endif /* * We now have a connection, so set it up with the appropriate @@ -3872,6 +4086,7 @@ static void child_main(int child_num_arg) ap_note_cleanups_for_fd(ptrans, dupped_csd); /* protect various fd_sets */ +#ifdef CHECK_FD_SETSIZE if (dupped_csd >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, "[dupped_csd] filedescriptor (%u) larger than FD_SETSIZE (%u) " @@ -3880,6 +4095,7 @@ static void child_main(int child_num_arg) continue; } #endif +#endif ap_bpushfd(conn_io, csd, dupped_csd); current_conn = new_connection(ptrans, server_conf, conn_io, @@ -3917,6 +4133,9 @@ static void child_main(int child_num_arg) ap_sync_scoreboard_image(); if (ap_scoreboard_image->global.running_generation != ap_my_generation) { +#ifdef EAPI + ap_call_close_connection_hook(current_conn); +#endif /* EAPI */ ap_bclose(conn_io); clean_child_exit(0); } @@ -3945,6 +4164,9 @@ static void child_main(int child_num_arg) */ #ifdef NO_LINGCLOSE +#ifdef EAPI + ap_call_close_connection_hook(current_conn); +#endif /* EAPI */ ap_bclose(conn_io); /* just close it */ #else if (r && r->connection @@ -3955,6 +4177,9 @@ static void child_main(int child_num_arg) lingering_close(r); } else { +#ifdef EAPI + ap_call_close_connection_hook(current_conn); +#endif /* EAPI */ ap_bsetflag(conn_io, B_EOUT, 1); ap_bclose(conn_io); } @@ -3962,6 +4187,36 @@ static void child_main(int child_num_arg) } } +#ifdef TPF +static void reset_tpf_listeners(APACHE_TPF_INPUT *input_parms) +{ + int count; + listen_rec *lr; + + count = 0; + listenmaxfd = -1; + FD_ZERO(&listenfds); + lr = ap_listeners; + + for(;;) { + lr->fd = input_parms->listeners[count]; + if(lr->fd >= 0) { + FD_SET(lr->fd, &listenfds); + if(lr->fd > listenmaxfd) + listenmaxfd = lr->fd; + } + if(lr->next == NULL) + break; + lr = lr->next; + count++; + } + lr->next = ap_listeners; + head_listener = ap_listeners; + close_unused_listeners(); +} + +#endif /* TPF */ + static int make_child(server_rec *s, int slot, time_t now) { int pid; @@ -3973,7 +4228,9 @@ static int make_child(server_rec *s, int slot, time_t now) if (one_process) { signal(SIGHUP, just_die); signal(SIGINT, just_die); +#ifdef SIGQUIT signal(SIGQUIT, SIG_DFL); +#endif signal(SIGTERM, just_die); child_main(slot); } @@ -3985,12 +4242,14 @@ static int make_child(server_rec *s, int slot, time_t now) (void) ap_update_child_status(slot, SERVER_STARTING, (request_rec *) NULL); -#ifndef _OSD_POSIX - if ((pid = fork()) == -1) { -#else /*_OSD_POSIX*/ +#ifdef _OSD_POSIX /* BS2000 requires a "special" version of fork() before a setuid() call */ - if ((pid = os_fork()) == -1) { -#endif /*_OSD_POSIX*/ + if ((pid = os_fork(ap_user_name)) == -1) { +#elif defined(TPF) + if ((pid = os_fork(s, slot)) == -1) { +#else + if ((pid = fork()) == -1) { +#endif ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process"); /* fork didn't succeed. Fix the scoreboard or else @@ -4308,7 +4567,8 @@ static void standalone_main(int argc, char **argv) server_conf = ap_read_config(pconf, ptrans, ap_server_confname); setup_listeners(pconf); - ap_open_logs(server_conf, pconf); + ap_clear_pool(plog); + ap_open_logs(server_conf, plog); ap_log_pid(pconf, ap_pid_fname); ap_set_version(); /* create our server_version string */ ap_init_modules(pconf, server_conf); @@ -4424,6 +4684,11 @@ static void standalone_main(int argc, char **argv) } perform_idle_server_maintenance(); +#ifdef TPF + shutdown_pending = os_check_server(tpf_server_name); + ap_check_signals(); + sleep(1); +#endif /*TPF */ } if (shutdown_pending) { @@ -4517,7 +4782,6 @@ extern int optind; int REALMAIN(int argc, char *argv[]) { int c; - int configtestonly = 0; int sock_in; int sock_out; char *s; @@ -4536,11 +4800,17 @@ int REALMAIN(int argc, char *argv[]) SOCKSinit(argv[0]); #endif +#ifdef TPF + APACHE_TPF_INPUT input_parms; + ecbptr()->ebrout = PRIMECRAS; + input_parms = * (APACHE_TPF_INPUT *)(&(ecbptr()->ebw000)); +#endif + MONCONTROL(0); common_init(); - if ((s = strrchr(argv[0], '/')) != NULL) { + if ((s = strrchr(argv[0], PATHSEPARATOR)) != NULL) { ap_server_argv0 = ++s; } else { @@ -4552,9 +4822,8 @@ int REALMAIN(int argc, char *argv[]) ap_setup_prelinked_modules(); -#ifndef TPF while ((c = getopt(argc, argv, - "D:C:c:Xd:f:vVlLR:Sth" + "D:C:c:xXd:f:vVlLR:StTh" #ifdef DEBUG_SIGSTOP "Z:" #endif @@ -4597,6 +4866,12 @@ int REALMAIN(int argc, char *argv[]) case 'X': ++one_process; /* Weird debugging mode. */ break; +#ifdef TPF + case 'x': + os_tpf_child(&input_parms); + set_signals(); + break; +#endif #ifdef DEBUG_SIGSTOP case 'Z': raise_sigstop_flags = atoi(optarg); @@ -4615,7 +4890,12 @@ int REALMAIN(int argc, char *argv[]) ap_dump_settings = 1; break; case 't': - configtestonly = 1; + ap_configtestonly = 1; + ap_docrootcheck = 1; + break; + case 'T': + ap_configtestonly = 1; + ap_docrootcheck = 0; break; case 'h': usage(argv[0]); @@ -4623,12 +4903,18 @@ int REALMAIN(int argc, char *argv[]) usage(argv[0]); } } -#endif /* TPF */ +#ifdef EAPI + ap_init_alloc_shared(TRUE); +#endif ap_suexec_enabled = init_suexec(); server_conf = ap_read_config(pconf, ptrans, ap_server_confname); - if (configtestonly) { +#ifdef EAPI + ap_init_alloc_shared(FALSE); +#endif + + if (ap_configtestonly) { fprintf(stderr, "Syntax OK\n"); exit(0); } @@ -4638,13 +4924,40 @@ int REALMAIN(int argc, char *argv[]) child_timeouts = !ap_standalone || one_process; +#ifndef TPF if (ap_standalone) { - ap_open_logs(server_conf, pconf); + ap_open_logs(server_conf, plog); ap_set_version(); ap_init_modules(pconf, server_conf); version_locked++; STANDALONE_MAIN(argc, argv); } +#else + if (ap_standalone) { + if(!tpf_child) { + memcpy(tpf_server_name, input_parms.inetd_server.servname, INETD_SERVNAME_LENGTH); + tpf_server_name[INETD_SERVNAME_LENGTH+1] = '\0'; + ap_open_logs(server_conf, pconf); + } + ap_set_version(); + ap_init_modules(pconf, server_conf); + version_locked++; + if(tpf_child) { + copy_listeners(pconf); + reset_tpf_listeners(&input_parms); + server_conf->error_log = NULL; +#ifdef SCOREBOARD_FILE + scoreboard_fd = input_parms.scoreboard_fd; + ap_scoreboard_image = &_scoreboard_image; +#else /* must be USE_TPF_SCOREBOARD or USE_SHMGET_SCOREBOARD */ + ap_scoreboard_image = (scoreboard *)input_parms.scoreboard_heap; +#endif + child_main(input_parms.slot); + } + else + STANDALONE_MAIN(argc, argv); + } +#endif else { conn_rec *conn; request_rec *r; @@ -4656,7 +4969,7 @@ int REALMAIN(int argc, char *argv[]) /* Yes this is called twice. */ ap_init_modules(pconf, server_conf); version_locked++; - ap_open_logs(server_conf, pconf); + ap_open_logs(server_conf, plog); ap_init_modules(pconf, server_conf); set_group_privs(); @@ -4667,7 +4980,7 @@ int REALMAIN(int argc, char *argv[]) if (setuid(ap_user_id) == -1) { GETUSERMODE(); ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf, - "setuid: unable to change uid"); + "setuid: unable to change to uid: %d", ap_user_id); exit(1); } GETUSERMODE(); @@ -4676,7 +4989,8 @@ int REALMAIN(int argc, char *argv[]) /* Only try to switch if we're running as root */ if (!geteuid() && setuid(ap_user_id) == -1) { ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf, - "setuid: unable to change uid"); + "setuid: unable to change to uid: %ld", + (long) ap_user_id); exit(1); } #endif @@ -4685,15 +4999,12 @@ int REALMAIN(int argc, char *argv[]) } #ifdef TPF - signal(SIGALRM, alrm_handler); - ecbptr()->ebrout = PRIMECRAS; -#endif /* TPF */ - -#ifdef TPF /* TPF only passes the incoming socket number from the internet daemon in ebw000 */ sock_in = * (int*)(&(ecbptr()->ebw000)); sock_out = * (int*)(&(ecbptr()->ebw000)); +/* TPF also needs a signal set for alarm in inetd mode */ + signal(SIGALRM, alrm_handler); #elif defined(MPE) /* HP MPE 5.5 inetd only passes the incoming socket as stdin (fd 0), whereas HPUX inetd passes the incoming socket as stdin (fd 0) and stdout (fd 1). @@ -4739,6 +5050,10 @@ int REALMAIN(int argc, char *argv[]) ap_destroy_pool(r->pool); } +#ifdef EAPI + ap_call_close_connection_hook(conn); +#endif /* EAPI */ + ap_bclose(cio); } exit(0); @@ -4863,6 +5178,9 @@ void add_job(int sock) /* TODO: If too many jobs in queue, sleep, check for problems */ ap_acquire_mutex(allowed_globals.jobmutex); new_job = (joblist *) malloc(sizeof(joblist)); + if (new_job == NULL) { + fprintf(stderr, "Ouch! Out of memory in add_job()!\n"); + } new_job->next = NULL; new_job->sock = sock; if (allowed_globals.jobtail != NULL) @@ -4955,8 +5273,7 @@ static void child_sub_main(int child_num) (void) ap_update_child_status(child_num, SERVER_READY, (request_rec *) NULL); /* - * Setup the jump buffers so that we can return here after - * a signal or a timeout (yeah, I know, same thing). + * Setup the jump buffers so that we can return here after a timeout. */ #if defined(USE_LONGJMP) setjmp(jmpbuffer); @@ -4975,16 +5292,14 @@ static void child_sub_main(int child_num) * (Re)initialize this child to a pre-connection state. */ - ap_set_callback_and_alarm(NULL, 0); /* Cancel any outstanding alarms. */ - timeout_req = NULL; /* No request in progress */ + ap_set_callback_and_alarm(NULL, 0); /* Cancel any outstanding alarms */ + timeout_req = NULL; /* No request in progress */ current_conn = NULL; -#ifdef SIGPIPE - signal(SIGPIPE, timeout); -#endif ap_clear_pool(ptrans); - (void) ap_update_child_status(child_num, SERVER_READY, (request_rec *) NULL); + (void) ap_update_child_status(child_num, SERVER_READY, + (request_rec *) NULL); /* Get job from the job list. This will block until a job is ready. * If -1 is returned then the main thread wants us to exit. @@ -5067,6 +5382,9 @@ static void child_sub_main(int child_num) ap_kill_cleanups_for_socket(ptrans, csd); #ifdef NO_LINGCLOSE +#ifdef EAPI + ap_call_close_connection_hook(current_conn); +#endif /* EAPI */ ap_bclose(conn_io); /* just close it */ #else if (r && r->connection @@ -5077,6 +5395,9 @@ static void child_sub_main(int child_num) lingering_close(r); } else { +#ifdef EAPI + ap_call_close_connection_hook(current_conn); +#endif /* EAPI */ ap_bsetflag(conn_io, B_EOUT, 1); ap_bclose(conn_io); } @@ -5118,7 +5439,7 @@ void cleanup_thread(thread **handles, int *thread_cnt, int thread_to_clean) * we are restricted to a maximum of 64 threads. This is a simplistic * routine that will increase this size. */ -DWORD wait_for_many_objects(DWORD nCount, CONST HANDLE *lpHandles, +static DWORD wait_for_many_objects(DWORD nCount, CONST HANDLE *lpHandles, DWORD dwSeconds) { time_t tStopTime; @@ -5182,6 +5503,71 @@ void setup_signal_names(char *prefix) APD2("signal prefix %s", signal_name_prefix); } +static void setup_inherited_listeners(pool *p) +{ + HANDLE pipe; + listen_rec *lr; + int fd; + WSAPROTOCOL_INFO WSAProtocolInfo; + DWORD BytesRead; + + /* Open the pipe to the parent process to receive the inherited socket + * data. The sockets have been set to listening in the parent process. + */ + pipe = GetStdHandle(STD_INPUT_HANDLE); + + /* Setup the listeners */ + listenmaxfd = -1; + FD_ZERO(&listenfds); + lr = ap_listeners; + + FD_ZERO(&listenfds); + + for (;;) { + fd = find_listener(lr); + if (fd < 0) { + if (!ReadFile(pipe, + &WSAProtocolInfo, sizeof(WSAPROTOCOL_INFO), + &BytesRead, + (LPOVERLAPPED) NULL)){ + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR|APLOG_CRIT, server_conf, + "setup_inherited_listeners: Unable to read socket data from parent"); + exit(1); + } + fd = WSASocket(FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + &WSAProtocolInfo, + 0, + 0); + if (fd == INVALID_SOCKET) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR|APLOG_CRIT, server_conf, + "setup_inherited_listeners: WSASocket failed to get inherit the socket."); + exit(1); + } + APD2("setup_inherited_listeners: WSASocket() returned socket %d", fd); + } + else { + ap_note_cleanups_for_socket(p, fd); + } + if (fd >= 0) { + FD_SET(fd, &listenfds); + if (fd > listenmaxfd) + listenmaxfd = fd; + } + lr->fd = fd; + if (lr->next == NULL) + break; + lr = lr->next; + } + /* turn the list into a ring */ + lr->next = ap_listeners; + head_listener = ap_listeners; + close_unused_listeners(); + CloseHandle(pipe); + return; +} + /* * worker_main() is main loop for the child process. The loop in * this function becomes the controlling thread for the actually working @@ -5203,8 +5589,6 @@ void worker_main(void) int i; struct timeval tv; int wait_time = 1; - int start_exit = 0; - int start_mutex_released = 0; int max_jobs_per_exe; int max_jobs_after_exit_request; HANDLE hObjects[2]; @@ -5249,7 +5633,7 @@ void worker_main(void) rv = WaitForMultipleObjects(2, hObjects, FALSE, INFINITE); if (rv == WAIT_FAILED) { ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_WIN32ERROR, server_conf, - "Waiting for start_mutex or exit_event -- process will exit"); + "Waiting for start_mutex or exit_event -- process will exit"); ap_destroy_pool(pchild); cleanup_scoreboard(); @@ -5262,8 +5646,13 @@ void worker_main(void) exit(0); } /* start_mutex obtained, continue into the select() loop */ + if (one_process) { + setup_listeners(pconf); + } else { + /* Get listeners from the parent process */ + setup_inherited_listeners(pconf); + } - setup_listeners(pconf); if (listenmaxfd == -1) { /* Help, no sockets were made, better log something and exit */ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, NULL, @@ -5306,43 +5695,20 @@ void worker_main(void) } while (1) { -#if SEVERELY_VERBOSE - APD4("child PID %d: thread_main total_jobs=%d start_exit=%d", - my_pid, total_jobs, start_exit); -#endif - if ((max_jobs_per_exe && (total_jobs > max_jobs_per_exe) && !start_exit)) { - start_exit = 1; - wait_time = 1; - ap_release_mutex(start_mutex); - start_mutex_released = 1; - APD2("process PID %d: start mutex released\n", my_pid); - } - if (!start_exit) { - rv = WaitForSingleObject(exit_event, 0); - ap_assert((rv == WAIT_TIMEOUT) || (rv == WAIT_OBJECT_0)); - if (rv == WAIT_OBJECT_0) { - APD1("child: exit event signalled, exiting"); - start_exit = 1; - /* Lets not break yet - we may have threads to clean up */ - /* break;*/ - } - rv = wait_for_many_objects(nthreads, child_handles, 0); - ap_assert(rv != WAIT_FAILED); - if (rv != WAIT_TIMEOUT) { - rv = rv - WAIT_OBJECT_0; - ap_assert((rv >= 0) && (rv < nthreads)); - cleanup_thread(child_handles, &nthreads, rv); - break; - } + if (max_jobs_per_exe && (total_jobs > max_jobs_per_exe)) { + /* MaxRequestsPerChild hit... + */ + break; } + /* Always check for the exit event being signaled. + */ + rv = WaitForSingleObject(exit_event, 0); + ap_assert((rv == WAIT_TIMEOUT) || (rv == WAIT_OBJECT_0)); + if (rv == WAIT_OBJECT_0) { + APD1("child: exit event signalled, exiting"); + break; + } -#if 0 - /* Um, this made us exit before all the connections in our - * listen queue were dealt with. - */ - if (start_exit && max_jobs_after_exit_request && (count_down-- < 0)) - break; -#endif tv.tv_sec = wait_time; tv.tv_usec = 0; @@ -5361,7 +5727,7 @@ void worker_main(void) if (errno != EINTR) { /* A "real" error occurred, log it and increment the count of * select errors. This count is used to ensure we don't go into - * a busy loop of continuour errors. + * a busy loop of continuous errors. */ ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "select: (listen)"); count_select_errors++; @@ -5375,10 +5741,7 @@ void worker_main(void) } count_select_errors = 0; /* reset count of errors */ if (srv == 0) { - if (start_exit) - break; - else - continue; + continue; } { @@ -5421,9 +5784,7 @@ void worker_main(void) /* Get ready to shutdown and exit */ allowed_globals.exit_now = 1; - if (!start_mutex_released) { - ap_release_mutex(start_mutex); - } + ap_release_mutex(start_mutex); #ifdef UNGRACEFUL_RESTART SetEvent(allowed_globals.thread_exit_event); @@ -5485,59 +5846,6 @@ void worker_main(void) * returned the error will already have been logged by ap_log_error(). */ -int create_event_and_spawn(int argc, char **argv, event **ev, int *child_num, char *prefix) -{ - char buf[40], mod[200]; - int i, rv; - char **pass_argv = (char **) alloca(sizeof(char *) * (argc + 3)); - - /* We need an event to tell the child process to kill itself when - * the parent is doing a shutdown/restart. This will be named - * apPID_CN where PID is the parent Apache process PID and - * N is a unique child serial number. prefix contains - * the "apPID" part. The child will get the name of this - * event as its -Z command line argument. - */ - ap_snprintf(buf, sizeof(buf), "%s_C%d", prefix, ++(*child_num)); - _flushall(); - *ev = CreateEvent(NULL, TRUE, FALSE, buf); - if (!*ev) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, - "could not create event for child process"); - return -1; - } - APD2("create_event_and_spawn(): created process kill event %s", buf); - - pass_argv[0] = argv[0]; - pass_argv[1] = "-Z"; - pass_argv[2] = buf; - for (i = 1; i < argc; i++) { - pass_argv[i + 2] = argv[i]; - } - pass_argv[argc + 2] = NULL; - - rv = GetModuleFileName(NULL, mod, sizeof(mod)); - if (rv == sizeof(mod)) { - /* mod[] was not big enough for our pathname */ - ap_log_error(APLOG_MARK, APLOG_ERR, NULL, - "Internal error: path to Apache process too long"); - return -1; - } - if (rv == 0) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, - "GetModuleFileName() for current process"); - return -1; - } - rv = spawnv(_P_NOWAIT, mod, pass_argv); - if (rv == -1) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, - "spawn of child process %s failed", mod); - return -1; - } - - return rv; -} - /********************************************************************** * master_main - this is the parent (main) process. We create a * child process to do the work, then sit around waiting for either @@ -5549,7 +5857,7 @@ int create_event_and_spawn(int argc, char **argv, event **ev, int *child_num, ch #define MAX_PROCESSES 50 /* must be < MAX_WAIT_OBJECTS-1 */ -void cleanup_process(HANDLE *handles, HANDLE *events, int position, int *processes) +static void cleanup_process(HANDLE *handles, HANDLE *events, int position, int *processes) { int i; int handle = 0; @@ -5568,31 +5876,192 @@ void cleanup_process(HANDLE *handles, HANDLE *events, int position, int *process APD4("cleanup_processes: removed child in slot %d handle %d, max=%d", position, handle, *processes); } -int create_process(HANDLE *handles, HANDLE *events, int *processes, int *child_num, char *kill_event_name, int argc, char **argv) +static int create_process(pool *p, HANDLE *handles, HANDLE *events, + int *processes, int *child_num, char *kill_event_name, int argc, char **argv) { - int i = *processes; + + int rv, i; HANDLE kill_event; - int child_handle; + char buf[1024]; + char exit_event_name[40]; /* apPID_C# */ + char *pCommand; - child_handle = create_event_and_spawn(argc, argv, &kill_event, child_num, kill_event_name); - if (child_handle <= 0) { - return -1; + STARTUPINFO si; /* Filled in prior to call to CreateProcess */ + PROCESS_INFORMATION pi; /* filled in on call to CreateProces */ + LPWSAPROTOCOL_INFO lpWSAProtocolInfo; + listen_rec *lr; + DWORD BytesWritten; + HANDLE hPipeRead = NULL; + HANDLE hPipeWrite = NULL; + SECURITY_ATTRIBUTES sa = {0}; + + sa.nLength = sizeof(sa); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + /* Build the command line. Should look something like this: + * C:/apache/bin/apache.exe -Z exit_event -f ap_server_confname + * First, get the path to the executable... + */ + rv = GetModuleFileName(NULL, buf, sizeof(buf)); + if (rv == sizeof(buf)) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, server_conf, + "Parent: Path to Apache process too long"); + return -1; + } else if (rv == 0) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, server_conf, + "Parent: GetModuleFileName() returned NULL for current process."); + return -1; } - handles[i] = (HANDLE)child_handle; - events[i] = kill_event; - (*processes)++; + + /* Create the exit event (apPID_C#). Parent signals this event to tell the + * child to exit + */ + ap_snprintf(exit_event_name, sizeof(exit_event_name), "%s_C%d", kill_event_name, ++(*child_num)); + kill_event = CreateEvent(NULL, TRUE, FALSE, exit_event_name); + if (!kill_event) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, server_conf, + "Parent: Could not create exit event for child process"); + return -1; + } + + pCommand = ap_psprintf(p, "\"%s\" -Z %s -f \"%s\"", buf, exit_event_name, ap_server_confname); - APD4("create_processes: created child in slot %d handle %d, max=%d", - (*processes)-1, handles[(*processes)-1], *processes); + for (i = 1; i < argc; i++) { + pCommand = ap_pstrcat(p, pCommand, " ", argv[i], NULL); + } + + /* Create a pipe to send socket info to the child */ + if (!CreatePipe(&hPipeRead, &hPipeWrite, &sa, 0)) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, server_conf, + "Parent: Unable to create pipe to child process.\n"); + return -1; + } + + /* Give the read in of teh pipe (hPipeRead) to the child as stdin. The + * parent will write the socket data to the child on this pipe. + */ + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + si.wShowWindow = SW_HIDE; + si.hStdInput = hPipeRead; + + if (!CreateProcess(NULL, pCommand, NULL, NULL, + TRUE, /* Inherit handles */ + 0, /* Creation flags */ + NULL, NULL, + &si, &pi)) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, server_conf, + "Parent: Not able to create the child process."); + /* + * We must close the handles to the new process and its main thread + * to prevent handle and memory leaks. + */ + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + + return -1; + } + else { + ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, server_conf, + "Parent: Created child process %d", pi.dwProcessId); + + /* Assume the child process lives. Update the process and event tables */ + handles[*processes] = pi.hProcess; + events[*processes] = kill_event; + (*processes)++; + + /* We never store the thread's handle, so close it now. */ + CloseHandle(pi.hThread); + + /* Run the chain of open sockets. For each socket, duplicate it + * for the target process then send the WSAPROTOCOL_INFO + * (returned by dup socket) to the child */ + lr = ap_listeners; + while (lr != NULL) { + lpWSAProtocolInfo = ap_pcalloc(p, sizeof(WSAPROTOCOL_INFO)); + ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, server_conf, + "Parent: Duplicating socket %d and sending it to child process %d", lr->fd, pi.dwProcessId); + if (WSADuplicateSocket(lr->fd, + pi.dwProcessId, + lpWSAProtocolInfo) == SOCKET_ERROR) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, server_conf, + "Parent: WSADuplicateSocket failed for socket %d.", lr->fd ); + return -1; + } + + if (!WriteFile(hPipeWrite, lpWSAProtocolInfo, (DWORD) sizeof(WSAPROTOCOL_INFO), + &BytesWritten, + (LPOVERLAPPED) NULL)) { + ap_log_error(APLOG_MARK, APLOG_WIN32ERROR | APLOG_CRIT, server_conf, + "Parent: Unable to write duplicated socket %d to the child.", lr->fd ); + return -1; + } + + lr = lr->next; + if (lr == ap_listeners) + break; + } + } + CloseHandle(hPipeRead); + CloseHandle(hPipeWrite); return 0; } +/* To share the semaphores with other processes, we need a NULL ACL + * Code from MS KB Q106387 + */ + +static PSECURITY_ATTRIBUTES GetNullACL() +{ + PSECURITY_DESCRIPTOR pSD; + PSECURITY_ATTRIBUTES sa; + + sa = (PSECURITY_ATTRIBUTES) LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES)); + pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, + SECURITY_DESCRIPTOR_MIN_LENGTH); + if (pSD == NULL || sa == NULL) { + return NULL; + } + /* + * We can safely use GetLastError() here without presetting it; + * {Initialize,Set}SecurityDescriptor() have been verified as clearing it + * on successful completion. + */ + if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) + || GetLastError()) { + LocalFree( pSD ); + LocalFree( sa ); + return NULL; + } + if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE) + || GetLastError()) { + LocalFree( pSD ); + LocalFree( sa ); + return NULL; + } + sa->nLength = sizeof(sa); + sa->lpSecurityDescriptor = pSD; + sa->bInheritHandle = TRUE; + return sa; +} + + +static void CleanNullACL( void *sa ) { + if( sa ) { + LocalFree( ((PSECURITY_ATTRIBUTES)sa)->lpSecurityDescriptor); + LocalFree( sa ); + } +} + int master_main(int argc, char **argv) { + /* returns NULL if invalid (Win95?) */ + PSECURITY_ATTRIBUTES sa = GetNullACL(); int nchild = ap_daemons_to_start; - event **ev; - int *child; int child_num = 0; int rv, cld; char signal_prefix_string[100]; @@ -5615,163 +6084,141 @@ int master_main(int argc, char **argv) "ap%d", getpid()); setup_signal_names(signal_prefix_string); - signal_shutdown_event = CreateEvent(NULL, TRUE, FALSE, signal_shutdown_name); + /* Create shutdown event, apPID_shutdown, where PID is the parent + * Apache process ID. Shutdown is signaled by 'apache -k shutdown'. + */ + signal_shutdown_event = CreateEvent(sa, TRUE, FALSE, signal_shutdown_name); if (!signal_shutdown_event) { ap_log_error(APLOG_MARK, APLOG_EMERG|APLOG_WIN32ERROR, server_conf, - "Cannot create shutdown event %s", signal_shutdown_name); + "master_main: Cannot create shutdown event %s", signal_shutdown_name); + CleanNullACL((void *)sa); exit(1); } - APD2("master_main: created event %s", signal_shutdown_name); - signal_restart_event = CreateEvent(NULL, TRUE, FALSE, signal_restart_name); + + /* Create restart event, apPID_restart, where PID is the parent + * Apache process ID. Restart is signaled by 'apache -k restart'. + */ + signal_restart_event = CreateEvent(sa, TRUE, FALSE, signal_restart_name); if (!signal_restart_event) { CloseHandle(signal_shutdown_event); ap_log_error(APLOG_MARK, APLOG_EMERG|APLOG_WIN32ERROR, server_conf, - "Cannot create restart event %s", signal_restart_name); + "master_main: Cannot create restart event %s", signal_restart_name); + CleanNullACL((void *)sa); exit(1); } - APD2("master_main: created event %s", signal_restart_name); + CleanNullACL((void *)sa); + /* Create the start mutex, apPID, where PID is the parent Apache process ID. + * Ths start mutex is used during a restart to prevent more than one + * child process from entering the accept loop at once. + */ start_mutex = ap_create_mutex(signal_prefix_string); - ev = (event **) alloca(sizeof(event *) * nchild); - child = (int *) alloca(sizeof(int) * (nchild+1)); - - while (processes_to_create--) { - service_set_status(SERVICE_START_PENDING); - if (create_process(process_handles, process_kill_events, - ¤t_live_processes, &child_num, signal_prefix_string, argc, argv) < 0) { - goto die_now; - } - } - - service_set_status(SERVICE_RUNNING); - restart_pending = shutdown_pending = 0; do { /* restart-pending */ if (!is_graceful) { ap_restart_time = time(NULL); } + copy_listeners(pconf); ap_clear_pool(pconf); pparent = ap_make_sub_pool(pconf); server_conf = ap_read_config(pconf, pparent, ap_server_confname); - ap_open_logs(server_conf, pconf); + setup_listeners(pconf); + ap_clear_pool(plog); + ap_open_logs(server_conf, plog); ap_set_version(); ap_init_modules(pconf, server_conf); version_locked++; - + service_set_status(SERVICE_START_PENDING); + /* Create child processes */ + while (processes_to_create--) { + if (create_process(pconf, process_handles, process_kill_events, + ¤t_live_processes, &child_num, signal_prefix_string, argc, argv) < 0) { + ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, + "master_main: create child process failed. Exiting."); + goto die_now; + } + } + service_set_status(SERVICE_RUNNING); restart_pending = shutdown_pending = 0; - /* Wait for either a child process to die, or for the stop_event - * to be signalled by the service manager or rpc server */ - while (1) { - /* Next line will block forever until either a child dies, or we - * get signalled on the "apache-signal" event (e.g. if the user is - * requesting a shutdown/restart) - */ - if (current_live_processes == 0) { - /* Shouldn't happen, but better safe than sorry */ - ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_NOERRNO, server_conf, - "master_main: no child processes alive! creating one"); - if (create_process(process_handles, process_kill_events, - ¤t_live_processes, &child_num, signal_prefix_string, - argc, argv) < 0) { - goto die_now; - } - if (processes_to_create) { - processes_to_create--; - } - } - process_handles[current_live_processes] = signal_shutdown_event; - process_handles[current_live_processes+1] = signal_restart_event; - rv = WaitForMultipleObjects(current_live_processes+2, (HANDLE *)process_handles, - FALSE, INFINITE); - if (rv == WAIT_FAILED) { - /* Something serious is wrong */ - ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_WIN32ERROR, server_conf, - "WaitForMultipeObjects on process handles and apache-signal -- doing shutdown"); - shutdown_pending = 1; - break; - } - if (rv == WAIT_TIMEOUT) { - /* Hey, this cannot happen */ - ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, - "WaitForMultipeObjects with INFINITE wait exited with WAIT_TIMEOUT"); - shutdown_pending = 1; - } + /* Wait for either the shutdown or restart events to be signaled */ + process_handles[current_live_processes] = signal_shutdown_event; + process_handles[current_live_processes+1] = signal_restart_event; + rv = WaitForMultipleObjects(current_live_processes+2, (HANDLE *)process_handles, + FALSE, INFINITE); + if (rv == WAIT_FAILED) { + /* Something serious is wrong */ + ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_WIN32ERROR, server_conf, + "master_main: : WaitForMultipeObjects on process handles and apache-signal -- doing shutdown"); + shutdown_pending = 1; + break; + } + if (rv == WAIT_TIMEOUT) { + /* Hey, this cannot happen */ + ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, + "master_main: WaitForMultipeObjects with INFINITE wait exited with WAIT_TIMEOUT"); + shutdown_pending = 1; + } - cld = rv - WAIT_OBJECT_0; - APD4("main process: wait finished, cld=%d handle %d (max=%d)", cld, process_handles[cld], current_live_processes); - if (cld == current_live_processes) { - /* shutdown event signalled, we should exit now */ - if (ResetEvent(signal_shutdown_event) == 0) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, server_conf, - "ResetEvent(signal_shutdown_event)"); - /* Continue -- since we are doing a shutdown anyway */ - } - shutdown_pending = 1; - APD3("main process: stop_event signalled: shutdown_pending=%d, restart_pending=%d", - shutdown_pending, restart_pending); - break; + cld = rv - WAIT_OBJECT_0; + APD4("main process: wait finished, cld=%d handle %d (max=%d)", cld, process_handles[cld], current_live_processes); + if (cld == current_live_processes) { + /* apPID_shutdown event signalled, we should exit now */ + shutdown_pending = 1; + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf, + "master_main: Shutdown event signaled. Shutting the server down."); + if (ResetEvent(signal_shutdown_event) == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, server_conf, + "ResetEvent(signal_shutdown_event)"); + } + /* Signal each child processes to die */ + for (i = 0; i < current_live_processes; i++) { + APD3("master_main: signalling child %d, handle %d to die", i, process_handles[i]); + if (SetEvent(process_kill_events[i]) == 0) + ap_log_error(APLOG_MARK,APLOG_ERR|APLOG_WIN32ERROR, server_conf, + "master_main: SetEvent for child process in slot #%d failed", i); } - if (cld == current_live_processes+1) { - /* restart event signalled, we should exit now */ - if (ResetEvent(signal_restart_event) == 0) { + break; + } else if (cld == current_live_processes+1) { + /* apPID_restart event signalled, restart the child process */ + int children_to_kill = current_live_processes; + restart_pending = 1; + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf, + "master_main: Restart event signaled. Doing a graceful restart."); + if (ResetEvent(signal_restart_event) == 0) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, server_conf, + "master_main: ResetEvent(signal_restart_event) failed."); + } + /* Signal each child process to die */ + for (i = 0; i < children_to_kill; i++) { + APD3("master_main: signalling child #%d handle %d to die", i, process_handles[i]); + if (SetEvent(process_kill_events[i]) == 0) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, server_conf, - "ResetEvent(signal_restart_event)"); - /* Continue -- hopefully the restart will fix the problem */ - } - restart_pending = 1; - APD3("main process: stop_event signalled: shutdown_pending=%d, restart_pending=%d", - shutdown_pending, restart_pending); - break; + "master_main: SetEvent for child process in slot #%d failed", i); + /* Remove the process (and event) from the process table */ + cleanup_process(process_handles, process_kill_events, i, ¤t_live_processes); } + processes_to_create = nchild; + ++ap_my_generation; + continue; + } else { + /* A child process must have exited because of MaxRequestPerChild being hit + * or a fatal error condition (seg fault, etc.). Remove the dead process + * from the process_handles and process_kill_events table and create a new + * child process. + */ + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf, + "master_main: Child processed exited (due to MaxRequestsPerChild?). Restarting the child process."); ap_assert(cld < current_live_processes); cleanup_process(process_handles, process_kill_events, cld, ¤t_live_processes); APD2("main_process: child in slot %d died", rv); - if (processes_to_create) { - create_process(process_handles, process_kill_events, ¤t_live_processes, - &child_num, signal_prefix_string, argc, argv); - processes_to_create--; - } - } - if (!shutdown_pending && !restart_pending) { - ap_log_error(APLOG_MARK,APLOG_CRIT|APLOG_NOERRNO, server_conf, - "master_main: no shutdown or restart variables set -- doing shutdown"); - shutdown_pending = 1; - } - if (shutdown_pending) { - /* tell all child processes to die */ - for (i = 0; i < current_live_processes; i++) { - APD3("main process: signalling child #%d handle %d to die", i, process_handles[i]); - if (SetEvent(process_kill_events[i]) == 0) - ap_log_error(APLOG_MARK,APLOG_WIN32ERROR, server_conf, - "SetEvent for child process in slot #%d", i); - } - break; + processes_to_create = 1; + continue; } - if (restart_pending) { - int children_to_kill = current_live_processes; - APD1("--- Doing graceful restart ---"); - - processes_to_create = nchild; - for (i = 0; i < nchild; ++i) { - if (current_live_processes >= MAX_PROCESSES) - break; - create_process(process_handles, process_kill_events, ¤t_live_processes, - &child_num, signal_prefix_string, argc, argv); - processes_to_create--; - } - for (i = 0; i < children_to_kill; i++) { - APD3("main process: signalling child #%d handle %d to die", i, process_handles[i]); - if (SetEvent(process_kill_events[i]) == 0) - ap_log_error(APLOG_MARK,APLOG_WIN32ERROR, server_conf, - "SetEvent for child process in slot #%d", i); - } - } - ++ap_my_generation; - } while (restart_pending); + } while (1); /* If we dropped out of the loop we definitly want to die completely. We need to * make sure we wait for all the child process to exit first. @@ -5829,7 +6276,7 @@ die_now: * either "shutdown" or "restart" */ -void send_signal(pool *p, char *signal) +int send_signal(pool *p, char *signal) { char prefix[20]; FILE *fp; @@ -5842,7 +6289,7 @@ void send_signal(pool *p, char *signal) fp = fopen(fname, "r"); if (!fp) { printf("Cannot read apache PID file %s\n", fname); - return; + return FALSE; } prefix[0] = 'a'; prefix[1] = 'p'; @@ -5851,7 +6298,7 @@ void send_signal(pool *p, char *signal) if (nread == 0) { fclose(fp); printf("PID file %s was empty\n", fname); - return; + return FALSE; } fclose(fp); @@ -5867,11 +6314,38 @@ void send_signal(pool *p, char *signal) ap_start_shutdown(); else if (!strcasecmp(signal, "restart")) ap_start_restart(1); - else + else { printf("Unknown signal name \"%s\". Use either shutdown or restart.\n", signal); + return FALSE; + } + return TRUE; +} - return; +void post_parse_init() +{ + ap_set_version(); + ap_init_modules(pconf, server_conf); + ap_suexec_enabled = init_suexec(); + version_locked++; + ap_open_logs(server_conf, plog); + set_group_privs(); +} + +int service_init() +{ + common_init(); + + ap_cpystrn(ap_server_root, HTTPD_ROOT, sizeof(ap_server_root)); + if (ap_registry_get_service_conf(pconf, ap_server_confname, sizeof(ap_server_confname), + ap_server_argv0)) + return FALSE; + + ap_setup_prelinked_modules(); + server_conf = ap_read_config(pconf, ptrans, ap_server_confname); + ap_log_pid(pconf, ap_pid_fname); + post_parse_init(); + return TRUE; } #ifdef WIN32 @@ -5884,41 +6358,44 @@ int REALMAIN(int argc, char *argv[]) int c; int child = 0; char *cp; - int run_as_service = 1; + char *s; + char *service_name = NULL; int install = 0; - int configtestonly = 0; + int conf_specified = 0; char *signal_to_send = NULL; - char *s; - - common_init(); + char cwd[MAX_STRING_LEN]; - if ((s = strrchr(argv[0], '/')) != NULL) { - ap_server_argv0 = ++s; + /* Service application + * Configuration file in registry at: + * HKLM\System\CurrentControlSet\Services\[Svc name]\Parameters\ConfPath + */ + if (isProcessService()) { + service_main(master_main, argc, argv); + clean_parent_exit(0); + } + + /* Console application or a child process. */ + + if ((s = strrchr(argv[0], PATHSEPARATOR)) != NULL) { + ap_server_argv0 = ++s; } else { - ap_server_argv0 = argv[0]; + ap_server_argv0 = argv[0]; } - /* Get the serverroot from the registry, if it exists. This can be - * overridden by a command line -d argument. - */ - if (ap_registry_get_server_root(pconf, ap_server_root, sizeof(ap_server_root)) < 0) { - /* The error has already been logged. Actually it won't have been, - * because we haven't read the config files to find out where our - * error log is. But we can't just ignore the error since we might - * end up using totally the wrong server root. - */ - exit(1); - } + common_init(); + ap_setup_prelinked_modules(); - if (!*ap_server_root) { - ap_cpystrn(ap_server_root, HTTPD_ROOT, sizeof(ap_server_root)); + if(!GetCurrentDirectory(sizeof(cwd),cwd)) { + ap_log_error(APLOG_MARK,APLOG_WIN32ERROR, NULL, + "GetCurrentDirectory() failure"); + return -1; } - ap_cpystrn(ap_server_confname, SERVER_CONFIG_FILE, sizeof(ap_server_confname)); - ap_setup_prelinked_modules(); + ap_cpystrn(cwd, ap_os_canonical_filename(pcommands, cwd), sizeof(cwd)); + ap_cpystrn(ap_server_root, cwd, sizeof(ap_server_root)); - while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLZ:iusSthk:")) != -1) { + while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLZ:iusStThk:n:")) != -1) { char **new; switch (c) { case 'c': @@ -5945,15 +6422,20 @@ int REALMAIN(int argc, char *argv[]) ap_assert(start_mutex); child = 1; break; + case 'n': + service_name = ap_pstrdup(pcommands, optarg); + if (isValidService(optarg)) { + ap_registry_get_service_conf(pconf, ap_server_confname, sizeof(ap_server_confname), + optarg); + conf_specified = 1; + } + break; case 'i': install = 1; break; case 'u': install = -1; break; - case 's': - run_as_service = 0; - break; case 'S': ap_dump_settings = 1; break; @@ -5962,10 +6444,22 @@ int REALMAIN(int argc, char *argv[]) break; #endif /* WIN32 */ case 'd': - ap_cpystrn(ap_server_root, ap_os_canonical_filename(pconf, optarg), sizeof(ap_server_root)); + optarg = ap_os_canonical_filename(pcommands, optarg); + if (!ap_os_is_path_absolute(optarg)) { + optarg = ap_pstrcat(pcommands, cwd, optarg, NULL); + ap_getparents(optarg); + } + if (optarg[strlen(optarg)-1] != '/') + optarg = ap_pstrcat(pcommands, optarg, "/", NULL); + ap_cpystrn(ap_server_root, + optarg, + sizeof(ap_server_root)); break; case 'f': - ap_cpystrn(ap_server_confname, ap_os_canonical_filename(pconf, optarg), sizeof(ap_server_confname)); + ap_cpystrn(ap_server_confname, + ap_os_canonical_filename(pcommands, optarg), + sizeof(ap_server_confname)); + conf_specified = 1; break; case 'v': ap_set_version(); @@ -5986,40 +6480,100 @@ int REALMAIN(int argc, char *argv[]) ++one_process; /* Weird debugging mode. */ break; case 't': - configtestonly = 1; + ap_configtestonly = 1; + ap_docrootcheck = 1; + break; + case 'T': + ap_configtestonly = 1; + ap_docrootcheck = 0; break; case 'h': - usage(argv[0]); + usage(ap_server_argv0); case '?': - usage(argv[0]); - } + usage(ap_server_argv0); + } /* switch */ + } /* while */ + + /* ServerConfFile is found in this order: + * (1) -f or -n + * (2) [-d]/SERVER_CONFIG_FILE + * (3) ./SERVER_CONFIG_FILE + * (4) [Registry: HKLM\Software\[product]\ServerRoot]/SERVER_CONFIG_FILE + * (5) /HTTPD_ROOT/SERVER_CONFIG_FILE + */ + + if (!conf_specified) { + ap_cpystrn(ap_server_confname, SERVER_CONFIG_FILE, sizeof(ap_server_confname)); + if (access(ap_server_root_relative(pcommands, ap_server_confname), 0)) { + ap_registry_get_server_root(pconf, ap_server_root, sizeof(ap_server_root)); + if (!*ap_server_root) + ap_cpystrn(ap_server_root, HTTPD_ROOT, sizeof(ap_server_root)); + ap_cpystrn(ap_server_root, ap_os_canonical_filename(pcommands, ap_server_root), + sizeof(ap_server_root)); + } } - if (!child && run_as_service) { - service_cd(); +#ifdef EAPI + ap_init_alloc_shared(TRUE); +#endif + + if (!ap_os_is_path_absolute(ap_server_confname)) { + char *full_conf_path; + + full_conf_path = ap_pstrcat(pcommands, ap_server_root, "/", ap_server_confname, NULL); + full_conf_path = ap_os_canonical_filename(pcommands, full_conf_path); + ap_cpystrn(ap_server_confname, full_conf_path, sizeof(ap_server_confname)); + } + ap_getparents(ap_server_confname); + ap_no2slash(ap_server_confname); + +#ifdef WIN32 + if (install) { + if (!service_name) + service_name = ap_pstrdup(pconf, DEFAULTSERVICENAME); + if (install > 0) + InstallService(service_name, ap_server_root_relative(pcommands, ap_server_confname)); + else + RemoveService(service_name); + clean_parent_exit(0); + } + + if (service_name && signal_to_send) { + send_signal_to_service(service_name, signal_to_send); + clean_parent_exit(0); } + if (service_name && !conf_specified) { + printf("Unknown service: %s\n", service_name); + clean_parent_exit(0); + } +#endif server_conf = ap_read_config(pconf, ptrans, ap_server_confname); - if (configtestonly) { - fprintf(stderr, "Syntax OK\n"); - exit(0); +#ifdef EAPI + ap_init_alloc_shared(FALSE); +#endif + + if (ap_configtestonly) { + fprintf(stderr, "%s: Syntax OK\n", ap_server_root_relative(pcommands, ap_server_confname)); + clean_parent_exit(0); } - if (signal_to_send) { - send_signal(pconf, signal_to_send); - exit(0); + if (ap_dump_settings) { + clean_parent_exit(0); } - if (!child && !ap_dump_settings && !install) { - ap_log_pid(pconf, ap_pid_fname); + /* Treat -k start confpath as just -f confpath */ + if (signal_to_send && strcasecmp(signal_to_send, "start")) { + send_signal(pconf, signal_to_send); + clean_parent_exit(0); } - ap_set_version(); - ap_init_modules(pconf, server_conf); - ap_suexec_enabled = init_suexec(); - version_locked++; - ap_open_logs(server_conf, pconf); - set_group_privs(); + + if (!child && !ap_dump_settings) { + ap_log_pid(pconf, ap_pid_fname); + } + + post_parse_init(); #ifdef OS2 printf("%s running...\n", ap_get_server_version()); @@ -6029,7 +6583,6 @@ int REALMAIN(int argc, char *argv[]) printf("%s running...\n", ap_get_server_version()); } #endif - if (one_process && !exit_event) exit_event = create_event(0, 0, NULL); if (one_process && !start_mutex) @@ -6046,10 +6599,8 @@ int REALMAIN(int argc, char *argv[]) ap_destroy_mutex(start_mutex); destroy_event(exit_event); } - else { - service_main(master_main, argc, argv, - "Apache", install, run_as_service); - } + else + master_main(argc, argv); clean_parent_exit(0); return 0; /* purely to avoid a warning */ @@ -6078,6 +6629,18 @@ int main(int argc, char *argv[]) #endif /* ndef SHARED_CORE_TIESTATIC */ #else /* ndef SHARED_CORE_BOOTSTRAP */ +#ifdef OS2 +/* Shared core loader for OS/2 */ + +int ap_main(int argc, char *argv[]); /* Load time linked from libhttpd.dll */ + +int main(int argc, char *argv[]) +{ + return ap_main(argc, argv); +} + +#else + /* ** Standalone Bootstrap Program for Shared Core support ** @@ -6127,7 +6690,7 @@ int main(int argc, char *argv[], char *envp[]) * but only handle the -L option */ llp_dir = SHARED_CORE_DIR; - while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:th")) != -1) { + while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:tTh")) != -1) { switch (c) { case 'D': case 'C': @@ -6142,6 +6705,7 @@ int main(int argc, char *argv[], char *envp[]) case 'S': case 'Z': case 't': + case 'T': case 'h': case '?': break; @@ -6154,7 +6718,7 @@ int main(int argc, char *argv[], char *envp[]) /* * create path to SHARED_CORE_EXECUTABLE_PROGRAM */ - sprintf(prog, "%s/%s", llp_dir, SHARED_CORE_EXECUTABLE_PROGRAM); + ap_snprintf(prog, sizeof(prog), "%s/%s", llp_dir, SHARED_CORE_EXECUTABLE_PROGRAM); /* * adjust process environment therewith the Unix loader @@ -6171,15 +6735,18 @@ int main(int argc, char *argv[], char *envp[]) } if (llp_slot == NULL) { envpnew = (char **)malloc(sizeof(char *)*(i + 2)); + if (envpnew == NULL) { + fprintf(stderr, "Ouch! Out of memory generating envpnew!\n"); + } memcpy(envpnew, envp, sizeof(char *)*i); envp = envpnew; llp_slot = &envp[i++]; envp[i] = NULL; } if (llp_existing != NULL) - sprintf(llp_buf, "%s=%s:%s", VARNAME, llp_dir, llp_existing); + ap_snprintf(llp_buf, sizeof(llp_buf), "%s=%s:%s", VARNAME, llp_dir, llp_existing); else - sprintf(llp_buf, "%s=%s", VARNAME, llp_dir); + ap_snprintf(llp_buf, sizeof(llp_buf), "%s=%s", VARNAME, llp_dir); *llp_slot = strdup(llp_buf); /* @@ -6196,5 +6763,28 @@ int main(int argc, char *argv[], char *envp[]) return 0; } +#endif /* def OS2 */ #endif /* ndef SHARED_CORE_BOOTSTRAP */ +#ifndef SHARED_CORE_BOOTSTRAP +/* + * Force ap_validate_password() into the image so that modules like + * mod_auth can use it even if they're dynamically loaded. + */ +void suck_in_ap_validate_password(void); +void suck_in_ap_validate_password(void) +{ + ap_validate_password("a", "b"); +} +#endif + +/* force Expat to be linked into the server executable */ +#if defined(USE_EXPAT) && !defined(SHARED_CORE_BOOTSTRAP) +#include "xmlparse.h" +const XML_LChar *suck_in_expat(void); +const XML_LChar *suck_in_expat(void) +{ + return XML_ErrorString(XML_ERROR_NONE); +} +#endif /* USE_EXPAT */ + diff --git a/usr.sbin/httpd/src/main/http_protocol.c b/usr.sbin/httpd/src/main/http_protocol.c index 9c4f831748e..0869708f726 100644 --- a/usr.sbin/httpd/src/main/http_protocol.c +++ b/usr.sbin/httpd/src/main/http_protocol.c @@ -144,16 +144,18 @@ API_EXPORT(int) ap_set_byterange(request_rec *r) return 0; } - /* Check the If-Range header for Etag or Date */ - + /* Check the If-Range header for Etag or Date. + * Note that this check will return false (as required) if either + * of the two etags are weak. + */ if ((if_range = ap_table_get(r->headers_in, "If-Range"))) { if (if_range[0] == '"') { if (!(match = ap_table_get(r->headers_out, "Etag")) || - (strcasecmp(if_range, match) != 0)) + (strcmp(if_range, match) != 0)) return 0; } else if (!(match = ap_table_get(r->headers_out, "Last-Modified")) || - (strcasecmp(if_range, match) != 0)) + (strcmp(if_range, match) != 0)) return 0; } @@ -398,13 +400,14 @@ API_EXPORT(int) ap_meets_conditions(request_rec *r) mtime = (r->mtime != 0) ? r->mtime : time(NULL); /* If an If-Match request-header field was given - * AND if our ETag does not match any of the entity tags in that field - * AND the field value is not "*" (meaning match anything), then + * AND the field value is not "*" (meaning match anything) + * AND if our strong ETag does not match any entity tag in that field, * respond with a status of 412 (Precondition Failed). */ if ((if_match = ap_table_get(r->headers_in, "If-Match")) != NULL) { - if ((etag == NULL) || - ((if_match[0] != '*') && !ap_find_token(r->pool, if_match, etag))) { + if (if_match[0] != '*' && + (etag == NULL || etag[0] == 'W' || + !ap_find_list_item(r->pool, if_match, etag))) { return HTTP_PRECONDITION_FAILED; } } @@ -425,22 +428,38 @@ API_EXPORT(int) ap_meets_conditions(request_rec *r) } /* If an If-None-Match request-header field was given - * AND if our ETag matches any of the entity tags in that field - * OR if the field value is "*" (meaning match anything), then - * if the request method was GET or HEAD, the server SHOULD - * respond with a 304 (Not Modified) response. - * For all other request methods, the server MUST - * respond with a status of 412 (Precondition Failed). + * AND the field value is "*" (meaning match anything) + * OR our ETag matches any of the entity tags in that field, fail. + * + * If the request method was GET or HEAD, failure means the server + * SHOULD respond with a 304 (Not Modified) response. + * For all other request methods, failure means the server MUST + * respond with a status of 412 (Precondition Failed). + * + * GET or HEAD allow weak etag comparison, all other methods require + * strong comparison. We can only use weak if it's not a range request. */ if_nonematch = ap_table_get(r->headers_in, "If-None-Match"); if (if_nonematch != NULL) { - int rstatus; - - if ((if_nonematch[0] == '*') - || ((etag != NULL) && ap_find_token(r->pool, if_nonematch, etag))) { - rstatus = (r->method_number == M_GET) ? HTTP_NOT_MODIFIED - : HTTP_PRECONDITION_FAILED; - return rstatus; + if (r->method_number == M_GET) { + if (if_nonematch[0] == '*') + return HTTP_NOT_MODIFIED; + if (etag != NULL) { + if (ap_table_get(r->headers_in, "Range")) { + if (etag[0] != 'W' && + ap_find_list_item(r->pool, if_nonematch, etag)) { + return HTTP_NOT_MODIFIED; + } + } + else if (strstr(if_nonematch, etag)) { + return HTTP_NOT_MODIFIED; + } + } + } + else if (if_nonematch[0] == '*' || + (etag != NULL && + ap_find_list_item(r->pool, if_nonematch, etag))) { + return HTTP_PRECONDITION_FAILED; } } /* Else if a valid If-Modified-Since request-header field was given @@ -730,10 +749,6 @@ CORE_EXPORT(void) ap_parse_uri(request_rec *r, const char *uri) for (x = r->uri; (x = strchr(x, '\\')) != NULL; ) *x = '/'; -#ifndef WIN32 /* for OS/2 only: */ - /* Fix OS/2 HPFS filename case problem. */ - ap_str_tolower(r->uri); -#endif } #endif /* OS2 || WIN32 */ } @@ -772,6 +787,10 @@ static int read_request_line(request_rec *r) while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) { if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) { ap_bsetflag(conn->client, B_SAFEREAD, 0); + /* this is a hack to make sure that request time is set, + * it's not perfect, but it's better than nothing + */ + r->request_time = time(0); return 0; } } @@ -934,7 +953,6 @@ request_rec *ap_read_request(conn_rec *conn) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "request failed: URI too long"); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); ap_log_transaction(r); return r; } @@ -948,7 +966,6 @@ request_rec *ap_read_request(conn_rec *conn) ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, "request failed: error reading the headers"); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); ap_log_transaction(r); return r; } @@ -968,7 +985,6 @@ request_rec *ap_read_request(conn_rec *conn) r->header_only = 0; r->status = HTTP_BAD_REQUEST; ap_send_error_response(r, 0); - ap_bflush(r->connection->client); ap_log_transaction(r); return r; } @@ -1001,7 +1017,6 @@ request_rec *ap_read_request(conn_rec *conn) "client sent HTTP/1.1 request without hostname " "(see RFC2068 section 9, and 14.23): %s", r->uri); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); ap_log_transaction(r); return r; } @@ -1022,7 +1037,6 @@ request_rec *ap_read_request(conn_rec *conn) "client sent an unrecognized expectation value of " "Expect: %s", expect); ap_send_error_response(r, 0); - ap_bflush(r->connection->client); (void) ap_discard_request_body(r); ap_log_transaction(r); return r; @@ -1141,7 +1155,13 @@ API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw) return AUTH_REQUIRED; } - t = ap_uudecode(r->pool, auth_line); + /* CHARSET_EBCDIC Issue's here ?!? Compare with 32/9 instead + * as we are operating on an octed stream ? + */ + while (*auth_line== ' ' || *auth_line== '\t') + auth_line++; + + t = ap_pbase64decode(r->pool, auth_line); /* Note that this allocation has to be made from r->connection->pool * because it has the lifetime of the connection. The other allocations * are temporary and can be tossed away any time. @@ -1160,7 +1180,16 @@ API_EXPORT(int) ap_get_basic_auth_pw(request_rec *r, const char **pw) * and must be listed in order. */ -static char *status_lines[RESPONSE_CODES] = { +#ifdef UTS21 +/* The second const triggers an assembler bug on UTS 2.1. + * Another workaround is to move some code out of this file into another, + * but this is easier. Dave Dykstra, 3/31/99 + */ +static const char * status_lines[RESPONSE_CODES] = +#else +static const char * const status_lines[RESPONSE_CODES] = +#endif +{ "100 Continue", "101 Switching Protocols", "102 Processing", @@ -1258,8 +1287,7 @@ API_EXPORT(int) ap_index_of_response(int status) API_EXPORT_NONSTD(int) ap_send_header_field(request_rec *r, const char *fieldname, const char *fieldval) { - return (0 < ap_bvputs(r->connection->client, - fieldname, ": ", fieldval, "\015\012", NULL)); + return (0 < ap_rvputs(r, fieldname, ": ", fieldval, "\015\012", NULL)); } API_EXPORT(void) ap_basic_http_header(request_rec *r) @@ -1294,8 +1322,7 @@ API_EXPORT(void) ap_basic_http_header(request_rec *r) /* Output the HTTP/1.x Status-Line and the Date and Server fields */ - ap_bvputs(r->connection->client, - protocol, " ", r->status_line, "\015\012", NULL); + ap_rvputs(r, protocol, " ", r->status_line, "\015\012", NULL); ap_send_header_field(r, "Date", ap_gm_timestr_822(r->pool, r->request_time)); ap_send_header_field(r, "Server", ap_get_server_version()); @@ -1380,9 +1407,9 @@ API_EXPORT(int) ap_send_http_trace(request_rec *r) ap_rvputs(r, r->the_request, "\015\012", NULL); - ap_table_do((int (*) (void *, const char *, const char *)) ap_send_header_field, - (void *) r, r->headers_in, NULL); - ap_bputs("\015\012", r->connection->client); + ap_table_do((int (*) (void *, const char *, const char *)) + ap_send_header_field, (void *) r, r->headers_in, NULL); + ap_rputs("\015\012", r); ap_kill_timeout(r); return OK; @@ -1429,6 +1456,84 @@ static int use_range_x(request_rec *r) && strstr(ua, "MSIE 3"))); } +/* This routine is called by ap_table_do and merges all instances of + * the passed field values into a single array that will be further + * processed by some later routine. Originally intended to help split + * and recombine multiple Vary fields, though it is generic to any field + * consisting of comma/space-separated tokens. + */ +static int uniq_field_values(void *d, const char *key, const char *val) +{ + array_header *values; + char *start; + char *e; + char **strpp; + int i; + + values = (array_header *)d; + + e = ap_pstrdup(values->pool, val); + + do { + /* Find a non-empty fieldname */ + + while (*e == ',' || ap_isspace(*e)) { + ++e; + } + if (*e == '\0') { + break; + } + start = e; + while (*e != '\0' && *e != ',' && !ap_isspace(*e)) { + ++e; + } + if (*e != '\0') { + *e++ = '\0'; + } + + /* Now add it to values if it isn't already represented. + * Could be replaced by a ap_array_strcasecmp() if we had one. + */ + for (i = 0, strpp = (char **) values->elts; i < values->nelts; + ++i, ++strpp) { + if (*strpp && strcasecmp(*strpp, start) == 0) { + break; + } + } + if (i == values->nelts) { /* if not found */ + *(char **)ap_push_array(values) = start; + } + } while (*e != '\0'); + + return 1; +} + +/* + * Since some clients choke violently on multiple Vary fields, or + * Vary fields with duplicate tokens, combine any multiples and remove + * any duplicates. + */ +static void fixup_vary(request_rec *r) +{ + array_header *varies; + + varies = ap_make_array(r->pool, 5, sizeof(char *)); + + /* Extract all Vary fields from the headers_out, separate each into + * its comma-separated fieldname values, and then add them to varies + * if not already present in the array. + */ + ap_table_do((int (*)(void *, const char *, const char *))uniq_field_values, + (void *) varies, r->headers_out, "Vary", NULL); + + /* If we found any, replace old Vary fields with unique-ified value */ + + if (varies->nelts > 0) { + ap_table_setn(r->headers_out, "Vary", + ap_array_pstrcat(r->pool, varies, ',')); + } +} + API_EXPORT(void) ap_send_http_header(request_rec *r) { int i; @@ -1453,6 +1558,20 @@ API_EXPORT(void) ap_send_http_header(request_rec *r) r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out, r->headers_out); + /* + * Remove the 'Vary' header field if the client can't handle it. + * Since this will have nasty effects on HTTP/1.1 caches, force + * the response into HTTP/1.0 mode. + */ + if (ap_table_get(r->subprocess_env, "force-no-vary") != NULL) { + ap_table_unset(r->headers_out, "Vary"); + r->proto_num = HTTP_VERSION(1,0); + ap_table_set(r->subprocess_env, "force-response-1.0", "1"); + } + else { + fixup_vary(r); + } + ap_hard_timeout("send headers", r); ap_basic_http_header(r); @@ -1533,9 +1652,9 @@ API_EXPORT(void) ap_finalize_request_protocol(request_rec *r) ap_bsetflag(r->connection->client, B_CHUNK, 0); ap_soft_timeout("send ending chunk", r); - ap_bputs("0\015\012", r->connection->client); + ap_rputs("0\015\012", r); /* If we had footer "headers", we'd send them now */ - ap_bputs("\015\012", r->connection->client); + ap_rputs("\015\012", r); ap_kill_timeout(r); } } @@ -1644,10 +1763,9 @@ API_EXPORT(int) ap_should_client_block(request_rec *r) if (r->expecting_100 && r->proto_num >= HTTP_VERSION(1,1)) { /* sending 100 Continue interim response */ - ap_bvputs(r->connection->client, - SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012", - NULL); - ap_bflush(r->connection->client); + ap_rvputs(r, SERVER_PROTOCOL, " ", status_lines[0], "\015\012\015\012", + NULL); + ap_rflush(r); } return 1; @@ -1657,7 +1775,7 @@ static long get_chunk_size(char *b) { long chunksize = 0; - while (isxdigit(*b)) { + while (ap_isxdigit(*b)) { int xvalue = 0; if (*b >= '0' && *b <= '9') @@ -1735,7 +1853,7 @@ API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz) chunk_start = getline(buffer, bufsiz, r->connection->client, 0); if ((chunk_start <= 0) || (chunk_start >= (bufsiz - 1)) - || !isxdigit(*buffer)) { + || !ap_isxdigit(*buffer)) { r->connection->keepalive = -1; return -1; } @@ -1854,14 +1972,18 @@ API_EXPORT(int) ap_discard_request_body(request_rec *r) if ((rv = ap_setup_client_block(r, REQUEST_CHUNKED_PASS))) return rv; - /* If we are discarding the request body, then we must already know - * the final status code, therefore disable the sending of 100 continue. + /* In order to avoid sending 100 Continue when we already know the + * final response status, and yet not kill the connection if there is + * no request body to be read, we need to duplicate the test from + * ap_should_client_block() here negated rather than call it directly. */ - r->expecting_100 = 0; - - if (ap_should_client_block(r)) { + if ((r->read_length == 0) && (r->read_chunked || (r->remaining > 0))) { char dumpbuf[HUGE_STRING_LEN]; + if (r->expecting_100) { + r->connection->keepalive = -1; + return OK; + } ap_hard_timeout("reading request body", r); while ((rv = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN)) > 0) continue; @@ -1910,23 +2032,19 @@ API_EXPORT(long) ap_send_fd_length(FILE *f, request_rec *r, long length) while (n && !r->connection->aborted) { w = ap_bwrite(r->connection->client, &buf[o], n); if (w > 0) { - ap_reset_timeout(r); /* reset timeout after successful write */ - total_bytes_sent += w; + ap_reset_timeout(r); /* reset timeout after successful write */ + total_bytes_sent += w; n -= w; o += w; } else if (w < 0) { - if (r->connection->aborted) - break; - else if (errno == EAGAIN) - continue; - else { + if (!r->connection->aborted) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, "client stopped connection before send body completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); r->connection->aborted = 1; - break; } + break; } } } @@ -1956,9 +2074,11 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) /* Make fb unbuffered and non-blocking */ ap_bsetflag(fb, B_RD, 0); +#ifndef TPF ap_bnonblock(fb, B_RD); +#endif fd = ap_bfileno(fb, B_RD); -#ifndef WIN32 +#ifdef CHECK_FD_SETSIZE if (fd >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) " @@ -1999,10 +2119,15 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) break; if (n < 0 && errno != EAGAIN) break; + /* we need to block, so flush the output first */ - ap_bflush(r->connection->client); - if (r->connection->aborted) + if (ap_bflush(r->connection->client) < 0) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before send body completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; break; + } FD_SET(fd, &fds); /* * we don't care what select says, we might as well loop back @@ -2017,30 +2142,24 @@ API_EXPORT(long) ap_send_fb_length(BUFF *fb, request_rec *r, long length) if (n < 1 || r->connection->aborted) { break; } - o = 0; - total_bytes_sent += n; while (n && !r->connection->aborted) { w = ap_bwrite(r->connection->client, &buf[o], n); if (w > 0) { - ap_reset_timeout(r); /* reset timeout after successful - * write */ + ap_reset_timeout(r); /* reset timeout after successful write */ + total_bytes_sent += w; n -= w; o += w; } else if (w < 0) { - if (r->connection->aborted) - break; - else if (errno == EAGAIN) - continue; - else { + if (!r->connection->aborted) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "client stopped connection before send body completed"); + "client stopped connection before send body completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); r->connection->aborted = 1; - break; } + break; } } } @@ -2089,23 +2208,19 @@ API_EXPORT(size_t) ap_send_mmap(void *mm, request_rec *r, size_t offset, while (n && !r->connection->aborted) { w = ap_bwrite(r->connection->client, (char *) mm + offset, n); if (w > 0) { - ap_reset_timeout(r); /* reset timeout after successful write */ + ap_reset_timeout(r); /* reset timeout after successful write */ total_bytes_sent += w; n -= w; offset += w; } else if (w < 0) { - if (r->connection->aborted) - break; - else if (errno == EAGAIN) - continue; - else { + if (!r->connection->aborted) { ap_log_rerror(APLOG_MARK, APLOG_INFO, r, - "client stopped connection before send mmap completed"); + "client stopped connection before send mmap completed"); ap_bsetflag(r->connection->client, B_EOUT, 1); r->connection->aborted = 1; - break; } + break; } } } @@ -2119,7 +2234,16 @@ API_EXPORT(int) ap_rputc(int c, request_rec *r) { if (r->connection->aborted) return EOF; - ap_bputc(c, r->connection->client); + + if (ap_bputc(c, r->connection->client) < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rputc completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return EOF; + } SET_BYTES_SENT(r); return c; } @@ -2130,7 +2254,17 @@ API_EXPORT(int) ap_rputs(const char *str, request_rec *r) if (r->connection->aborted) return EOF; + rcode = ap_bputs(str, r->connection->client); + if (rcode < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rputs completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return EOF; + } SET_BYTES_SENT(r); return rcode; } @@ -2138,9 +2272,42 @@ API_EXPORT(int) ap_rputs(const char *str, request_rec *r) API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r) { int n; + if (r->connection->aborted) - return EOF; + return -1; + n = ap_bwrite(r->connection->client, buf, nbyte); + if (n < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rwrite completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return -1; + } + SET_BYTES_SENT(r); + return n; +} + +API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list ap) +{ + int n; + + if (r->connection->aborted) + return -1; + + n = ap_vbprintf(r->connection->client, fmt, ap); + + if (n < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before vrprintf completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return -1; + } SET_BYTES_SENT(r); return n; } @@ -2151,10 +2318,21 @@ API_EXPORT(int) ap_rprintf(request_rec *r, const char *fmt,...) int n; if (r->connection->aborted) - return EOF; + return -1; + va_start(vlist, fmt); n = ap_vbprintf(r->connection->client, fmt, vlist); va_end(vlist); + + if (n < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rprintf completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return -1; + } SET_BYTES_SENT(r); return n; } @@ -2178,7 +2356,13 @@ API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...) i = ap_bwrite(fb, x, j); if (i != j) { va_end(args); - return -1; + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rvputs completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return EOF; } k += i; } @@ -2190,7 +2374,16 @@ API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...) API_EXPORT(int) ap_rflush(request_rec *r) { - return ap_bflush(r->connection->client); + if (ap_bflush(r->connection->client) < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before rflush completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return EOF; + } + return 0; } /* We should have named this send_canned_response, since it is used for any @@ -2201,12 +2394,19 @@ API_EXPORT(int) ap_rflush(request_rec *r) */ void ap_send_error_response(request_rec *r, int recursive_error) { - BUFF *fd = r->connection->client; int status = r->status; int idx = ap_index_of_response(status); char *custom_response; const char *location = ap_table_get(r->headers_out, "Location"); + /* + * It's possible that the Location field might be in r->err_headers_out + * instead of r->headers_out; use the latter if possible, else the + * former. + */ + if (location == NULL) { + location = ap_table_get(r->err_headers_out, "Location"); + } /* We need to special-case the handling of 204 and 304 responses, * since they have specific HTTP requirements and do not include a * message body. Note that being assbackwards here is not an option. @@ -2258,9 +2458,14 @@ void ap_send_error_response(request_rec *r, int recursive_error) r->err_headers_out = tmp; ap_clear_table(r->err_headers_out); - if (location && *location - && (ap_is_HTTP_REDIRECT(status) || status == HTTP_CREATED)) - ap_table_setn(r->headers_out, "Location", location); + if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) { + if ((location != NULL) && *location) { + ap_table_setn(r->headers_out, "Location", location); + } + else { + location = ""; /* avoids coredump when printing, below */ + } + } r->content_language = NULL; r->content_languages = NULL; @@ -2275,6 +2480,7 @@ void ap_send_error_response(request_rec *r, int recursive_error) if (r->header_only) { ap_finalize_request_protocol(r); + ap_rflush(r); return; } } @@ -2295,9 +2501,10 @@ void ap_send_error_response(request_rec *r, int recursive_error) * the original error and output that as well. */ if (custom_response[0] == '\"') { - ap_bputs(custom_response + 1, fd); + ap_rputs(custom_response + 1, r); ap_kill_timeout(r); ap_finalize_request_protocol(r); + ap_rflush(r); return; } /* @@ -2307,8 +2514,8 @@ void ap_send_error_response(request_rec *r, int recursive_error) r = r->prev; } { - char *title = status_lines[idx]; - char *h1; + const char *title = status_lines[idx]; + const char *h1; const char *error_notes; /* Accept a status_line set by a module, but only if it begins @@ -2327,8 +2534,8 @@ void ap_send_error_response(request_rec *r, int recursive_error) /* folks decided they didn't want the error code in the H1 text */ h1 = &title[4]; - ap_bvputs(fd, - "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" + ap_rvputs(r, + DOCTYPE_HTML_2_0 "<HTML><HEAD>\n<TITLE>", title, "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n", NULL); @@ -2337,17 +2544,17 @@ void ap_send_error_response(request_rec *r, int recursive_error) case HTTP_MOVED_PERMANENTLY: case HTTP_MOVED_TEMPORARILY: case HTTP_TEMPORARY_REDIRECT: - ap_bvputs(fd, "The document has moved <A HREF=\"", + ap_rvputs(r, "The document has moved <A HREF=\"", ap_escape_html(r->pool, location), "\">here</A>.<P>\n", NULL); break; case HTTP_SEE_OTHER: - ap_bvputs(fd, "The answer to your request is located <A HREF=\"", + ap_rvputs(r, "The answer to your request is located <A HREF=\"", ap_escape_html(r->pool, location), "\">here</A>.<P>\n", NULL); break; case HTTP_USE_PROXY: - ap_bvputs(fd, "This resource is only accessible " + ap_rvputs(r, "This resource is only accessible " "through the proxy\n", ap_escape_html(r->pool, location), "<BR>\nYou will need to ", @@ -2355,38 +2562,38 @@ void ap_send_error_response(request_rec *r, int recursive_error) break; case HTTP_PROXY_AUTHENTICATION_REQUIRED: case AUTH_REQUIRED: - ap_bputs("This server could not verify that you\n", fd); - ap_bputs("are authorized to access the document you\n", fd); - ap_bputs("requested. Either you supplied the wrong\n", fd); - ap_bputs("credentials (e.g., bad password), or your\n", fd); - ap_bputs("browser doesn't understand how to supply\n", fd); - ap_bputs("the credentials required.<P>\n", fd); + ap_rputs("This server could not verify that you\n" + "are authorized to access the document\n" + "requested. Either you supplied the wrong\n" + "credentials (e.g., bad password), or your\n" + "browser doesn't understand how to supply\n" + "the credentials required.<P>\n", r); break; case BAD_REQUEST: - ap_bputs("Your browser sent a request that\n", fd); - ap_bputs("this server could not understand.<P>\n", fd); + ap_rputs("Your browser sent a request that " + "this server could not understand.<P>\n", r); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case HTTP_FORBIDDEN: - ap_bvputs(fd, "You don't have permission to access ", + ap_rvputs(r, "You don't have permission to access ", ap_escape_html(r->pool, r->uri), "\non this server.<P>\n", NULL); break; case NOT_FOUND: - ap_bvputs(fd, "The requested URL ", + ap_rvputs(r, "The requested URL ", ap_escape_html(r->pool, r->uri), " was not found on this server.<P>\n", NULL); break; case METHOD_NOT_ALLOWED: - ap_bvputs(fd, "The requested method ", r->method, + ap_rvputs(r, "The requested method ", r->method, " is not allowed " "for the URL ", ap_escape_html(r->pool, r->uri), ".<P>\n", NULL); break; case NOT_ACCEPTABLE: - ap_bvputs(fd, + ap_rvputs(r, "An appropriate representation of the " "requested resource ", ap_escape_html(r->pool, r->uri), @@ -2396,44 +2603,47 @@ void ap_send_error_response(request_rec *r, int recursive_error) { const char *list; if ((list = ap_table_get(r->notes, "variant-list"))) - ap_bputs(list, fd); + ap_rputs(list, r); } break; case LENGTH_REQUIRED: - ap_bvputs(fd, "A request of the requested method ", r->method, + ap_rvputs(r, "A request of the requested method ", r->method, " requires a valid Content-length.<P>\n", NULL); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case PRECONDITION_FAILED: - ap_bvputs(fd, "The precondition on the request for the URL ", + ap_rvputs(r, "The precondition on the request for the URL ", ap_escape_html(r->pool, r->uri), " evaluated to false.<P>\n", NULL); break; case HTTP_NOT_IMPLEMENTED: - ap_bvputs(fd, ap_escape_html(r->pool, r->method), " to ", + ap_rvputs(r, ap_escape_html(r->pool, r->method), " to ", ap_escape_html(r->pool, r->uri), " not supported.<P>\n", NULL); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case BAD_GATEWAY: - ap_bputs("The proxy server received an invalid\015\012", fd); - ap_bputs("response from an upstream server.<P>\015\012", fd); + ap_rputs("The proxy server received an invalid\015\012" + "response from an upstream server.<P>\015\012", r); + if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { + ap_rvputs(r, error_notes, "<P>\n", NULL); + } break; case VARIANT_ALSO_VARIES: - ap_bvputs(fd, "A variant for the requested resource\n<PRE>\n", + ap_rvputs(r, "A variant for the requested resource\n<PRE>\n", ap_escape_html(r->pool, r->uri), "\n</PRE>\nis itself a negotiable resource. " "This indicates a configuration error.<P>\n", NULL); break; case HTTP_REQUEST_TIME_OUT: - ap_bputs("I'm tired of waiting for your request.\n", fd); + ap_rputs("I'm tired of waiting for your request.\n", r); break; case HTTP_GONE: - ap_bvputs(fd, "The requested resource<BR>", + ap_rvputs(r, "The requested resource<BR>", ap_escape_html(r->pool, r->uri), "<BR>\nis no longer available on this server ", "and there is no forwarding address.\n", @@ -2441,30 +2651,30 @@ void ap_send_error_response(request_rec *r, int recursive_error) NULL); break; case HTTP_REQUEST_ENTITY_TOO_LARGE: - ap_bvputs(fd, "The requested resource<BR>", + ap_rvputs(r, "The requested resource<BR>", ap_escape_html(r->pool, r->uri), "<BR>\n", "does not allow request data with ", r->method, " requests, or the amount of data provided in\n", "the request exceeds the capacity limit.\n", NULL); break; case HTTP_REQUEST_URI_TOO_LARGE: - ap_bputs("The requested URL's length exceeds the capacity\n" - "limit for this server.<P>\n", fd); + ap_rputs("The requested URL's length exceeds the capacity\n" + "limit for this server.<P>\n", r); if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - ap_bvputs(fd, error_notes, "<P>\n", NULL); + ap_rvputs(r, error_notes, "<P>\n", NULL); } break; case HTTP_UNSUPPORTED_MEDIA_TYPE: - ap_bputs("The supplied request data is not in a format\n" - "acceptable for processing by this resource.\n", fd); + ap_rputs("The supplied request data is not in a format\n" + "acceptable for processing by this resource.\n", r); break; case HTTP_RANGE_NOT_SATISFIABLE: - ap_bputs("None of the range-specifier values in the Range\n" + ap_rputs("None of the range-specifier values in the Range\n" "request-header field overlap the current extent\n" - "of the selected resource.\n", fd); + "of the selected resource.\n", r); break; case HTTP_EXPECTATION_FAILED: - ap_bvputs(fd, "The expectation given in the Expect request-header" + ap_rvputs(r, "The expectation given in the Expect request-header" "\nfield could not be met by this server.<P>\n" "The client sent<PRE>\n Expect: ", ap_table_get(r->headers_in, "Expect"), "\n</PRE>\n" @@ -2472,42 +2682,55 @@ void ap_send_error_response(request_rec *r, int recursive_error) NULL); break; case HTTP_UNPROCESSABLE_ENTITY: - ap_bputs("The server understands the media type of the\n" + ap_rputs("The server understands the media type of the\n" "request entity, but was unable to process the\n" - "contained instructions.\n", fd); + "contained instructions.\n", r); break; case HTTP_LOCKED: - ap_bputs("The requested resource is currently locked.\n" + ap_rputs("The requested resource is currently locked.\n" "The lock must be released or proper identification\n" - "given before the method can be applied.\n", fd); + "given before the method can be applied.\n", r); break; case HTTP_FAILED_DEPENDENCY: - ap_bputs("The method could not be performed on the resource\n" + ap_rputs("The method could not be performed on the resource\n" "because the requested action depended on another\n" - "action and that other action failed.\n", fd); + "action and that other action failed.\n", r); break; case HTTP_INSUFFICIENT_STORAGE: - ap_bputs("The method could not be performed on the resource\n" + ap_rputs("The method could not be performed on the resource\n" "because the server is unable to store the\n" "representation needed to successfully complete the\n" "request. There is insufficient free space left in\n" - "your storage allocation.\n", fd); + "your storage allocation.\n", r); break; case HTTP_SERVICE_UNAVAILABLE: - ap_bputs("The server is temporarily unable to service your\n" + ap_rputs("The server is temporarily unable to service your\n" "request due to maintenance downtime or capacity\n" - "problems. Please try again later.\n", fd); + "problems. Please try again later.\n", r); break; case HTTP_GATEWAY_TIME_OUT: - ap_bputs("The proxy server did not receive a timely response\n" - "from the upstream server.\n", fd); + ap_rputs("The proxy server did not receive a timely response\n" + "from the upstream server.\n", r); break; case HTTP_NOT_EXTENDED: - ap_bputs("A mandatory extension policy in the request is not\n" - "accepted by the server for this resource.\n", fd); + ap_rputs("A mandatory extension policy in the request is not\n" + "accepted by the server for this resource.\n", r); break; default: /* HTTP_INTERNAL_SERVER_ERROR */ - ap_bvputs(fd, "The server encountered an internal error or\n" + /* + * This comparison to expose error-notes could be modified to + * use a configuration directive and export based on that + * directive. For now "*" is used to designate an error-notes + * that is totally safe for any user to see (ie lacks paths, + * database passwords, etc.) + */ + if (((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) + && (h1 = ap_table_get(r->notes, "verbose-error-to")) != NULL + && (strcmp(h1, "*") == 0)) { + ap_rvputs(r, error_notes, "<P>\n", NULL); + } + else { + ap_rvputs(r, "The server encountered an internal error or\n" "misconfiguration and was unable to complete\n" "your request.<P>\n" "Please contact the server administrator,\n ", @@ -2517,6 +2740,7 @@ void ap_send_error_response(request_rec *r, int recursive_error) "caused the error.<P>\n" "More information about this error may be available\n" "in the server error log.<P>\n", NULL); + } /* * It would be nice to give the user the information they need to * fix the problem directly since many users don't have access to @@ -2527,21 +2751,22 @@ void ap_send_error_response(request_rec *r, int recursive_error) * can figure out a way to remove the pathname, leave this commented. * * if ((error_notes = ap_table_get(r->notes, "error-notes")) != NULL) { - * ap_bvputs(fd, error_notes, "<P>\n", NULL); + * ap_rvputs(r, error_notes, "<P>\n", NULL); * } */ break; } if (recursive_error) { - ap_bvputs(fd, "<P>Additionally, a ", + ap_rvputs(r, "<P>Additionally, a ", status_lines[ap_index_of_response(recursive_error)], "\nerror was encountered while trying to use an " "ErrorDocument to handle the request.\n", NULL); } - ap_bputs(ap_psignature("<HR>\n", r), fd); - ap_bputs("</BODY></HTML>\n", fd); + ap_rputs(ap_psignature("<HR>\n", r), r); + ap_rputs("</BODY></HTML>\n", r); } ap_kill_timeout(r); ap_finalize_request_protocol(r); + ap_rflush(r); } diff --git a/usr.sbin/httpd/src/main/http_request.c b/usr.sbin/httpd/src/main/http_request.c index 693cf310648..e6f66316582 100644 --- a/usr.sbin/httpd/src/main/http_request.c +++ b/usr.sbin/httpd/src/main/http_request.c @@ -178,8 +178,8 @@ static int get_path_info(request_rec *r) char *end = &path[strlen(path)]; char *last_cp = NULL; int rv; -#ifdef WIN32 - BOOL bStripSlash=TRUE; +#ifdef HAVE_DRIVE_LETTERS + char bStripSlash=1; #endif if (r->finfo.st_mode) { @@ -187,12 +187,12 @@ static int get_path_info(request_rec *r) return OK; } -#ifdef WIN32 +#ifdef HAVE_DRIVE_LETTERS /* If the directory is x:\, then we don't want to strip * the trailing slash since x: is not a valid directory. */ if (strlen(path) == 3 && path[1] == ':' && path[2] == '/') - bStripSlash = FALSE; + bStripSlash = 0; /* If UNC name == //machine/share/, do not @@ -211,7 +211,7 @@ static int get_path_info(request_rec *r) } if (iCount == 4) - bStripSlash = FALSE; + bStripSlash = 0; } if (bStripSlash) @@ -265,8 +265,12 @@ static int get_path_info(request_rec *r) *cp = '\0'; return OK; } + /* must set this to zero, some stat()s may have corrupted it + * even if they returned an error. + */ + r->finfo.st_mode = 0; #if defined(ENOENT) && defined(ENOTDIR) - else if (errno == ENOENT || errno == ENOTDIR) { + if (errno == ENOENT || errno == ENOTDIR) { last_cp = cp; while (--cp > path && *cp != '/') @@ -299,15 +303,13 @@ static int get_path_info(request_rec *r) * you needed to do this. Please be sure to include the operating * system you are using. */ - else { - last_cp = cp; + last_cp = cp; - while (--cp > path && *cp != '/') - continue; + while (--cp > path && *cp != '/') + continue; - while (cp > path && cp[-1] == '/') - --cp; - } + while (cp > path && cp[-1] == '/') + --cp; #endif /* ENOENT && ENOTDIR */ } return OK; @@ -368,7 +370,7 @@ static int directory_walk(request_rec *r) this_conf = NULL; if (entry_core->r) { - if (!regexec(entry_core->r, r->filename, 0, NULL, 0)) + if (!ap_regexec(entry_core->r, r->filename, 0, NULL, 0)) this_conf = entry_config; } else if (entry_core->d_is_fnmatch) { @@ -534,7 +536,7 @@ static int directory_walk(request_rec *r) ap_get_module_config(entry_config, &core_module); if (entry_core->r) { - if (!regexec(entry_core->r, test_dirname, 0, NULL, REG_NOTEOL)) { + if (!ap_regexec(entry_core->r, test_dirname, 0, NULL, REG_NOTEOL)) { per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults, entry_config); @@ -610,7 +612,7 @@ static int location_walk(request_rec *r) this_conf = NULL; if (entry_core->r) { - if (!regexec(entry_core->r, r->uri, 0, NULL, 0)) + if (!ap_regexec(entry_core->r, r->uri, 0, NULL, 0)) this_conf = entry_config; } else if (entry_core->d_is_fnmatch) { @@ -671,7 +673,7 @@ static int file_walk(request_rec *r) this_conf = NULL; if (entry_core->r) { - if (!regexec(entry_core->r, test_file, 0, NULL, 0)) + if (!ap_regexec(entry_core->r, test_file, 0, NULL, 0)) this_conf = entry_config; } else if (entry_core->d_is_fnmatch) { @@ -718,8 +720,9 @@ static request_rec *make_sub_request(const request_rec *r) return rr; } -API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, - const request_rec *r) +API_EXPORT(request_rec *) ap_sub_req_method_uri(const char *method, + const char *new_file, + const request_rec *r) { request_rec *rnew; int res; @@ -736,6 +739,10 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, ap_set_sub_req_protocol(rnew, r); + /* would be nicer to pass "method" to ap_set_sub_req_protocol */ + rnew->method = method; + rnew->method_number = ap_method_number_of(method); + if (new_file[0] == '/') ap_parse_uri(rnew, new_file); else { @@ -796,6 +803,12 @@ API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, return rnew; } +API_EXPORT(request_rec *) ap_sub_req_lookup_uri(const char *new_file, + const request_rec *r) +{ + return ap_sub_req_method_uri("GET", new_file, r); +} + API_EXPORT(request_rec *) ap_sub_req_lookup_file(const char *new_file, const request_rec *r) { @@ -1298,6 +1311,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, request_rec new->htaccess = r->htaccess; new->no_cache = r->no_cache; + new->expecting_100 = r->expecting_100; new->no_local_copy = r->no_local_copy; new->read_length = r->read_length; /* We can only read it once */ new->vlist_validator = r->vlist_validator; diff --git a/usr.sbin/httpd/src/main/md5c.c b/usr.sbin/httpd/src/main/md5c.c deleted file mode 100644 index a94601d3109..00000000000 --- a/usr.sbin/httpd/src/main/md5c.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * This is work is derived from material Copyright RSA Data Security, Inc. - * - * The RSA copyright statement and Licence for that original material is - * included below. This is followed by the Apache copyright statement and - * licence for the modifications made to that material. - */ - -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - rights reserved. - - License to copy and use this software is granted provided that it - is identified as the "RSA Data Security, Inc. MD5 Message-Digest - Algorithm" in all material mentioning or referencing this software - or this function. - - License is also granted to make and use derivative works provided - that such works are identified as "derived from the RSA Data - Security, Inc. MD5 Message-Digest Algorithm" in all material - mentioning or referencing the derived work. - - RSA Data Security, Inc. makes no representations concerning either - the merchantability of this software or the suitability of this - software for any particular purpose. It is provided "as is" - without express or implied warranty of any kind. - - These notices must be retained in any copies of any part of this - documentation and/or software. - */ - -/* ==================================================================== - * Copyright (c) 1996-1999 The Apache Group. 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. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * 4. The names "Apache Server" and "Apache Group" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the Apache Group - * for use in the Apache HTTP server project (http://www.apache.org/)." - * - * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Group and was originally based - * on public domain software written at the National Center for - * Supercomputing Applications, University of Illinois, Urbana-Champaign. - * For more information on the Apache Group and the Apache HTTP server - * project, please see <http://www.apache.org/>. - * - */ - -#include <string.h> - -#include "ap_config.h" -#include "ap_md5.h" -#ifdef CHARSET_EBCDIC -#include "ebcdic.h" -#endif /*CHARSET_EBCDIC*/ - -/* Constants for MD5Transform routine. - */ - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static void MD5Transform(UINT4 state[4], const unsigned char block[64]); -static void Encode(unsigned char *output, const UINT4 *input, - unsigned int len); -static void Decode(UINT4 *output, const unsigned char *input, - unsigned int len); - -static unsigned char PADDING[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. - Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -API_EXPORT(void) ap_MD5Init(AP_MD5_CTX * context) -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. */ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ -API_EXPORT(void) ap_MD5Update(AP_MD5_CTX * context, const unsigned char *input, - unsigned int inputLen) -{ - unsigned int i, idx, partLen; - - /* Compute number of bytes mod 64 */ - idx = (unsigned int) ((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ((context->count[0] += ((UINT4) inputLen << 3)) < ((UINT4) inputLen << 3)) - context->count[1]++; - context->count[1] += (UINT4) inputLen >> 29; - - partLen = 64 - idx; - - /* Transform as many times as possible. */ -#ifndef CHARSET_EBCDIC - if (inputLen >= partLen) { - memcpy(&context->buffer[idx], input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform(context->state, &input[i]); - - idx = 0; - } - else - i = 0; - - /* Buffer remaining input */ - memcpy(&context->buffer[idx], &input[i], inputLen - i); -#else /*CHARSET_EBCDIC*/ - if (inputLen >= partLen) { - ebcdic2ascii_strictly(&context->buffer[idx], input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) { - unsigned char inp_tmp[64]; - ebcdic2ascii_strictly(inp_tmp, &input[i], 64); - MD5Transform(context->state, inp_tmp); - } - - idx = 0; - } - else - i = 0; - - /* Buffer remaining input */ - ebcdic2ascii_strictly(&context->buffer[idx], &input[i], inputLen - i); -#endif /*CHARSET_EBCDIC*/ -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ -API_EXPORT(void) ap_MD5Final(unsigned char digest[16], AP_MD5_CTX * context) -{ - unsigned char bits[8]; - unsigned int idx, padLen; - - - /* Save number of bits */ - Encode(bits, context->count, 8); - -#ifdef CHARSET_EBCDIC - /* XXX: @@@: In order to make this no more complex than necessary, - * this kludge converts the bits[] array using the ascii-to-ebcdic - * table, because the following ap_MD5Update() re-translates - * its input (ebcdic-to-ascii). - * Otherwise, we would have to pass a "conversion" flag to ap_MD5Update() - */ - ascii2ebcdic(bits,bits,8); - - /* Since everything is converted to ascii within ap_MD5Update(), - * the initial 0x80 (PADDING[0]) must be stored as 0x20 - */ - PADDING[0] = os_toebcdic[0x80]; -#endif /*CHARSET_EBCDIC*/ - - /* Pad out to 56 mod 64. */ - idx = (unsigned int) ((context->count[0] >> 3) & 0x3f); - padLen = (idx < 56) ? (56 - idx) : (120 - idx); - ap_MD5Update(context, PADDING, padLen); - - /* Append length (before padding) */ - ap_MD5Update(context, bits, 8); - - /* Store state in digest */ - Encode(digest, context->state, 16); - - /* Zeroize sensitive information. */ - memset(context, 0, sizeof(*context)); -} - -/* MD5 basic transformation. Transforms state based on block. */ -static void MD5Transform(UINT4 state[4], const unsigned char block[64]) -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode(x, block, 64); - - /* Round 1 */ - FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ - FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ - FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ - FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ - FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ - FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ - FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ - FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ - FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ - FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ - FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ - GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ - GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ - GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ - GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ - GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ - GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ - GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ - GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ - GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ - GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ - HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ - HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ - HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ - HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ - HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ - HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ - HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ - HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ - HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ - II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ - II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ - II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ - II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ - II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ - II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ - II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ - II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ - II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. */ - memset(x, 0, sizeof(x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode(unsigned char *output, const UINT4 *input, unsigned int len) -{ - unsigned int i, j; - UINT4 k; - - for (i = 0, j = 0; j < len; i++, j += 4) { - k = input[i]; - output[j] = (unsigned char) (k & 0xff); - output[j + 1] = (unsigned char) ((k >> 8) & 0xff); - output[j + 2] = (unsigned char) ((k >> 16) & 0xff); - output[j + 3] = (unsigned char) ((k >> 24) & 0xff); - } -} - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - a multiple of 4. - */ -static void Decode(UINT4 *output, const unsigned char *input, unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) | - (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24); -} diff --git a/usr.sbin/httpd/src/main/rfc1413.c b/usr.sbin/httpd/src/main/rfc1413.c index 1c60a7ddab3..65bc6ef4d07 100644 --- a/usr.sbin/httpd/src/main/rfc1413.c +++ b/usr.sbin/httpd/src/main/rfc1413.c @@ -147,6 +147,9 @@ static int get_rfc1413(int sock, const struct sockaddr_in *our_sin, ntohs(our_sin->sin_port)); /* send query to server. Handle short write. */ +#ifdef CHARSET_EBCDIC + ebcdic2ascii(&buffer, &buffer, buflen); +#endif i = 0; while(i < strlen(buffer)) { int j; @@ -168,8 +171,12 @@ static int get_rfc1413(int sock, const struct sockaddr_in *our_sin, */ i = 0; - memset(buffer, 0, sizeof(buffer)); - while((cp = strchr(buffer, '\n')) == NULL && i < sizeof(buffer) - 1) { + memset(buffer, '\0', sizeof(buffer)); + /* + * Note that the strchr function below checks for 10 instead of '\n' + * this allows it to work on both ASCII and EBCDIC machines. + */ + while((cp = strchr(buffer, '\012')) == NULL && i < sizeof(buffer) - 1) { int j; j = read(sock, buffer+i, (sizeof(buffer) - 1) - i); if (j < 0 && errno != EINTR) { @@ -183,6 +190,9 @@ static int get_rfc1413(int sock, const struct sockaddr_in *our_sin, } /* RFC1413_USERLEN = 512 */ +#ifdef CHARSET_EBCDIC + ascii2ebcdic(&buffer, &buffer, (size_t)i); +#endif if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port, user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port || ntohs(our_sin->sin_port) != our_port) diff --git a/usr.sbin/httpd/src/main/util.c b/usr.sbin/httpd/src/main/util.c index 81b40ca4055..b358501c077 100644 --- a/usr.sbin/httpd/src/main/util.c +++ b/usr.sbin/httpd/src/main/util.c @@ -119,6 +119,26 @@ API_EXPORT(char *) ap_get_time() return (time_string); } +/* + * Examine a field value (such as a media-/content-type) string and return + * it sans any parameters; e.g., strip off any ';charset=foo' and the like. + */ +API_EXPORT(char *) ap_field_noparam(pool *p, const char *intype) +{ + const char *semi; + + semi = strchr(intype, ';'); + if (semi == NULL) { + return ap_pstrdup(p, intype); + } + else { + while ((semi > intype) && ap_isspace(semi[-1])) { + semi--; + } + return ap_pstrndup(p, intype, semi - intype); + } +} + API_EXPORT(char *) ap_ht_time(pool *p, time_t t, const char *fmt, int gmt) { char ts[MAX_STRING_LEN]; @@ -281,9 +301,27 @@ API_EXPORT(int) ap_is_matchexp(const char *str) return 0; } +/* + * Apache stub function for the regex libraries regexec() to make sure the + * whole regex(3) API is available through the Apache (exported) namespace. + * This is especially important for the DSO situations of modules. + * DO NOT MAKE A MACRO OUT OF THIS FUNCTION! + */ +API_EXPORT(int) ap_regexec(const regex_t *preg, const char *string, + size_t nmatch, regmatch_t pmatch[], int eflags) +{ + return regexec(preg, string, nmatch, pmatch, eflags); +} + +API_EXPORT(size_t) ap_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ + return regerror(errcode, preg, errbuf, errbuf_size); +} + + /* This function substitutes for $0-$9, filling in regular expression * submatches. Pass it the same nmatch and pmatch arguments that you - * passed regexec(). pmatch should not be greater than the maximum number + * passed ap_regexec(). pmatch should not be greater than the maximum number * of subexpressions - i.e. one more than the re_nsub member of regex_t. * * input should be the string with the $-expressions, source should be the @@ -877,8 +915,8 @@ API_EXPORT(int) ap_cfg_getline(char *buf, size_t bufsize, configfile_t *cfp) * line continuation requested - * then remove backslash and continue */ - cbuf = cp; cbufsize -= (cp-cbuf); + cbuf = cp; continue; } else { @@ -978,6 +1016,258 @@ API_EXPORT(int) ap_cfg_getline(char *buf, size_t bufsize, configfile_t *cfp) } } +/* Size an HTTP header field list item, as separated by a comma. + * The return value is a pointer to the beginning of the non-empty list item + * within the original string (or NULL if there is none) and the address + * of field is shifted to the next non-comma, non-whitespace character. + * len is the length of the item excluding any beginning whitespace. + */ +API_EXPORT(const char *) ap_size_list_item(const char **field, int *len) +{ + const unsigned char *ptr = (const unsigned char *)*field; + const unsigned char *token; + int in_qpair, in_qstr, in_com; + + /* Find first non-comma, non-whitespace byte */ + + while (*ptr == ',' || ap_isspace(*ptr)) + ++ptr; + + token = ptr; + + /* Find the end of this item, skipping over dead bits */ + + for (in_qpair = in_qstr = in_com = 0; + *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); + ++ptr) { + + if (in_qpair) { + in_qpair = 0; + } + else { + switch (*ptr) { + case '\\': in_qpair = 1; /* quoted-pair */ + break; + case '"' : if (!in_com) /* quoted string delim */ + in_qstr = !in_qstr; + break; + case '(' : if (!in_qstr) /* comment (may nest) */ + ++in_com; + break; + case ')' : if (in_com) /* end comment */ + --in_com; + break; + default : break; + } + } + } + + if ((*len = (ptr - token)) == 0) { + *field = (const char *)ptr; + return NULL; + } + + /* Advance field pointer to the next non-comma, non-white byte */ + + while (*ptr == ',' || ap_isspace(*ptr)) + ++ptr; + + *field = (const char *)ptr; + return (const char *)token; +} + +/* Retrieve an HTTP header field list item, as separated by a comma, + * while stripping insignificant whitespace and lowercasing anything not in + * a quoted string or comment. The return value is a new string containing + * the converted list item (or NULL if none) and the address pointed to by + * field is shifted to the next non-comma, non-whitespace. + */ +API_EXPORT(char *) ap_get_list_item(pool *p, const char **field) +{ + const char *tok_start; + const unsigned char *ptr; + unsigned char *pos; + char *token; + int addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0, tok_len = 0; + + /* Find the beginning and maximum length of the list item so that + * we can allocate a buffer for the new string and reset the field. + */ + if ((tok_start = ap_size_list_item(field, &tok_len)) == NULL) { + return NULL; + } + token = ap_palloc(p, tok_len + 1); + + /* Scan the token again, but this time copy only the good bytes. + * We skip extra whitespace and any whitespace around a '=', '/', + * or ';' and lowercase normal characters not within a comment, + * quoted-string or quoted-pair. + */ + for (ptr = (const unsigned char *)tok_start, pos = (unsigned char *)token; + *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); + ++ptr) { + + if (in_qpair) { + in_qpair = 0; + *pos++ = *ptr; + } + else { + switch (*ptr) { + case '\\': in_qpair = 1; + if (addspace == 1) + *pos++ = ' '; + *pos++ = *ptr; + addspace = 0; + break; + case '"' : if (!in_com) + in_qstr = !in_qstr; + if (addspace == 1) + *pos++ = ' '; + *pos++ = *ptr; + addspace = 0; + break; + case '(' : if (!in_qstr) + ++in_com; + if (addspace == 1) + *pos++ = ' '; + *pos++ = *ptr; + addspace = 0; + break; + case ')' : if (in_com) + --in_com; + *pos++ = *ptr; + addspace = 0; + break; + case ' ' : + case '\t': if (addspace) + break; + if (in_com || in_qstr) + *pos++ = *ptr; + else + addspace = 1; + break; + case '=' : + case '/' : + case ';' : if (!(in_com || in_qstr)) + addspace = -1; + *pos++ = *ptr; + break; + default : if (addspace == 1) + *pos++ = ' '; + *pos++ = (in_com || in_qstr) ? *ptr + : ap_tolower(*ptr); + addspace = 0; + break; + } + } + } + *pos = '\0'; + + return token; +} + +/* Find an item in canonical form (lowercase, no extra spaces) within + * an HTTP field value list. Returns 1 if found, 0 if not found. + * This would be much more efficient if we stored header fields as + * an array of list items as they are received instead of a plain string. + */ +API_EXPORT(int) ap_find_list_item(pool *p, const char *line, const char *tok) +{ + const unsigned char *pos; + const unsigned char *ptr = (const unsigned char *)line; + int good = 0, addspace = 0, in_qpair = 0, in_qstr = 0, in_com = 0; + + if (!line || !tok) + return 0; + + do { /* loop for each item in line's list */ + + /* Find first non-comma, non-whitespace byte */ + + while (*ptr == ',' || ap_isspace(*ptr)) + ++ptr; + + if (*ptr) + good = 1; /* until proven otherwise for this item */ + else + break; /* no items left and nothing good found */ + + /* We skip extra whitespace and any whitespace around a '=', '/', + * or ';' and lowercase normal characters not within a comment, + * quoted-string or quoted-pair. + */ + for (pos = (const unsigned char *)tok; + *ptr && (in_qpair || in_qstr || in_com || *ptr != ','); + ++ptr) { + + if (in_qpair) { + in_qpair = 0; + if (good) + good = (*pos++ == *ptr); + } + else { + switch (*ptr) { + case '\\': in_qpair = 1; + if (addspace == 1) + good = good && (*pos++ == ' '); + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case '"' : if (!in_com) + in_qstr = !in_qstr; + if (addspace == 1) + good = good && (*pos++ == ' '); + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case '(' : if (!in_qstr) + ++in_com; + if (addspace == 1) + good = good && (*pos++ == ' '); + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case ')' : if (in_com) + --in_com; + good = good && (*pos++ == *ptr); + addspace = 0; + break; + case ' ' : + case '\t': if (addspace || !good) + break; + if (in_com || in_qstr) + good = (*pos++ == *ptr); + else + addspace = 1; + break; + case '=' : + case '/' : + case ';' : if (!(in_com || in_qstr)) + addspace = -1; + good = good && (*pos++ == *ptr); + break; + default : if (!good) + break; + if (addspace == 1) + good = (*pos++ == ' '); + if (in_com || in_qstr) + good = good && (*pos++ == *ptr); + else + good = good && (*pos++ == ap_tolower(*ptr)); + addspace = 0; + break; + } + } + } + if (good && *pos) + good = 0; /* not good if only a prefix was matched */ + + } while (*ptr && !good); + + return good; +} + + /* Retrieve a token, spacing over it and returning a pointer to * the first non-white byte afterwards. Note that these tokens * are delimited by semis and commas; and can also be delimited @@ -1146,7 +1436,7 @@ API_EXPORT(int) ap_unescape_url(char *url) if (url[y] != '%') url[x] = url[y]; else { - if (!isxdigit(url[y + 1]) || !isxdigit(url[y + 2])) { + if (!ap_isxdigit(url[y + 1]) || !ap_isxdigit(url[y + 2])) { badesc = 1; url[x] = '%'; } @@ -1373,8 +1663,10 @@ char *strdup(const char *str) { char *sdup; - if (!(sdup = (char *) malloc(strlen(str) + 1))) + if (!(sdup = (char *) malloc(strlen(str) + 1))) { + fprintf(stderr, "Ouch! Out of memory in our strdup()!\n"); return NULL; + } sdup = strcpy(sdup, str); return sdup; @@ -1454,7 +1746,7 @@ char *strstr(char *s1, char *s2) #ifdef NEED_INITGROUPS int initgroups(const char *name, gid_t basegid) { -#if defined(QNX) || defined(MPE) || defined(BEOS) || defined(_OSD_POSIX) || defined(TPF) +#if defined(QNX) || defined(MPE) || defined(BEOS) || defined(_OSD_POSIX) || defined(TPF) || defined(__TANDEM) /* QNX, MPE and BeOS do not appear to support supplementary groups. */ return 0; #else /* ndef QNX */ @@ -1646,7 +1938,11 @@ char *ap_get_local_host(pool *a) char *server_hostname; struct hostent *p; +#ifdef BEOS /* BeOS returns zero as an error for gethostname */ + if (gethostname(str, sizeof(str) - 1) == 0) { +#else if (gethostname(str, sizeof(str) - 1) != 0) { +#endif /* BeOS */ perror("Unable to gethostname"); exit(1); } @@ -1661,125 +1957,43 @@ char *ap_get_local_host(pool *a) return server_hostname; } -/* aaaack but it's fast and const should make it shared text page. */ -static const unsigned char pr2six[256] = -{ - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 -}; - -API_EXPORT(char *) ap_uudecode(pool *p, const char *bufcoded) +/* simple 'pool' alloc()ing glue to ap_base64.c + */ +API_EXPORT(char *) ap_pbase64decode(pool *p, const char *bufcoded) { - int nbytesdecoded; - register const unsigned char *bufin; - register char *bufplain; - register unsigned char *bufout; - register int nprbytes; + char *decoded; + int l; - /* Strip leading whitespace. */ + decoded = (char *) ap_palloc(p, 1 + ap_base64decode_len(bufcoded)); + l = ap_base64decode(decoded, bufcoded); + decoded[l] = '\0'; /* make binary sequence into string */ - while (*bufcoded == ' ' || *bufcoded == '\t') - bufcoded++; + return decoded; +} - /* Figure out how many characters are in the input buffer. - * Allocate this many from the per-transaction pool for the result. - */ -#ifndef CHARSET_EBCDIC - bufin = (const unsigned char *) bufcoded; - while (pr2six[*(bufin++)] <= 63); - nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; - nbytesdecoded = ((nprbytes + 3) / 4) * 3; - - bufplain = ap_palloc(p, nbytesdecoded + 1); - bufout = (unsigned char *) bufplain; - - bufin = (const unsigned char *) bufcoded; - - while (nprbytes > 0) { - *(bufout++) = - (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); - *(bufout++) = - (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); - *(bufout++) = - (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); - bufin += 4; - nprbytes -= 4; - } - - if (nprbytes & 03) { - if (pr2six[bufin[-2]] > 63) - nbytesdecoded -= 2; - else - nbytesdecoded -= 1; - } - bufplain[nbytesdecoded] = '\0'; -#else /*CHARSET_EBCDIC*/ - bufin = (const unsigned char *) bufcoded; - while (pr2six[os_toascii[(unsigned char)*(bufin++)]] <= 63); - nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; - nbytesdecoded = ((nprbytes + 3) / 4) * 3; - - bufplain = ap_palloc(p, nbytesdecoded + 1); - bufout = (unsigned char *) bufplain; - - bufin = (const unsigned char *) bufcoded; - - while (nprbytes > 0) { - *(bufout++) = os_toebcdic[ - (unsigned char) (pr2six[os_toascii[*bufin]] << 2 | pr2six[os_toascii[bufin[1]]] >> 4)]; - *(bufout++) = os_toebcdic[ - (unsigned char) (pr2six[os_toascii[bufin[1]]] << 4 | pr2six[os_toascii[bufin[2]]] >> 2)]; - *(bufout++) = os_toebcdic[ - (unsigned char) (pr2six[os_toascii[bufin[2]]] << 6 | pr2six[os_toascii[bufin[3]]])]; - bufin += 4; - nprbytes -= 4; - } - - if (nprbytes & 03) { - if (pr2six[os_toascii[bufin[-2]]] > 63) - nbytesdecoded -= 2; - else - nbytesdecoded -= 1; - } - bufplain[nbytesdecoded] = '\0'; -#endif /*CHARSET_EBCDIC*/ - return bufplain; +API_EXPORT(char *) ap_pbase64encode(pool *p, char *string) +{ + char *encoded; + int l = strlen(string); + + encoded = (char *) ap_palloc(p, 1 + ap_base64encode_len(l)); + l = ap_base64encode(encoded, string, l); + encoded[l] = '\0'; /* make binary sequence into string */ + + return encoded; } -static const char basis_64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -API_EXPORT(char *) ap_uuencode(pool *a, char *string) +/* deprecated names for the above two functions, here for compatibility + */ +API_EXPORT(char *) ap_uudecode(pool *p, const char *bufcoded) +{ + return ap_pbase64decode(p, bufcoded); +} + +API_EXPORT(char *) ap_uuencode(pool *p, char *string) { - int i, len = strlen(string); - char *p; - char *encoded = (char *) ap_pcalloc(a, (len+2) / 3 * 4); - - p = encoded; - for (i = 0; i < len; i += 3) { - *p++ = basis_64[string[i] >> 2]; - *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; - *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int) (string[i + 2] & 0xC0) >> 6)]; - *p++ = basis_64[string[i + 2] & 0x3F]; - } - *p-- = '\0'; - *p-- = '='; - *p-- = '='; - return encoded; -} + return ap_pbase64encode(p, string); +} #ifdef OS2 void os2pathname(char *path) @@ -1806,6 +2020,32 @@ void os2pathname(char *path) strcpy(path, newpath); }; + +/* quotes in the string are doubled up. + * Used to escape quotes in args passed to OS/2's cmd.exe + */ +char *ap_double_quotes(pool *p, char *str) +{ + int num_quotes = 0; + int len = 0; + char *quote_doubled_str, *dest; + + while (str[len]) { + num_quotes += str[len++] == '\"'; + } + + quote_doubled_str = ap_palloc(p, len + num_quotes + 1); + dest = quote_doubled_str; + + while (*str) { + if (*str == '\"') + *(dest++) = '\"'; + *(dest++) = *(str++); + } + + *dest = 0; + return quote_doubled_str; +} #endif @@ -1877,6 +2117,7 @@ API_EXPORT(char *) ap_escape_quotes (pool *p, const char *instring) */ if ((*inchr == '\\') && (inchr[1] != '\0')) { inchr++; + newlen++; } inchr++; } diff --git a/usr.sbin/httpd/src/main/util_date.c b/usr.sbin/httpd/src/main/util_date.c index 933079cc3f3..5111a600f0d 100644 --- a/usr.sbin/httpd/src/main/util_date.c +++ b/usr.sbin/httpd/src/main/util_date.c @@ -109,7 +109,7 @@ API_EXPORT(int) ap_checkmask(const char *data, const char *mask) return 0; break; case '&': - if (!isxdigit(d)) + if (!ap_isxdigit(d)) return 0; break; case '~': diff --git a/usr.sbin/httpd/src/main/util_md5.c b/usr.sbin/httpd/src/main/util_md5.c index 7700de7af79..368ddf63b23 100644 --- a/usr.sbin/httpd/src/main/util_md5.c +++ b/usr.sbin/httpd/src/main/util_md5.c @@ -100,7 +100,7 @@ API_EXPORT(char *) ap_md5_binary(pool *p, const unsigned char *buf, int length) */ ap_MD5Init(&my_md5); - ap_MD5Update(&my_md5, buf, length); + ap_MD5Update(&my_md5, buf, (unsigned int)length); ap_MD5Final(hash, &my_md5); for (i = 0, r = result; i < 16; i++) { @@ -114,7 +114,7 @@ API_EXPORT(char *) ap_md5_binary(pool *p, const unsigned char *buf, int length) API_EXPORT(char *) ap_md5(pool *p, const unsigned char *string) { - return ap_md5_binary(p, string, strlen(string)); + return ap_md5_binary(p, string, (int) strlen((char *)string)); } /* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */ @@ -187,7 +187,9 @@ API_EXPORT(char *) ap_md5contextTo64(pool *a, AP_MD5_CTX * context) return encodedDigest; } -API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile) +#ifdef CHARSET_EBCDIC + +API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile, int convert) { AP_MD5_CTX context; unsigned char buf[1000]; @@ -196,9 +198,32 @@ API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile) ap_MD5Init(&context); while ((nbytes = fread(buf, 1, sizeof(buf), infile))) { + length += nbytes; + if (!convert) { + ascii2ebcdic(buf, buf, nbytes); + } + ap_MD5Update(&context, buf, nbytes); + } + rewind(infile); + return ap_md5contextTo64(p, &context); +} + +#else + +API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile) +{ + AP_MD5_CTX context; + unsigned char buf[1000]; + long length = 0; + unsigned int nbytes; + + ap_MD5Init(&context); + while ((nbytes = fread(buf, 1, sizeof(buf), infile))) { length += nbytes; ap_MD5Update(&context, buf, nbytes); } rewind(infile); return ap_md5contextTo64(p, &context); } + +#endif /* CHARSET_EBCDIC */ diff --git a/usr.sbin/httpd/src/main/util_script.c b/usr.sbin/httpd/src/main/util_script.c index 48f7b96cc18..467dd2964c1 100644 --- a/usr.sbin/httpd/src/main/util_script.c +++ b/usr.sbin/httpd/src/main/util_script.c @@ -67,6 +67,11 @@ #include "util_script.h" #include "util_date.h" /* For parseHTTPdate() */ +#ifdef OS2 +#define INCL_DOS +#include <os2.h> +#endif + /* * Various utility functions which are common to a whole lot of * script-type extensions mechanisms, and might as well be gathered @@ -265,6 +270,7 @@ API_EXPORT(void) ap_add_common_vars(request_rec *r) ap_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); ap_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version()); ap_table_addn(e, "SERVER_NAME", ap_get_server_name(r)); + ap_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */ ap_table_addn(e, "SERVER_PORT", ap_psprintf(r->pool, "%u", ap_get_server_port(r))); host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST); @@ -496,6 +502,8 @@ API_EXPORT(int) ap_scan_script_header_err_core(request_rec *r, char *buffer, ap_overlap_tables(r->err_headers_out, merge, AP_OVERLAP_TABLES_MERGE); if (!ap_is_empty_table(cookie_table)) { + /* the cookies have already been copied to the cookie_table */ + ap_table_unset(r->err_headers_out, "Set-Cookie"); r->err_headers_out = ap_overlay_tables(r->pool, r->err_headers_out, cookie_table); } @@ -693,7 +701,7 @@ API_EXPORT(int) ap_call_exec(request_rec *r, child_info *pinfo, char *argv0, #endif -#ifndef WIN32 +#if !defined(WIN32) && !defined(OS2) /* the fd on r->server->error_log is closed, but we need somewhere to * put the error messages from the log_* functions. So, we use stderr, * since that is better than allowing errors to go unnoticed. Don't do @@ -747,174 +755,222 @@ API_EXPORT(int) ap_call_exec(request_rec *r, child_info *pinfo, char *argv0, #ifdef OS2 { /* Additions by Alec Kloss, to allow exec'ing of scripts under OS/2 */ - int is_script; + int is_script = 0; char interpreter[2048]; /* hope it's enough for the interpreter path */ + char error_object[260]; FILE *program; - + char *cmdline = r->filename, *cmdline_pos; + int cmdlen; + char *args = "", *args_end; + ULONG rc; + RESULTCODES rescodes; + int env_len, e; + char *env_block, *env_block_pos; + + if (r->args && r->args[0] && !strchr(r->args, '=')) + args = r->args; + program = fopen(r->filename, "rt"); + if (!program) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "fopen(%s) failed", r->filename); return (pid); } + fgets(interpreter, sizeof(interpreter), program); fclose(program); + if (!strncmp(interpreter, "#!", 2)) { is_script = 1; - interpreter[strlen(interpreter) - 1] = '\0'; + interpreter[strlen(interpreter) - 1] = '\0'; + if (interpreter[2] != '/' && interpreter[2] != '\\' && interpreter[3] != ':') { + char buffer[300]; + if (DosSearchPath(SEARCH_ENVIRONMENT, "PATH", interpreter+2, buffer, sizeof(buffer)) == 0) { + strcpy(interpreter+2, buffer); + } else { + strcat(interpreter, ".exe"); + if (DosSearchPath(SEARCH_ENVIRONMENT, "PATH", interpreter+2, buffer, sizeof(buffer)) == 0) { + strcpy(interpreter+2, buffer); + } + } + } } - else { - is_script = 0; + + if (is_script) { + cmdline = ap_pstrcat(r->pool, interpreter+2, " ", r->filename, NULL); + } + else if (strstr(strupr(r->filename), ".CMD") > 0) { + /* Special case to allow use of REXX commands as scripts. */ + os2pathname(r->filename); + cmdline = ap_pstrcat(r->pool, SHELL_PATH, " /C ", r->filename, NULL); + } + else { + cmdline = r->filename; } + + args = ap_pstrdup(r->pool, args); + ap_unescape_url(args); + args = ap_double_quotes(r->pool, args); + args_end = args + strlen(args); + + if (args_end - args > 4000) { /* cmd.exe won't handle lines longer than 4k */ + args_end = args + 4000; + *args_end = 0; + } - if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) { - int emxloop; - char *emxtemp; + /* +4 = 1 space between progname and args, 2 for double null at end, 2 for possible quote on first arg */ + cmdlen = strlen(cmdline) + strlen(args) + 4; + cmdline_pos = cmdline; - /* For OS/2 place the variables in the current - * environment then it will be inherited. This way - * the program will also get all of OS/2's other SETs. - */ - for (emxloop = 0; ((emxtemp = env[emxloop]) != NULL); emxloop++) { - putenv(emxtemp); - } + while (*cmdline_pos) { + cmdlen += 2 * (*cmdline_pos == '+'); /* Allow space for each arg to be quoted */ + cmdline_pos++; + } - /* More additions by Alec Kloss for OS/2 */ - if (is_script) { - /* here's the stuff to run the interpreter */ - execl(interpreter + 2, interpreter + 2, r->filename, NULL); - } - else if (strstr(strupr(r->filename), ".CMD") > 0) { - /* Special case to allow use of REXX commands as scripts. */ - os2pathname(r->filename); - execl(SHELL_PATH, SHELL_PATH, "/C", r->filename, NULL); - } - else { - execl(r->filename, argv0, NULL); - } + cmdline = ap_pstrndup(r->pool, cmdline, cmdlen); + cmdline_pos = cmdline + strlen(cmdline); + + while (args < args_end) { + char *arg; + + arg = ap_getword_nc(r->pool, &args, '+'); + + if (strpbrk(arg, "&|<> ")) + arg = ap_pstrcat(r->pool, "\"", arg, "\"", NULL); + + *(cmdline_pos++) = ' '; + strcpy(cmdline_pos, arg); + cmdline_pos += strlen(cmdline_pos); + } + + *(++cmdline_pos) = 0; /* Add required second terminator */ + args = strchr(cmdline, ' '); + + if (args) { + *args = 0; + args++; } - else { - int emxloop; - char *emxtemp; - /* For OS/2 place the variables in the current - * environment so that they will be inherited. This way - * the program will also get all of OS/2's other SETs. - */ - for (emxloop = 0; ((emxtemp = env[emxloop]) != NULL); emxloop++) { - putenv(emxtemp); - } + /* Create environment block from list of envariables */ + for (env_len=1, e=0; env[e]; e++) + env_len += strlen(env[e]) + 1; - if (strstr(strupr(r->filename), ".CMD") > 0) { - /* Special case to allow use of REXX commands as scripts. */ - os2pathname(r->filename); - execv(SHELL_PATH, create_argv_cmd(r->pool, argv0, r->args, - r->filename)); - } - else { - execv(r->filename, - create_argv(r->pool, NULL, NULL, NULL, argv0, r->args)); - } + env_block = ap_palloc(r->pool, env_len); + env_block_pos = env_block; + + for (e=0; env[e]; e++) { + strcpy(env_block_pos, env[e]); + env_block_pos += strlen(env_block_pos) + 1; + } + + *env_block_pos = 0; /* environment block is terminated by a double null */ + + rc = DosExecPgm(error_object, sizeof(error_object), EXEC_ASYNC, cmdline, env_block, &rescodes, cmdline); + + if (rc) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "DosExecPgm(%s %s) failed, %s - %s", + cmdline, args ? args : "", ap_os_error_message(rc), error_object ); + return -1; } - return (pid); + + return rescodes.codeTerminate; } #elif defined(WIN32) { - /* Adapted from Alec Kloss' work for OS/2 */ - int is_script = 0; - int is_binary = 0; - char interpreter[2048]; /* hope it's enough for the interpreter path */ - FILE *program; - int i, sz; - char *dot; - char *exename; + /* Adapted from Alec Kloss' work for OS/2 */ + char *interpreter = NULL; + char *arguments = NULL; + char *ext = NULL; + char *exename = NULL; + char *s = NULL; char *quoted_filename; - int is_exe = 0; - STARTUPINFO si; - PROCESS_INFORMATION pi; char *pCommand; char *pEnvBlock, *pNext; + + int i; int iEnvBlockLen; - memset(&si, 0, sizeof(si)); - memset(&pi, 0, sizeof(pi)); + file_type_e fileType; + + STARTUPINFO si; + PROCESS_INFORMATION pi; - interpreter[0] = 0; - pid = -1; + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); - quoted_filename = ap_pstrcat(r->pool, "\"", r->filename, "\"", NULL); + pid = -1; if (!shellcmd) { - exename = strrchr(r->filename, '/'); - if (!exename) { - exename = strrchr(r->filename, '\\'); - } - if (!exename) { - exename = r->filename; - } - else { - exename++; - } - dot = strrchr(exename, '.'); - if (dot) { - if (!strcasecmp(dot, ".BAT") - || !strcasecmp(dot, ".CMD") - || !strcasecmp(dot, ".EXE") - || !strcasecmp(dot, ".COM")) { - is_exe = 1; - } + + fileType = ap_get_win32_interpreter(r, &interpreter); + + if (fileType == eFileTypeUNKNOWN) { + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r, + "%s is not executable; ensure interpreted scripts have " + "\"#!\" first line", + r->filename); + return (pid); } - if (!is_exe) { - program = fopen(r->filename, "rb"); - if (!program) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "fopen(%s) failed", r->filename); - return (pid); - } - sz = fread(interpreter, 1, sizeof(interpreter) - 1, program); - if (sz < 0) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "fread of %s failed", r->filename); - fclose(program); - return (pid); - } - interpreter[sz] = 0; - fclose(program); - if (!strncmp(interpreter, "#!", 2)) { - is_script = 1; - for (i = 2; i < sizeof(interpreter); i++) { - if ((interpreter[i] == '\r') - || (interpreter[i] == '\n')) { - break; - } - } - interpreter[i] = 0; - for (i = 2; interpreter[i] == ' '; ++i) - ; - memmove(interpreter+2,interpreter+i,strlen(interpreter+i)+1); - } - else { - /* Check to see if it's a executable */ - IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)interpreter; - if (hdr->e_magic == IMAGE_DOS_SIGNATURE && hdr->e_cblp < 512) { - is_binary = 1; + /* + * Look at the arguments... + */ + arguments = ""; + if ((r->args) && (r->args[0]) && !strchr(r->args, '=')) { + /* If we are in this leg, there are some other arguments + * that we must include in the execution of the CGI. + * Because CreateProcess is the way it is, we have to + * create a command line like format for the execution + * of the CGI. This means we need to create on long + * string with the executable and arguments. + * + * The arguments string comes in the request structure, + * and each argument is separated by a '+'. We'll replace + * these pluses with spaces. + */ + + int iStringSize = 0; + int x; + + /* + * Duplicate the request structure string so we don't change it. + */ + arguments = ap_pstrdup(r->pool, r->args); + + /* + * Change the '+' to ' ' + */ + for (x=0; arguments[x]; x++) { + if ('+' == arguments[x]) { + arguments[x] = ' '; } } + + /* + * We need to unescape any characters that are + * in the arguments list. + */ + ap_unescape_url(arguments); + arguments = ap_escape_shell_cmd(r->pool, arguments); } - /* Bail out if we haven't figured out what kind of - * file this is by now.. + + /* + * We have the interpreter (if there is one) and we have + * the arguments (if there are any). + * Build the command string to pass to CreateProcess. */ - if (!is_exe && !is_script && !is_binary) { - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r, - "%s is not executable; ensure interpreted scripts have " - "\"#!\" first line", - r->filename); - return (pid); + quoted_filename = ap_pstrcat(r->pool, "\"", r->filename, "\"", NULL); + if (interpreter && *interpreter) { + pCommand = ap_pstrcat(r->pool, interpreter, " ", + quoted_filename, " ", arguments, NULL); + } + else { + pCommand = ap_pstrcat(r->pool, quoted_filename, " ", arguments, NULL); } - } - if (shellcmd) { + } else { + char *shell_cmd = "CMD.EXE /C "; OSVERSIONINFO osver; osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); @@ -929,96 +985,17 @@ API_EXPORT(int) ap_call_exec(request_rec *r, child_info *pinfo, char *argv0, } pCommand = ap_pstrcat(r->pool, shell_cmd, argv0, NULL); } - else if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) { - if (is_exe || is_binary) { - /* - * When the CGI is a straight binary executable, - * we can run it as is - */ - pCommand = quoted_filename; - } - else if (is_script) { - /* When an interpreter is needed, we need to create - * a command line that has the interpreter name - * followed by the CGI script name. - */ - pCommand = ap_pstrcat(r->pool, interpreter + 2, " ", - quoted_filename, NULL); - } - else { - /* If not an executable or script, just execute it - * from a command prompt. - */ - pCommand = ap_pstrcat(r->pool, SHELL_PATH, " /C ", - quoted_filename, NULL); - } - } - else { - /* If we are in this leg, there are some other arguments - * that we must include in the execution of the CGI. - * Because CreateProcess is the way it is, we have to - * create a command line like format for the execution - * of the CGI. This means we need to create on long - * string with the executable and arguments. - * - * The arguments string comes in the request structure, - * and each argument is separated by a '+'. We'll replace - * these pluses with spaces. - */ - char *arguments=NULL; - int iStringSize = 0; - int x; - - /* - * Duplicate the request structure string so we don't change it. - */ - arguments = ap_pstrdup(r->pool, r->args); - - /* - * Change the '+' to ' ' - */ - for (x=0; arguments[x]; x++) { - if ('+' == arguments[x]) { - arguments[x] = ' '; - } - } - - /* - * We need to unescape any characters that are - * in the arguments list. - */ - ap_unescape_url(arguments); - arguments = ap_escape_shell_cmd(r->pool, arguments); - - /* - * The argument list should now be good to use, - * so now build the command line. - */ - if (is_exe || is_binary) { - pCommand = ap_pstrcat(r->pool, quoted_filename, " ", - arguments, NULL); - } - else if (is_script) { - pCommand = ap_pstrcat(r->pool, interpreter + 2, " ", - quoted_filename, " ", arguments, NULL); - } - else { - pCommand = ap_pstrcat(r->pool, SHELL_PATH, " /C ", - quoted_filename, " ", arguments, NULL); - } - } - - /* - * Make child process use hPipeOutputWrite as standard out, - * and make sure it does not show on screen. - */ - si.cb = sizeof(si); - si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; - si.wShowWindow = SW_HIDE; - si.hStdInput = pinfo->hPipeInputRead; - si.hStdOutput = pinfo->hPipeOutputWrite; - si.hStdError = pinfo->hPipeErrorWrite; + /* + * Make child process use hPipeOutputWrite as standard out, + * and make sure it does not show on screen. + */ + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + si.wShowWindow = SW_HIDE; + si.hStdInput = pinfo->hPipeInputRead; + si.hStdOutput = pinfo->hPipeOutputWrite; + si.hStdError = pinfo->hPipeErrorWrite; /* * Win32's CreateProcess call requires that the environment @@ -1042,60 +1019,31 @@ API_EXPORT(int) ap_call_exec(request_rec *r, child_info *pinfo, char *argv0, i++; } - if (CreateProcess(NULL, pCommand, NULL, NULL, TRUE, 0, pEnvBlock, + if (CreateProcess(NULL, pCommand, NULL, NULL, TRUE, DETACHED_PROCESS, pEnvBlock, ap_make_dirstr_parent(r->pool, r->filename), &si, &pi)) { - pid = pi.dwProcessId; - /* - * We must close the handles to the new process and its main thread - * to prevent handle and memory leaks. - */ - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } else { - if (is_script) { - /* since we are doing magic to find what we are executing - * if running a script, log what we think we should have - * executed - */ - ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, r, - "could not run script interpreter: %s", pCommand); - } - } -#if 0 - if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) { - if (is_exe || is_binary) { - pid = spawnle(_P_NOWAIT, r->filename, r->filename, NULL, env); - } - else if (is_script) { - pid = spawnle(_P_NOWAIT, interpreter + 2, interpreter + 2, - r->filename, NULL, env); - } - else { - pid = spawnle(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/C", - r->filename, NULL, env); - } - } - else { - if (is_exe || is_binary) { - pid = spawnve(_P_NOWAIT, r->filename, - create_argv(r->pool, NULL, NULL, NULL, argv0, - r->args), env); - } - else if (is_script) { - pid = spawnve(_P_NOWAIT, interpreter + 2, - create_argv(r->pool, interpreter + 2, NULL, NULL, - r->filename, r->args), env); - } - else { - pid = spawnve(_P_NOWAIT, SHELL_PATH, - create_argv_cmd(r->pool, argv0, r->args, - r->filename), env); - } - } -#endif - return (pid); + if (fileType == eFileTypeEXE16) { + /* Hack to get 16-bit CGI's working. It works for all the + * standard modules shipped with Apache. pi.dwProcessId is 0 + * for 16-bit CGIs and all the Unix specific code that calls + * ap_call_exec interprets this as a failure case. And we can't + * use -1 either because it is mapped to 0 by the caller. + */ + pid = -2; + } + else { + pid = pi.dwProcessId; + /* + * We must close the handles to the new process and its main thread + * to prevent handle and memory leaks. + */ + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + } + return (pid); } + #else if (ap_suexec_enabled && ((r->server->server_uid != ap_user_id) diff --git a/usr.sbin/httpd/src/main/util_uri.c b/usr.sbin/httpd/src/main/util_uri.c index d34dbd1852f..10eb5dc0d00 100644 --- a/usr.sbin/httpd/src/main/util_uri.c +++ b/usr.sbin/httpd/src/main/util_uri.c @@ -186,11 +186,18 @@ API_EXPORT(char *) ap_unparse_uri_components(pool *p, const uri_components *uptr /* Construct scheme://site string */ if (uptr->hostname) { + int is_default_port; + + is_default_port = + (uptr->port_str == NULL || + uptr->port == 0 || + uptr->port == ap_default_port_for_scheme(uptr->scheme)); + ret = ap_pstrcat (p, uptr->scheme, "://", ret, uptr->hostname ? uptr->hostname : "", - uptr->port_str ? ":" : "", - uptr->port_str ? uptr->port_str : "", + is_default_port ? "" : ":", + is_default_port ? "" : uptr->port_str, NULL); } } @@ -266,8 +273,8 @@ void ap_util_uri_init(void) /* This is a sub-RE which will break down the hostinfo part, * i.e., user, password, hostname and port. * $ 12 3 4 5 6 7 */ - re_str = "^(([^:]*)(:(.*))?@)?([^@:]*)(:(.*))?$"; - /* ^^user^ :pw ^host^ port */ + re_str = "^(([^:]*)(:(.*))?@)?([^@:]*)(:([0-9]*))?$"; + /* ^^user^ :pw ^host^ ^:[port]^ */ if ((ret = regcomp(&re_hostpart, re_str, REG_EXTENDED)) != 0) { char line[1024]; @@ -306,11 +313,11 @@ API_EXPORT(int) ap_parse_uri_components(pool *p, const char *uri, uri_components memset (uptr, '\0', sizeof(*uptr)); uptr->is_initialized = 1; - ret = regexec(&re_uri, uri, re_uri.re_nsub + 1, match, 0); + ret = ap_regexec(&re_uri, uri, re_uri.re_nsub + 1, match, 0); if (ret != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL, - "regexec() could not parse uri (\"%s\")", + "ap_regexec() could not parse uri (\"%s\")", uri); return HTTP_BAD_REQUEST; @@ -336,18 +343,18 @@ API_EXPORT(int) ap_parse_uri_components(pool *p, const char *uri, uri_components if (uptr->hostinfo) { /* Parse the hostinfo part to extract user, password, host, and port */ - ret = regexec(&re_hostpart, uptr->hostinfo, re_hostpart.re_nsub + 1, match, 0); + ret = ap_regexec(&re_hostpart, uptr->hostinfo, re_hostpart.re_nsub + 1, match, 0); if (ret != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL, - "regexec() could not parse (\"%s\") as host part", + "ap_regexec() could not parse (\"%s\") as host part", uptr->hostinfo); return HTTP_BAD_REQUEST; } - /* $ 12 3 4 5 6 7 */ - /* = "^(([^:]*)(:(.*))?@)?([^@:]*)(:(.*))?$" */ - /* ^^user^ :pw ^host^ port */ + /* $ 12 3 4 5 6 7 */ + /* "^(([^:]*)(:(.*))?@)?([^@:]*)(:([0-9]*))?$" */ + /* ^^user^ :pw ^host^ ^:[port]^ */ /* empty user is valid, that's why we test $1 but use $2 */ if (match[1].rm_so != match[1].rm_eo) @@ -371,7 +378,7 @@ API_EXPORT(int) ap_parse_uri_components(pool *p, const char *uri, uri_components port = strtol(uptr->port_str, &endstr, 10); uptr->port = port; - if (*endstr != '\0' || uptr->port != port) { + if (*endstr != '\0') { /* Invalid characters after ':' found */ return HTTP_BAD_REQUEST; } diff --git a/usr.sbin/httpd/src/modules/example/mod_example.c b/usr.sbin/httpd/src/modules/example/mod_example.c index 764b1550a96..68a6b06fe3a 100644 --- a/usr.sbin/httpd/src/modules/example/mod_example.c +++ b/usr.sbin/httpd/src/modules/example/mod_example.c @@ -525,7 +525,7 @@ static int example_handler(request_rec *r) * Now send our actual output. Since we tagged this as being * "text/html", we need to embed any HTML. */ - ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n", r); + ap_rputs(DOCTYPE_HTML_3_2, r); ap_rputs("<HTML>\n", r); ap_rputs(" <HEAD>\n", r); ap_rputs(" <TITLE>mod_example Module Content-Handler Output\n", r); diff --git a/usr.sbin/httpd/src/modules/experimental/Makefile.tmpl b/usr.sbin/httpd/src/modules/experimental/Makefile.tmpl index 7b9e1c749de..371167d6cd1 100644 --- a/usr.sbin/httpd/src/modules/experimental/Makefile.tmpl +++ b/usr.sbin/httpd/src/modules/experimental/Makefile.tmpl @@ -12,3 +12,12 @@ mod_mmap_static.o: mod_mmap_static.c $(INCDIR)/httpd.h \ $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ $(INCDIR)/http_log.h $(INCDIR)/http_protocol.h \ $(INCDIR)/http_request.h $(INCDIR)/http_core.h +mod_digest.o: mod_digest.c $(INCDIR)/httpd.h \ + $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ + $(INCDIR)/http_core.h $(INCDIR)/http_log.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/util_md5.h \ + $(INCDIR)/ap_md5.h diff --git a/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.dsp b/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.dsp index 9c94df590e9..6ee5cf30ddd 100644 --- a/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.dsp +++ b/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.dsp @@ -45,7 +45,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -55,7 +55,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /machine:I386 !ELSEIF "$(CFG)" == "ApacheModuleProxy - Win32 Debug" @@ -71,7 +71,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -81,7 +81,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 !ENDIF diff --git a/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.mak b/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.mak index 95541504be3..b7074715e8d 100644 --- a/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.mak +++ b/usr.sbin/httpd/src/modules/proxy/ApacheModuleProxy.mak @@ -30,6 +30,10 @@ NULL= NULL=nul !ENDIF +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + !IF "$(CFG)" == "ApacheModuleProxy - Win32 Release" OUTDIR=.\Release @@ -63,53 +67,20 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP=cl.exe CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D\ - "_WINDOWS" /D "SHARED_MODULE" /Fp"$(INTDIR)\ApacheModuleProxy.pch" /YX\ - /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + "_WINDOWS" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN"\ + /Fp"$(INTDIR)\ApacheModuleProxy.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ + /c CPP_OBJS=.\Release/ CPP_SBRS=. - -.c{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_OBJS)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(CPP_SBRS)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\ApacheModuleProxy.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ - winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo\ /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\ApacheModuleProxy.pdb"\ /machine:I386 /out:"$(OUTDIR)\ApacheModuleProxy.dll"\ /implib:"$(OUTDIR)\ApacheModuleProxy.lib" @@ -162,12 +133,37 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D\ - "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /Fp"$(INTDIR)\ApacheModuleProxy.pch"\ - /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + "WIN32" /D "_WINDOWS" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN"\ + /Fp"$(INTDIR)\ApacheModuleProxy.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD\ + /c CPP_OBJS=.\Debug/ CPP_SBRS=. +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\ApacheModuleProxy.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo\ + /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\ApacheModuleProxy.pdb"\ + /debug /machine:I386 /out:"$(OUTDIR)\ApacheModuleProxy.dll"\ + /implib:"$(OUTDIR)\ApacheModuleProxy.lib" +LINK32_OBJS= \ + "$(INTDIR)\mod_proxy.obj" \ + "$(INTDIR)\proxy_cache.obj" \ + "$(INTDIR)\proxy_connect.obj" \ + "$(INTDIR)\proxy_ftp.obj" \ + "$(INTDIR)\proxy_http.obj" \ + "$(INTDIR)\proxy_util.obj" + +"$(OUTDIR)\ApacheModuleProxy.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF .c{$(CPP_OBJS)}.obj:: $(CPP) @<< @@ -199,34 +195,6 @@ CPP_SBRS=. $(CPP_PROJ) $< << -MTL=midl.exe -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\ApacheModuleProxy.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ - winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo\ - /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\ApacheModuleProxy.pdb"\ - /debug /machine:I386 /out:"$(OUTDIR)\ApacheModuleProxy.dll"\ - /implib:"$(OUTDIR)\ApacheModuleProxy.lib" -LINK32_OBJS= \ - "$(INTDIR)\mod_proxy.obj" \ - "$(INTDIR)\proxy_cache.obj" \ - "$(INTDIR)\proxy_connect.obj" \ - "$(INTDIR)\proxy_ftp.obj" \ - "$(INTDIR)\proxy_http.obj" \ - "$(INTDIR)\proxy_util.obj" - -"$(OUTDIR)\ApacheModuleProxy.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - !IF "$(CFG)" == "ApacheModuleProxy - Win32 Release" || "$(CFG)" ==\ "ApacheModuleProxy - Win32 Debug" @@ -239,6 +207,7 @@ DEP_CPP_MOD_P=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ @@ -264,12 +233,14 @@ DEP_CPP_MOD_P=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ "..\..\include\http_config.h"\ "..\..\include\http_log.h"\ "..\..\include\http_protocol.h"\ + "..\..\include\http_request.h"\ "..\..\include\http_vhost.h"\ "..\..\include\httpd.h"\ "..\..\include\util_uri.h"\ @@ -293,9 +264,11 @@ DEP_CPP_PROXY=\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ "..\..\include\ap_md5.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ + "..\..\include\http_conf_globals.h"\ "..\..\include\http_config.h"\ "..\..\include\http_log.h"\ "..\..\include\http_main.h"\ @@ -320,9 +293,11 @@ DEP_CPP_PROXY=\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ "..\..\include\ap_md5.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ + "..\..\include\http_conf_globals.h"\ "..\..\include\http_config.h"\ "..\..\include\http_log.h"\ "..\..\include\http_main.h"\ @@ -350,6 +325,7 @@ DEP_CPP_PROXY_=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ @@ -374,6 +350,7 @@ DEP_CPP_PROXY_=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ @@ -402,10 +379,12 @@ DEP_CPP_PROXY_F=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ "..\..\include\http_config.h"\ + "..\..\include\http_core.h"\ "..\..\include\http_log.h"\ "..\..\include\http_main.h"\ "..\..\include\http_protocol.h"\ @@ -426,10 +405,12 @@ DEP_CPP_PROXY_F=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ "..\..\include\http_config.h"\ + "..\..\include\http_core.h"\ "..\..\include\http_log.h"\ "..\..\include\http_main.h"\ "..\..\include\http_protocol.h"\ @@ -454,6 +435,7 @@ DEP_CPP_PROXY_H=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ @@ -480,6 +462,7 @@ DEP_CPP_PROXY_H=\ "..\..\include\ap.h"\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ @@ -511,6 +494,7 @@ DEP_CPP_PROXY_U=\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ "..\..\include\ap_md5.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ @@ -520,6 +504,7 @@ DEP_CPP_PROXY_U=\ "..\..\include\http_protocol.h"\ "..\..\include\httpd.h"\ "..\..\include\multithread.h"\ + "..\..\include\util_date.h"\ "..\..\include\util_uri.h"\ "..\..\os\win32\os.h"\ "..\..\os\win32\readdir.h"\ @@ -537,6 +522,7 @@ DEP_CPP_PROXY_U=\ "..\..\include\ap_config.h"\ "..\..\include\ap_ctype.h"\ "..\..\include\ap_md5.h"\ + "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ "..\..\include\explain.h"\ "..\..\include\hsregex.h"\ @@ -546,6 +532,7 @@ DEP_CPP_PROXY_U=\ "..\..\include\http_protocol.h"\ "..\..\include\httpd.h"\ "..\..\include\multithread.h"\ + "..\..\include\util_date.h"\ "..\..\include\util_uri.h"\ "..\..\os\win32\os.h"\ "..\..\os\win32\readdir.h"\ diff --git a/usr.sbin/httpd/src/modules/proxy/Makefile.tmpl b/usr.sbin/httpd/src/modules/proxy/Makefile.tmpl index f7d560ad909..906de39cf8a 100644 --- a/usr.sbin/httpd/src/modules/proxy/Makefile.tmpl +++ b/usr.sbin/httpd/src/modules/proxy/Makefile.tmpl @@ -21,7 +21,12 @@ libproxy.so: $(OBJS_PIC) rm -f $@ $(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $(OBJS_PIC) $(LIBS_SHLIB) -.SUFFIXES: .o .lo +libproxy.dll: $(OBJS_PIC) mod_proxy.def + $(LD_SHLIB) $(LDFLAGS_SHLIB) -o $* $(OBJS_PIC) $(LIBS_SHLIB) + emxbind -b -q -s -h0 -dmod_proxy.def $* && \ + rm $* + +.SUFFIXES: .o .lo .dll .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< diff --git a/usr.sbin/httpd/src/modules/proxy/mod_proxy.c b/usr.sbin/httpd/src/modules/proxy/mod_proxy.c index f5fcf29af6b..cfd3aa1d372 100644 --- a/usr.sbin/httpd/src/modules/proxy/mod_proxy.c +++ b/usr.sbin/httpd/src/modules/proxy/mod_proxy.c @@ -607,7 +607,7 @@ static const char * ap_get_module_config(s->module_config, &proxy_module); int *New; - if (!isdigit(arg[0])) + if (!ap_isdigit(arg[0])) return "AllowCONNECT: port number must be numeric"; New = ap_push_array(conf->allowed_connect_ports); diff --git a/usr.sbin/httpd/src/modules/proxy/mod_proxy.h b/usr.sbin/httpd/src/modules/proxy/mod_proxy.h index 61760c4c21a..9eb3428d80c 100644 --- a/usr.sbin/httpd/src/modules/proxy/mod_proxy.h +++ b/usr.sbin/httpd/src/modules/proxy/mod_proxy.h @@ -301,7 +301,7 @@ void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength); int ap_proxy_hex2sec(const char *x); void ap_proxy_sec2hex(int t, char *y); cache_req *ap_proxy_cache_error(cache_req *r); -int ap_proxyerror(request_rec *r, const char *message); +int ap_proxyerror(request_rec *r, int statuscode, const char *message); const char *ap_proxy_host2addr(const char *host, struct hostent *reqhp); int ap_proxy_is_ipaddr(struct dirconn_entry *This, pool *p); int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p); diff --git a/usr.sbin/httpd/src/modules/proxy/proxy_cache.c b/usr.sbin/httpd/src/modules/proxy/proxy_cache.c index 46951f62ba9..90de9a057e1 100644 --- a/usr.sbin/httpd/src/modules/proxy/proxy_cache.c +++ b/usr.sbin/httpd/src/modules/proxy/proxy_cache.c @@ -69,6 +69,10 @@ #endif /* WIN32 */ #include "multithread.h" #include "ap_md5.h" +#ifdef __TANDEM +#include <sys/types.h> +#include <sys/stat.h> +#endif DEF_Explain @@ -102,8 +106,7 @@ typedef struct { #define ROUNDUP2BLOCKS(_bytes) (((_bytes)+block_size-1) & ~(block_size-1)) static long block_size = 512; /* this must be a power of 2 */ static long61_t curbytes, cachesize; -static time_t every, garbage_now, garbage_expire; -static char *filename; +static time_t garbage_now, garbage_expire; static mutex *garbage_mutex = NULL; @@ -119,6 +122,7 @@ int ap_proxy_garbage_init(server_rec *r, pool *p) static int sub_garbage_coll(request_rec *r, array_header *files, const char *cachedir, const char *cachesubdir); static void help_proxy_garbage_coll(request_rec *r); +static int should_proxy_garbage_coll(request_rec *r); #if !defined(WIN32) && !defined(MPE) && !defined(OS2) static void detached_proxy_garbage_coll(request_rec *r); #endif @@ -138,10 +142,11 @@ void ap_proxy_garbage_coll(request_rec *r) (void) ap_release_mutex(garbage_mutex); ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */ + if (should_proxy_garbage_coll(r)) #if !defined(WIN32) && !defined(MPE) && !defined(OS2) - detached_proxy_garbage_coll(r); + detached_proxy_garbage_coll(r); #else - help_proxy_garbage_coll(r); + help_proxy_garbage_coll(r); #endif ap_unblock_alarms(); @@ -205,6 +210,10 @@ static void detached_proxy_garbage_coll(request_rec *r) int status; pid_t pgrp; +#if 0 + ap_log_error(APLOG_MARK, APLOG_DEBUG, r->server, + "proxy: Guess what; we fork() again..."); +#endif switch (pid = fork()) { case -1: ap_log_error(APLOG_MARK, APLOG_ERR, r->server, @@ -264,27 +273,27 @@ static void detached_proxy_garbage_coll(request_rec *r) } #endif /* ndef WIN32 */ -static void help_proxy_garbage_coll(request_rec *r) +#define DOT_TIME "/.time" /* marker */ + +static int should_proxy_garbage_coll(request_rec *r) { - const char *cachedir; void *sconf = r->server->module_config; proxy_server_conf *pconf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); const struct cache_conf *conf = &pconf->cache; - array_header *files; - struct stat buf; - struct gc_ent *fent; - int i, timefd; - static time_t lastcheck = BAD_DATE; /* static (per-process) data!!! */ - cachedir = conf->root; - /* configured size is given in kB. Make it bytes, convert to long61_t: */ - cachesize.lower = cachesize.upper = 0; - add_long61(&cachesize, conf->space << 10); - every = conf->gcinterval; + const char *cachedir = conf->root; + char *filename; + struct stat buf; + int timefd; + time_t every = conf->gcinterval; + static time_t lastcheck = BAD_DATE; /* static (per-process) data!!! */ if (cachedir == NULL || every == -1) - return; + return 0; + + filename = ap_palloc(r->pool, strlen(cachedir) + strlen( DOT_TIME ) +1); + garbage_now = time(NULL); /* Usually, the modification time of <cachedir>/.time can only increase. * Thus, even with several child processes having their own copy of @@ -292,41 +301,68 @@ static void help_proxy_garbage_coll(request_rec *r) * for GC yet. */ if (garbage_now != -1 && lastcheck != BAD_DATE && garbage_now < lastcheck + every) - return; - - ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */ - - filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); - strcpy(filename, cachedir); - strcat(filename, "/.time"); - if (stat(filename, &buf) == -1) { /* does not exist */ - if (errno != ENOENT) { - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "proxy: stat(%s)", filename); - ap_unblock_alarms(); - return; - } - if ((timefd = creat(filename, 0666)) == -1) { - if (errno != EEXIST) - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "proxy: creat(%s)", filename); - else - lastcheck = garbage_now; /* someone else got in there */ - ap_unblock_alarms(); - return; - } - close(timefd); + return 0; + + strcpy(filename,cachedir); + strcat(filename,DOT_TIME); + + /* At this point we have a bit of an engineering compromise. We could either + * create and/or mark the .time file (prior to the fork which might + * fail on a resource issue) or wait until we are safely forked. The + * advantage of doing it now in this process is that we get some + * usefull live out of the global last check variable. (XXX which + * should go scoreboard IMHO.) Note that the actual counting is + * at a later moment. + */ + if (stat(filename, &buf) == -1) { /* does not exist */ + if (errno != ENOENT) { + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "proxy: stat(%s)", filename); + return 0; + } + if ((timefd = creat(filename, 0666)) == -1) { + if (errno != EEXIST) + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "proxy: creat(%s)", filename); + else + lastcheck = garbage_now; /* someone else got in there */ + return 0; + } + close(timefd); } else { - lastcheck = buf.st_mtime; /* save the time */ - if (garbage_now < lastcheck + every) { - ap_unblock_alarms(); - return; - } - if (utime(filename, NULL) == -1) - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "proxy: utimes(%s)", filename); + lastcheck = buf.st_mtime; /* save the time */ + if (garbage_now < lastcheck + every) { + return 0; + } + if (utime(filename, NULL) == -1) + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "proxy: utimes(%s)", filename); } + + return 1; +} + +static void help_proxy_garbage_coll(request_rec *r) +{ + const char *cachedir; + void *sconf = r->server->module_config; + proxy_server_conf *pconf = + (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + const struct cache_conf *conf = &pconf->cache; + array_header *files; + struct gc_ent *fent; + char *filename; + int i; + + cachedir = conf->root; + filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); + /* configured size is given in kB. Make it bytes, convert to long61_t: */ + cachesize.lower = cachesize.upper = 0; + add_long61(&cachesize, conf->space << 10); + + ap_block_alarms(); /* avoid SIGALRM on big cache cleanup */ + files = ap_make_array(r->pool, 100, sizeof(struct gc_ent)); curbytes.upper = curbytes.lower = 0L; @@ -385,8 +421,10 @@ static int sub_garbage_coll(request_rec *r, array_header *files, #endif struct gc_ent *fent; int nfiles = 0; + char *filename; ap_snprintf(cachedir, sizeof(cachedir), "%s%s", cachebasedir, cachesubdir); + filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); Explain1("GC Examining directory %s", cachedir); dir = opendir(cachedir); if (dir == NULL) { @@ -777,7 +815,7 @@ int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf, int ap_proxy_cache_update(cache_req *c, table *resp_hdrs, const int is_HTTP1, int nocache) { -#ifdef ULTRIX_BRAIN_DEATH +#if defined(ULTRIX_BRAIN_DEATH) || defined(SINIX_D_RESOLVER_BUG) extern char *mktemp(char *template); #endif request_rec *r = c->req; @@ -826,7 +864,7 @@ int ap_proxy_cache_update(cache_req *c, table *resp_hdrs, * requests with an Authorization header, or * protocol requests nocache (e.g. ftp with user/password) */ -/* @@@ XXX FIXME: is the test "r->status != HTTP_MOVED_PERMANENTLY" corerct? +/* @@@ XXX FIXME: is the test "r->status != HTTP_MOVED_PERMANENTLY" correct? * or shouldn't it be "ap_is_HTTP_REDIRECT(r->status)" ? -MnKr */ if ((r->status != HTTP_OK && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) || (expire != NULL && expc == BAD_DATE) || @@ -999,14 +1037,19 @@ int ap_proxy_cache_update(cache_req *c, table *resp_hdrs, strcpy(c->tempfile, conf->cache.root); strcat(c->tempfile, TMPFILESTR); #undef TMPFILESTR - i = mkstemp(c->tempfile); + p = mktemp(c->tempfile); + if (p == NULL) + return DECLINED; + + Explain1("Create temporary file %s", c->tempfile); + + i = open(c->tempfile, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0622); if (i == -1) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating cache file %s", c->tempfile); return DECLINED; } - ap_note_cleanups_for_fd(r->pool, i); c->fp = ap_bcreate(r->pool, B_WR); ap_bpushfd(c->fp, -1, i); @@ -1101,6 +1144,8 @@ void ap_proxy_cache_tidy(cache_req *c) *p = '\0'; #ifdef WIN32 if (mkdir(c->filename) < 0 && errno != EEXIST) +#elif defined(__TANDEM) + if (mkdir(c->filename, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) #else if (mkdir(c->filename, S_IREAD | S_IWRITE | S_IEXEC) < 0 && errno != EEXIST) #endif /* WIN32 */ diff --git a/usr.sbin/httpd/src/modules/proxy/proxy_connect.c b/usr.sbin/httpd/src/modules/proxy/proxy_connect.c index 9a19313c828..82203f2c9ef 100644 --- a/usr.sbin/httpd/src/modules/proxy/proxy_connect.c +++ b/usr.sbin/httpd/src/modules/proxy/proxy_connect.c @@ -148,7 +148,8 @@ int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url, for (i = 0; i < conf->noproxies->nelts; i++) { if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL) || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, "Connect to remote machine blocked"); + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); } /* Check if it is an allowed port */ @@ -175,7 +176,9 @@ int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url, err = ap_proxy_host2addr(proxyhost ? proxyhost : host, &server_hp); if (err != NULL) - return ap_proxyerror(r, err); /* give up */ + return ap_proxyerror(r, + proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, + err); sock = ap_psocket(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { @@ -184,7 +187,7 @@ int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url, return HTTP_INTERNAL_SERVER_ERROR; } -#ifndef WIN32 +#ifdef CHECK_FD_SETSIZE if (sock >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, "proxy_connect_handler: filedescriptor (%u) " @@ -207,7 +210,7 @@ int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url, } if (i == -1) { ap_pclosesocket(r->pool, sock); - return ap_proxyerror(r, ap_pstrcat(r->pool, + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool, "Could not connect to remote machine:<br>", strerror(errno), NULL)); } diff --git a/usr.sbin/httpd/src/modules/proxy/proxy_ftp.c b/usr.sbin/httpd/src/modules/proxy/proxy_ftp.c index 1cdade07730..47ca9daf9d4 100644 --- a/usr.sbin/httpd/src/modules/proxy/proxy_ftp.c +++ b/usr.sbin/httpd/src/modules/proxy/proxy_ftp.c @@ -60,6 +60,7 @@ #include "mod_proxy.h" #include "http_main.h" #include "http_log.h" +#include "http_core.h" #define AUTODETECT_PWD @@ -77,7 +78,7 @@ static int decodeenc(char *x) for (i = 0, j = 0; x[i] != '\0'; i++, j++) { /* decode it if not already done */ ch = x[i]; - if (ch == '%' && isxdigit(x[i + 1]) && isxdigit(x[i + 2])) { + if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) { ch = ap_proxy_hex2c(&x[i + 1]); i += 2; } @@ -97,7 +98,7 @@ static int ftp_check_string(const char *x) for (i = 0; x[i] != '\0'; i++) { ch = x[i]; - if (ch == '%' && isxdigit(x[i + 1]) && isxdigit(x[i + 2])) { + if (ch == '%' && ap_isxdigit(x[i + 1]) && ap_isxdigit(x[i + 2])) { ch = ap_proxy_hex2c(&x[i + 1]); i += 2; } @@ -290,7 +291,7 @@ static long int send_dir(BUFF *f, request_rec *r, cache_req *c, char *cwd) path[n-1] = '\0'; /* print "ftp://host/" */ - n = ap_snprintf(buf, sizeof(buf), "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" + n = ap_snprintf(buf, sizeof(buf), DOCTYPE_HTML_3_2 "<HTML><HEAD><TITLE>%s%s</TITLE>\n" "<BASE HREF=\"%s%s\"></HEAD>\n" "<BODY><H2>Directory of " @@ -322,8 +323,11 @@ static long int send_dir(BUFF *f, request_rec *r, cache_req *c, char *cwd) while (!con->aborted) { n = ap_bgets(buf, sizeof buf, f); if (n == -1) { /* input error */ - if (c != NULL) + if (c != NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error reading from %s", c->url); c = ap_proxy_cache_error(c); + } break; } if (n == 0) @@ -382,8 +386,11 @@ static long int send_dir(BUFF *f, request_rec *r, cache_req *c, char *cwd) o = 0; total_bytes_sent += n; - if (c != NULL && c->fp && ap_bwrite(c->fp, buf, n) != n) + if (c != NULL && c->fp && ap_bwrite(c->fp, buf, n) != n) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing to %s", c->tempfile); c = ap_proxy_cache_error(c); + } while (n && !r->connection->aborted) { w = ap_bwrite(con->client, &buf[o], n); @@ -503,7 +510,7 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) */ if ((password = ap_table_get(r->headers_in, "Authorization")) != NULL && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0 - && (password = ap_uudecode(r->pool, password))[0] != ':') { + && (password = ap_pbase64decode(r->pool, password))[0] != ':') { /* Note that this allocation has to be made from r->connection->pool * because it has the lifetime of the connection. The other allocations * are temporary and can be tossed away any time. @@ -533,7 +540,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) for (i = 0; i < conf->noproxies->nelts; i++) { if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL) || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, /*HTTP_FORBIDDEN*/ "Connect to remote machine blocked"); + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); } Explain2("FTP: connect to %s:%d", host, port); @@ -547,7 +555,7 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) server.sin_port = htons(port); err = ap_proxy_host2addr(host, &server_hp); if (err != NULL) - return ap_proxyerror(r, err); /* give up */ + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err); sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { @@ -598,7 +606,7 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) #endif if (i == -1) { ap_pclosesocket(p, sock); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ ap_pstrcat(r->pool, + return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool, "Could not connect to remote machine: ", strerror(errno), NULL)); } @@ -620,7 +628,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", i); if (i == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } #if 0 if (i == 120) { @@ -636,12 +645,12 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) * Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds ) */ ap_set_header("Retry-After", ap_psprintf(p, "%u", 60*wait_mins); - return ap_proxyerror(r, /*HTTP_SERVICE_UNAVAILABLE*/ resp); + return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, resp); } #endif if (i != 220) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ resp); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, resp); } Explain0("FTP: connected."); @@ -664,7 +673,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", i); if (i == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 530) { ap_kill_timeout(r); @@ -694,11 +704,13 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", i); if (i == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 332) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_UNAUTHORIZED*/ "Need account for login"); + return ap_proxyerror(r, HTTP_UNAUTHORIZED, + "Need account for login"); } /* @@@ questionable -- we might as well return a 403 Forbidden here */ if (i == 530) { @@ -738,7 +750,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", i); if (i == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { ap_kill_timeout(r); @@ -781,7 +794,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", i); if (i == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i != 200 && i != 504) { ap_kill_timeout(r); @@ -862,9 +876,10 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) if (i == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ ap_pstrcat(r->pool, - "Could not connect to remote machine: ", - strerror(errno), NULL)); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + ap_pstrcat(r->pool, + "Could not connect to remote machine: ", + strerror(errno), NULL)); } else { pasvmode = 1; @@ -952,7 +967,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", i); if (i == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { ap_kill_timeout(r); @@ -990,7 +1006,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: PWD returned status %d", i); if (i == -1 || i == 421) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { ap_kill_timeout(r); @@ -1034,7 +1051,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", rc); if (rc == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (rc == 550) { Explain0("FTP: RETR failed, trying LIST instead"); @@ -1054,7 +1072,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: returned status %d", rc); if (rc == -1) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (rc == 550) { ap_kill_timeout(r); @@ -1080,7 +1099,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: PWD returned status %d", i); if (i == -1 || i == 421) { ap_kill_timeout(r); - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } if (i == 550) { ap_kill_timeout(r); @@ -1098,7 +1118,8 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) rc = ftp_getrc(f); Explain1("FTP: returned status %d", rc); if (rc == -1) - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ "Error reading from remote server"); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); } ap_kill_timeout(r); if (rc != 125 && rc != 150 && rc != 226 && rc != 250) @@ -1110,15 +1131,18 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) resp_hdrs = ap_make_table(p, 2); c->hdrs = resp_hdrs; + ap_table_setn(resp_hdrs, "Date", ap_gm_timestr_822(r->pool, r->request_time)); + ap_table_setn(resp_hdrs, "Server", ap_get_server_version()); + if (parms[0] == 'd') - ap_table_set(resp_hdrs, "Content-Type", "text/html"); + ap_table_setn(resp_hdrs, "Content-Type", "text/html"); else { if (r->content_type != NULL) { - ap_table_set(resp_hdrs, "Content-Type", r->content_type); + ap_table_setn(resp_hdrs, "Content-Type", r->content_type); Explain1("FTP: Content-Type set to %s", r->content_type); } else { - ap_table_set(resp_hdrs, "Content-Type", "text/plain"); + ap_table_setn(resp_hdrs, "Content-Type", ap_default_type(r)); } if (parms[0] != 'a' && size != NULL) { /* We "trust" the ftp server to really serve (size) bytes... */ @@ -1126,6 +1150,10 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) Explain1("FTP: Content-Length set to %s", size); } } + if (r->content_encoding != NULL && r->content_encoding[0] != '\0') { + Explain1("FTP: Content-Encoding set to %s", r->content_encoding); + ap_table_setn(resp_hdrs, "Content-Encoding", r->content_encoding); + } /* check if NoCache directive on this host */ for (i = 0; i < conf->nocaches->nelts; i++) { @@ -1168,18 +1196,17 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) ap_bpushfd(data, dsock, dsock); } -#ifdef CHARSET_EBCDIC -/* bsetflag(data, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);*/ -#endif /*CHARSET_EBCDIC*/ - ap_hard_timeout("proxy receive", r); /* send response */ /* write status line */ if (!r->assbackwards) ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL); if (c != NULL && c->fp != NULL - && ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) - c = ap_proxy_cache_error(c); + && ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing CRLF to %s", c->tempfile); + c = ap_proxy_cache_error(c); + } /* send headers */ tdo.req = r; @@ -1188,8 +1215,11 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) if (!r->assbackwards) ap_rputs(CRLF, r); - if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) + if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing CRLF to %s", c->tempfile); c = ap_proxy_cache_error(c); + } ap_bsetopt(r->connection->client, BO_BYTECT, &zero); r->sent_bodyct = 1; @@ -1208,6 +1238,7 @@ int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url) /* XXX: we checked for 125||150||226||250 above. This is redundant. */ if (rc != 226 && rc != 250) + /* XXX: we no longer log an "error writing to c->tempfile" - should we? */ c = ap_proxy_cache_error(c); } else { diff --git a/usr.sbin/httpd/src/modules/proxy/proxy_http.c b/usr.sbin/httpd/src/modules/proxy/proxy_http.c index d43dd1ee112..b5cb31358c6 100644 --- a/usr.sbin/httpd/src/modules/proxy/proxy_http.c +++ b/usr.sbin/httpd/src/modules/proxy/proxy_http.c @@ -239,7 +239,8 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, for (i = 0; i < conf->noproxies->nelts; i++) { if ((npent[i].name != NULL && strstr(desthost, npent[i].name) != NULL) || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*') - return ap_proxyerror(r, "Connect to remote machine blocked"); + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); } if (proxyhost != NULL) { @@ -252,7 +253,7 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, server.sin_port = htons(destport); err = ap_proxy_host2addr(desthost, &server_hp); if (err != NULL) - return ap_proxyerror(r, err); /* give up */ + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err); } sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -297,7 +298,7 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, if (proxyhost != NULL) return DECLINED; /* try again another way */ else - return ap_proxyerror(r, /*HTTP_BAD_GATEWAY*/ ap_pstrcat(r->pool, + return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool, "Could not connect to remote machine: ", strerror(errno), NULL)); } @@ -315,7 +316,7 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, AP_HOOK_DECLINE(NULL), &errmsg, r, f); if (errmsg != NULL) - return ap_proxyerror(r, errmsg); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg); } #endif /* EAPI */ @@ -385,7 +386,7 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, } ap_bputs(CRLF, f); -/* send the request data, if any. N.B. should we trap SIGPIPE ? */ +/* send the request data, if any. */ if (ap_should_client_block(r)) { while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) @@ -397,13 +398,19 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, ap_hard_timeout("proxy receive", r); len = ap_bgets(buffer, sizeof buffer - 1, f); - if (len == -1 || len == 0) { + if (len == -1) { ap_bclose(f); ap_kill_timeout(r); ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "ap_bgets() - proxy receive - Error reading from remote server %s", - proxyhost ? proxyhost : desthost); - return ap_proxyerror(r, "Error reading from remote server"); + "ap_bgets() - proxy receive - Error reading from remote server %s (length %d)", + proxyhost ? proxyhost : desthost, len); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Error reading from remote server"); + } else if (len == 0) { + ap_bclose(f); + ap_kill_timeout(r); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Document contains no data"); } /* Is it an HTTP/1 response? This is buggy if we ever see an HTTP/1.10 */ @@ -512,8 +519,11 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, if (!r->assbackwards) ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL); if (c != NULL && c->fp != NULL && - ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) - c = ap_proxy_cache_error(c); + ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing status line to %s", c->tempfile); + c = ap_proxy_cache_error(c); + } /* send headers */ tdo.req = r; @@ -522,16 +532,22 @@ int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url, if (!r->assbackwards) ap_rputs(CRLF, r); - if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) + if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing CRLF to %s", c->tempfile); c = ap_proxy_cache_error(c); + } ap_bsetopt(r->connection->client, BO_BYTECT, &zero); r->sent_bodyct = 1; /* Is it an HTTP/0.9 respose? If so, send the extra data */ if (backasswards) { ap_bwrite(r->connection->client, buffer, len); - if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) != len) + if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) != len) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing extra data to %s", c->tempfile); c = ap_proxy_cache_error(c); + } } ap_kill_timeout(r); diff --git a/usr.sbin/httpd/src/modules/proxy/proxy_util.c b/usr.sbin/httpd/src/modules/proxy/proxy_util.c index 257b78bc848..c1258f14995 100644 --- a/usr.sbin/httpd/src/modules/proxy/proxy_util.c +++ b/usr.sbin/httpd/src/modules/proxy/proxy_util.c @@ -178,7 +178,7 @@ char * } /* decode it if not already done */ if (isenc && ch == '%') { - if (!isxdigit(x[i + 1]) || !isxdigit(x[i + 2])) + if (!ap_isxdigit(x[i + 1]) || !ap_isxdigit(x[i + 2])) return NULL; ch = ap_proxy_hex2c(&x[i + 1]); i += 2; @@ -491,15 +491,15 @@ table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f) long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c) { - int ok = 1; + int ok; char buf[IOBUFSIZE]; - long total_bytes_rcv; + long total_bytes_rcvd; register int n, o, w; conn_rec *con = r->connection; - int alt_to = 1; + int alternate_timeouts = 1; /* 1 if we alternate between soft & hard timeouts */ - total_bytes_rcv = 0; - if (c) + total_bytes_rcvd = 0; + if (c != NULL) c->written = 0; #ifdef CHARSET_EBCDIC @@ -520,65 +520,71 @@ long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c) #ifdef WIN32 /* works fine under win32, so leave it */ ap_hard_timeout("proxy send body", r); - alt_to = 0; + alternate_timeouts = 0; #else /* CHECKME! Since hard_timeout won't work in unix on sends with partial * cache completion, we have to alternate between hard_timeout * for reads, and soft_timeout for send. This is because we need * to get a return from ap_bwrite to be able to continue caching. * BUT, if we *can't* continue anyway, just use hard_timeout. + * (Also, if no cache file is written, use hard timeouts) */ - if (c) { - if (c->len <= 0 || c->cache_completion == 1) { - ap_hard_timeout("proxy send body", r); - alt_to = 0; - } - } else { + if (c == NULL || c->len <= 0 || c->cache_completion == 1.0) { ap_hard_timeout("proxy send body", r); - alt_to = 0; + alternate_timeouts = 0; } #endif - while (ok) { - if (alt_to) - ap_hard_timeout("proxy send body", r); + /* Loop and ap_bread() while we can successfully read and write, + * or (after the client aborted) while we can successfully + * read and finish the configured cache_completion. + */ + for (ok = 1; ok; ) { + if (alternate_timeouts) + ap_hard_timeout("proxy recv body from upstream server", r); /* Read block from server */ n = ap_bread(f, buf, IOBUFSIZE); - if (alt_to) + if (alternate_timeouts) ap_kill_timeout(r); else ap_reset_timeout(r); if (n == -1) { /* input error */ - if (c != NULL) + if (c != NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error reading from %s", c->url); c = ap_proxy_cache_error(c); + } break; } if (n == 0) break; /* EOF */ o = 0; - total_bytes_rcv += n; + total_bytes_rcvd += n; /* Write to cache first. */ + /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */ if (c != NULL && c->fp != NULL) { if (ap_bwrite(c->fp, &buf[0], n) != n) { - c = ap_proxy_cache_error(c); + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing to %s", c->tempfile); + c = ap_proxy_cache_error(c); } else { c->written += n; } } /* Write the block to the client, detect aborted transfers */ - while (n && !con->aborted) { - if (alt_to) + while (!con->aborted && n > 0) { + if (alternate_timeouts) ap_soft_timeout("proxy send body", r); w = ap_bwrite(con->client, &buf[o], n); - if (alt_to) + if (alternate_timeouts) ap_kill_timeout(r); else ap_reset_timeout(r); @@ -591,7 +597,7 @@ long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c) */ ok = (c->len > 0) && (c->cache_completion > 0) && - (c->len * c->cache_completion < total_bytes_rcv); + (c->len * c->cache_completion < total_bytes_rcvd); if (! ok) { ap_pclosef(c->req->pool, c->fp->fd); @@ -605,14 +611,14 @@ long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c) } n -= w; o += w; - } - } + } /* while client alive and more data to send */ + } /* loop and ap_bread while "ok" */ if (!con->aborted) ap_bflush(con->client); ap_kill_timeout(r); - return total_bytes_rcv; + return total_bytes_rcvd; } /* @@ -628,14 +634,11 @@ void ap_proxy_send_headers(request_rec *r, const char *respline, table *t) BUFF *fp = r->connection->client; table_entry *elts = (table_entry *) ap_table_elts(t)->elts; - ap_bputs(respline, fp); - ap_bputs(CRLF, fp); + ap_bvputs(fp, respline, CRLF, NULL); for (i = 0; i < ap_table_elts(t)->nelts; ++i) { if (elts[i].key != NULL) { ap_bvputs(fp, elts[i].key, ": ", elts[i].val, CRLF, NULL); - /* FIXME: @@@ This used to be ap_table_set(), but I think - * ap_table_addn() is correct. MnKr */ ap_table_addn(r->headers_out, elts[i].key, elts[i].val); } } @@ -826,15 +829,17 @@ void ap_proxy_sec2hex(int t, char *y) cache_req *ap_proxy_cache_error(cache_req *c) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, - "proxy: error writing to cache file %s", c->tempfile); - ap_pclosef(c->req->pool, c->fp->fd); - c->fp = NULL; - unlink(c->tempfile); + if (c != NULL) { + if (c->fp != NULL) { + ap_pclosef(c->req->pool, c->fp->fd); + c->fp = NULL; + } + if (c->tempfile) unlink(c->tempfile); + } return NULL; } -int ap_proxyerror(request_rec *r, const char *message) +int ap_proxyerror(request_rec *r, int statuscode, const char *message) { ap_table_setn(r->notes, "error-notes", ap_pstrcat(r->pool, @@ -842,8 +847,12 @@ int ap_proxyerror(request_rec *r, const char *message) "<EM><A HREF=\"", r->uri, "\">", r->method, " ", r->uri, "</A></EM>.<P>\n" "Reason: <STRONG>", message, "</STRONG>", NULL)); - r->status_line = "500 Proxy Error"; - return HTTP_INTERNAL_SERVER_ERROR; + + /* Allow the "error-notes" string to be printed by ap_send_error_response() */ + ap_table_setn(r->notes, "verbose-error-to", ap_pstrdup(r->pool, "*")); + + r->status_line = ap_psprintf(r->pool, "%3.3u Proxy Error", statuscode); + return statuscode; } /* @@ -1260,8 +1269,11 @@ int ap_proxy_send_hdr_line(void *p, const char *key, const char *value) if (!parm->req->assbackwards) ap_rvputs(parm->req, key, ": ", value, CRLF, NULL); if (parm->cache != NULL && parm->cache->fp != NULL && - ap_bvputs(parm->cache->fp, key, ": ", value, CRLF, NULL) == -1) + ap_bvputs(parm->cache->fp, key, ": ", value, CRLF, NULL) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, parm->cache->req, + "proxy: error writing header to %s", parm->cache->tempfile); parm->cache = ap_proxy_cache_error(parm->cache); + } return 1; /* tell ap_table_do() to continue calling us for more headers */ } diff --git a/usr.sbin/httpd/src/modules/ssl/Makefile.libdir b/usr.sbin/httpd/src/modules/ssl/Makefile.libdir index 499ce4a3d95..a4a4c32080a 100644 --- a/usr.sbin/httpd/src/modules/ssl/Makefile.libdir +++ b/usr.sbin/httpd/src/modules/ssl/Makefile.libdir @@ -1,8 +1,8 @@ ## _ _ -## _ __ ___ ___ __| | ___ ___| | -## | '_ ` _ \ / _ \ / _` | / __/ __| | -## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +## _ __ ___ ___ __| | ___ ___| | mod_ssl +## | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +## | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +## |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ## |_____| ## Makefile.libdir ## Apache 1.3 Configuration mechanism indicator file diff --git a/usr.sbin/httpd/src/modules/ssl/Makefile.tmpl b/usr.sbin/httpd/src/modules/ssl/Makefile.tmpl index 2181e709fe6..25d23f1eed0 100644 --- a/usr.sbin/httpd/src/modules/ssl/Makefile.tmpl +++ b/usr.sbin/httpd/src/modules/ssl/Makefile.tmpl @@ -1,8 +1,8 @@ ## _ _ -## _ __ ___ ___ __| | ___ ___| | -## | '_ ` _ \ / _ \ / _` | / __/ __| | -## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +## _ __ ___ ___ __| | ___ ___| | mod_ssl +## | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +## | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +## |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ## |_____| ## Makefile.tmpl ## Apache 1.3 Makefile template for SSL module (Unix environment) @@ -27,7 +27,7 @@ ## software must display the following acknowledgment: ## "This product includes software developed by ## Ralf S. Engelschall <rse@engelschall.com> for use in the -## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." +## mod_ssl project (http://www.modssl.org/)." ## ## 4. The names "mod_ssl" must not be used to endorse or promote ## products derived from this software without prior written @@ -42,7 +42,7 @@ ## acknowledgment: ## "This product includes software developed by ## Ralf S. Engelschall <rse@engelschall.com> for use in the -## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." +## mod_ssl project (http://www.modssl.org/)." ## ## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY ## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -71,6 +71,7 @@ OBJS=\ ssl_engine_config.o\ ssl_engine_compat.o\ ssl_engine_ds.o\ + ssl_engine_dh.o\ ssl_engine_init.o\ ssl_engine_kernel.o\ ssl_engine_rand.o\ @@ -87,13 +88,16 @@ OBJS=\ ssl_expr_eval.o\ ssl_util.o\ ssl_util_ssl.o\ - ssl_util_sdbm.o + ssl_util_sdbm.o\ + ssl_util_table.o\ + $(SSL_VENDOR_OBJS) OBJS_PIC=\ mod_ssl.lo\ ssl_engine_config.lo\ ssl_engine_compat.lo\ ssl_engine_ds.lo\ + ssl_engine_dh.lo\ ssl_engine_init.lo\ ssl_engine_kernel.lo\ ssl_engine_rand.lo\ @@ -110,7 +114,9 @@ OBJS_PIC=\ ssl_expr_eval.lo\ ssl_util.lo\ ssl_util_ssl.lo\ - ssl_util_sdbm.lo + ssl_util_sdbm.lo\ + ssl_util_table.lo\ + $(SSL_VENDOR_OBJS_PIC) ## ## END-USER AREA @@ -158,8 +164,10 @@ ssl_expr_scan.c: ssl_expr_scan.l ssl_expr_parse.h sed -e '/$$Header:/d' <lex.ssl_expr_yy.c >ssl_expr_scan.c && rm -f lex.ssl_expr_yy.c ssl_expr_parse.c ssl_expr_parse.h: ssl_expr_parse.y - yacc -d -l ssl_expr_parse.y - sed -e 's;yy;ssl_expr_yy;g' -e '/yysccsid/d' \ + yacc -d ssl_expr_parse.y + sed -e 's;yy;ssl_expr_yy;g' \ + -e '/#ifndef lint/,/#endif/d' \ + -e '/#if defined(c_plusplus) || defined(__cplusplus)/,/#endif/d' \ <y.tab.c >ssl_expr_parse.c && rm -f y.tab.c sed -e 's;yy;ssl_expr_yy;g' \ <y.tab.h >ssl_expr_parse.h && rm -f y.tab.h @@ -195,219 +203,274 @@ $(OBJS) $(OBJS_PIC): Makefile mod_ssl.o mod_ssl.lo: mod_ssl.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_compat.o ssl_engine_compat.lo: ssl_engine_compat.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_config.o ssl_engine_config.lo: ssl_engine_config.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ + $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ + $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h +ssl_engine_dh.o ssl_engine_dh.lo: ssl_engine_dh.c mod_ssl.h $(INCDIR)/ap_config.h \ + $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ + $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_ds.o ssl_engine_ds.lo: ssl_engine_ds.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_ext.o ssl_engine_ext.lo: ssl_engine_ext.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_init.o ssl_engine_init.lo: ssl_engine_init.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_io.o ssl_engine_io.lo: ssl_engine_io.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_kernel.o ssl_engine_kernel.lo: ssl_engine_kernel.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_log.o ssl_engine_log.lo: ssl_engine_log.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_mutex.o ssl_engine_mutex.lo: ssl_engine_mutex.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_pphrase.o ssl_engine_pphrase.lo: ssl_engine_pphrase.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_rand.o ssl_engine_rand.lo: ssl_engine_rand.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_scache.o ssl_engine_scache.lo: ssl_engine_scache.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_engine_vars.o ssl_engine_vars.lo: ssl_engine_vars.c mod_ssl.h \ $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_expr.o ssl_expr.lo: ssl_expr.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_expr_eval.o ssl_expr_eval.lo: ssl_expr_eval.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_expr_parse.o ssl_expr_parse.lo: ssl_expr_parse.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_expr_scan.o ssl_expr_scan.lo: ssl_expr_scan.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_expr_parse.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_expr_parse.h ssl_util.o ssl_util.lo: ssl_util.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_util_sdbm.o ssl_util_sdbm.lo: ssl_util_sdbm.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h ssl_util_ssl.o ssl_util_ssl.lo: ssl_util_ssl.c mod_ssl.h $(INCDIR)/ap_config.h \ $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ - $(INCDIR)/httpd.h $(INCDIR)/alloc.h $(INCDIR)/ap_hook.h \ - $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ - $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ - $(INCDIR)/http_conf_globals.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/httpd.h $(INCDIR)/ap_mm.h $(INCDIR)/alloc.h \ + $(INCDIR)/ap_hook.h $(INCDIR)/ap_ctx.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h \ + $(INCDIR)/http_config.h $(INCDIR)/http_conf_globals.h \ + $(INCDIR)/http_protocol.h $(INCDIR)/http_request.h \ $(INCDIR)/http_main.h $(INCDIR)/http_core.h \ $(INCDIR)/http_log.h $(INCDIR)/scoreboard.h \ - $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h + $(INCDIR)/fnmatch.h ssl_expr.h ssl_util_ssl.h ssl_util_table.h \ + ssl_util_sdbm.h +ssl_util_table.o ssl_util_table.lo: ssl_util_table.c ssl_util_table.h diff --git a/usr.sbin/httpd/src/modules/ssl/Makefile.win32 b/usr.sbin/httpd/src/modules/ssl/Makefile.win32 index 3cf7677078d..0e7976f26a3 100644 --- a/usr.sbin/httpd/src/modules/ssl/Makefile.win32 +++ b/usr.sbin/httpd/src/modules/ssl/Makefile.win32 @@ -1,8 +1,8 @@ ## _ _ -## _ __ ___ ___ __| | ___ ___| | -## | '_ ` _ \ / _ \ / _` | / __/ __| | -## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +## _ __ ___ ___ __| | ___ ___| | mod_ssl +## | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +## | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +## |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ## |_____| ## Makefile.win32 ## Apache 1.3 Makefile for SSL module (Win32 environment) @@ -28,7 +28,7 @@ ## software must display the following acknowledgment: ## "This product includes software developed by ## Ralf S. Engelschall <rse@engelschall.com> for use in the -## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." +## mod_ssl project (http://www.modssl.org/)." ## ## 4. The names "mod_ssl" must not be used to endorse or promote ## products derived from this software without prior written @@ -43,7 +43,7 @@ ## acknowledgment: ## "This product includes software developed by ## Ralf S. Engelschall <rse@engelschall.com> for use in the -## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." +## mod_ssl project (http://www.modssl.org/)." ## ## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY ## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -62,8 +62,8 @@ # the following variables are automatically # adjusted by the configure.bat script. -SSLEAY_INC = p:\ssl\work\win32\ssleay\include -SSLEAY_LIB = p:\ssl\work\win32\ssleay\lib +SSL_INC = p:\ssl\work\win32\openssl\include +SSL_LIB = p:\ssl\work\win32\openssl\lib MOD_SSL_VERS_NUM = 000000 MOD_SSL_VERS_STR = 0.0.0 @@ -71,7 +71,7 @@ MOD_SSL_VERS_STR = 0.0.0 CC = cl.exe CFLAGS = /nologo /c /O2 /MD /W3 /GX /DNDEBUG /DWIN32 /D_WINDOWS /DSHARED_MODULE /DEAPI CFLAGS = $(CFLAGS) /DMOD_SSL=$(MOD_SSL_VERS_NUM) /DMOD_SSL_VERSION=\"$(MOD_SSL_VERS_STR)\" -CFLAGS = $(CFLAGS) /I..\..\include /I$(SSLEAY_INC) +CFLAGS = $(CFLAGS) /I..\..\include /I$(SSL_INC) LD = link.exe LDFLAGS = /nologo RM = del @@ -87,6 +87,7 @@ OBJS=\ ssl_engine_config.obj\ ssl_engine_compat.obj\ ssl_engine_ds.obj\ + ssl_engine_dh.obj\ ssl_engine_init.obj\ ssl_engine_kernel.obj\ ssl_engine_rand.obj\ @@ -103,7 +104,8 @@ OBJS=\ ssl_expr_eval.obj\ ssl_util.obj\ ssl_util_ssl.obj\ - ssl_util_sdbm.obj + ssl_util_sdbm.obj\ + ssl_util_table.obj .c.obj: $(CC) $(CFLAGS) $< @@ -118,8 +120,8 @@ $(LIBNAME).dll: $(OBJS) $(LD) $(LDFLAGS) /dll /out:$@ \ $(OBJS) \ ..\..\CoreR\ApacheCore.lib \ - $(SSLEAY_LIB)\ssleay32.lib \ - $(SSLEAY_LIB)\libeay32.lib \ + $(SSL_LIB)\ssleay32.lib \ + $(SSL_LIB)\libeay32.lib \ wsock32.lib clean: diff --git a/usr.sbin/httpd/src/modules/ssl/README b/usr.sbin/httpd/src/modules/ssl/README index fc5269acd39..e363b8a3554 100644 --- a/usr.sbin/httpd/src/modules/ssl/README +++ b/usr.sbin/httpd/src/modules/ssl/README @@ -2,19 +2,24 @@ _ __ ___ ___ __| | ___ ___| | | '_ ` _ \ / _ \ / _` | / __/ __| | | | | | | | (_) | (_| | \__ \__ \ | ``mod_ssl combines the flexibility of - |_| |_| |_|\___/ \__,_|___|___/___/_| Apache with the security of SSLeay.'' + |_| |_| |_|\___/ \__,_|___|___/___/_| Apache with the security of OpenSSL.'' |_____| - ``Ralf Engelschall has released an - mod_ssl - Apache Interface to SSLeay excellent module that integrates - http://www.engelschall.com/sw/mod_ssl/ Apache and SSLeay.'' - Version 2.1.0-1.3.3 Tim J. Hudson, SSLeay co-author + mod_ssl ``Ralf Engelschall has released an + Apache Interface to OpenSSL excellent module that integrates + http://www.modssl.org/ Apache and SSLeay.'' + Version 2.3 -- Tim J. Hudson + SYNOPSIS + This Apache module provides strong cryptography for the Apache 1.3 webserver via the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS - v1) protocols by the help of the SSL/TLS implementation library SSLeay from - Eric A. Young and Tim J. Hudson. The mod_ssl package was created in April - 1998 by Ralf S. Engelschall and was originally derived from software - developed by Ben Laurie for use in the Apache-SSL HTTP server project. + v1) protocols by the help of the SSL/TLS implementation library OpenSSL which + is based on SSLeay from Eric A. Young and Tim J. Hudson. The mod_ssl package + was created in April 1998 by Ralf S. Engelschall and was originally derived + from software developed by Ben Laurie for use in the Apache-SSL HTTP server + project. + + SOURCES Here is a short overview of the source files: @@ -53,18 +58,22 @@ -Wmissing-declarations -Wnested-externs -Winline'' compiler test without any complains. When you make changes or additions make sure the source still passes this compiler test. + + FUNCTIONS Inside the source code you will be confronted with the following types of functions which can be identified by their prefixes: ap_xxxx() ............... Apache API function ssl_xxxx() .............. mod_ssl function - SSL_xxxx() .............. SSLeay function (SSL library) - SSLeay_xxxx() ........... SSLeay function (SSL library) - X509_xxxx() ............. SSLeay function (Crypto library) - PEM_xxxx() .............. SSLeay function (Crypto library) - EVP_xxxx() .............. SSLeay function (Crypto library) - RSA_xxxx() .............. SSLeay function (Crypto library) + SSL_xxxx() .............. OpenSSL function (SSL library) + OpenSSL_xxxx() .......... OpenSSL function (SSL library) + X509_xxxx() ............. OpenSSL function (Crypto library) + PEM_xxxx() .............. OpenSSL function (Crypto library) + EVP_xxxx() .............. OpenSSL function (Crypto library) + RSA_xxxx() .............. OpenSSL function (Crypto library) + + DATA STRUCTURES Inside the source code you will be confronted with the following data structures: @@ -77,12 +86,12 @@ SSLModConfig ............ mod_ssl (Global) Module Configuration SSLSrvConfig ............ mod_ssl (Virtual) Server Configuration SSLDirConfig ............ mod_ssl Directory Configuration - SSL_CTX ................. SSLeay Context - SSL_METHOD .............. SSLeay Protocol Method - SSL_CIPHER .............. SSLeay Cipher - SSL_SESSION ............. SSLeay Session - SSL ..................... SSLeay Connection - BIO ..................... SSLeay Connection Buffer + SSL_CTX ................. OpenSSL Context + SSL_METHOD .............. OpenSSL Protocol Method + SSL_CIPHER .............. OpenSSL Cipher + SSL_SESSION ............. OpenSSL Session + SSL ..................... OpenSSL Connection + BIO ..................... OpenSSL Connection Buffer For an overview how these are related and chained together have a look at the page in README.dsov.{fig,ps}. It contains overview diagrams for those data @@ -90,3 +99,38 @@ a smaller version inside XFig by specifing a magnification on the Export panel. + EXPERIMENTAL CODE + + Experimental code is always encapsulated as + + | #ifdef SSL_EXPERIMENTAL + | ... + | #endif + + blocks and only compiled in when this define is enabled with the APACI + --enable-rule=SSL_EXPERIMENTAL option. Currently the following features are + experimental: + + o The ability to use SSLCACertificateFile and SSLCACertificatePath + in a per-directory context (.htaccess). This is provided by some nasty + reconfiguration hacks until OpenSSL has better support for this. It + should work on non-multithreaded platforms (all but Win32). + + VENDOR EXTENSIONS + + Inside the mod_ssl sources you can enable various EAPI vendor hooks + (`ap::mod_ssl::vendor::xxxx') by using the APACI --enable-rule=SSL_VENDOR + option. These hooks can be used to change or extend mod_ssl by a vendor + without patching the source code. Grep for `ap::mod_ssl::vendor::'. + Additionally vendors can add their own source code to files named + ssl_vendor.c, ssl_vendor_XXX.c, etc. The libssl.module script automatically + picks these up under configuration time and mod_ssl under run-time calls the + functions `void ssl_vendor_register(void)' and `void + ssl_vendor_unregister(void)' inside these objects to bootstrap them. + + An ssl_vendor.c should at least contain the following contents: + + | #include "mod_ssl.h" + | void ssl_vendor_register(void) { return; } + | void ssl_vendor_unregister(void) { return; } + diff --git a/usr.sbin/httpd/src/modules/ssl/README.dsov.fig b/usr.sbin/httpd/src/modules/ssl/README.dsov.fig index 9a76380718c..d8d03db247c 100644 --- a/usr.sbin/httpd/src/modules/ssl/README.dsov.fig +++ b/usr.sbin/httpd/src/modules/ssl/README.dsov.fig @@ -14,14 +14,14 @@ Single 0 36 #ffffff 6 6345 2835 7155 3150 6 6345 2970 7110 3150 -4 0 0 200 0 20 8 0.0000 4 120 750 6345 3105 "ssl_module")\001 +4 0 0 200 0 20 8 0.0000 4 120 585 6345 3105 "ssl_module")\001 -6 -4 0 0 200 0 20 8 0.0000 4 135 810 6345 2970 ap_ctx_get(...,\001 +4 0 0 200 0 20 8 0.0000 4 120 660 6345 2970 ap_ctx_get(...,\001 -6 6 10800 2610 12240 3060 -4 0 0 200 0 20 8 0.0000 4 120 1425 10800 2745 ap_get_module_config(...\001 -4 0 0 200 0 20 8 0.0000 4 135 1035 10800 2880 ->per_dir_config,\001 -4 0 0 200 0 20 8 0.0000 4 120 750 10800 3015 &ssl_module)\001 +4 0 0 200 0 20 8 0.0000 4 120 1170 10800 2745 ap_get_module_config(...\001 +4 0 0 200 0 20 8 0.0000 4 120 795 10800 2880 ->per_dir_config,\001 +4 0 0 200 0 20 8 0.0000 4 120 585 10800 3015 &ssl_module)\001 -6 6 7920 4770 9135 4995 2 4 0 1 35 35 200 0 20 0.000 0 0 4 0 0 5 @@ -280,16 +280,16 @@ Single 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000 4 0 0 100 0 0 12 0.0000 4 180 1440 10575 675 Ralf S. Engelschall\001 -4 0 0 100 0 18 20 0.0000 4 270 3600 4275 675 Apache+mod_ssl+SSLeay\001 +4 0 0 100 0 18 20 0.0000 4 270 3840 4275 675 Apache+mod_ssl+OpenSSL\001 4 0 0 100 0 0 10 0.0000 4 135 1320 10575 855 rse@engelschall.com\001 4 0 0 100 0 0 10 0.0000 4 135 1410 10575 1035 www.engelschall.com\001 4 0 0 100 0 0 12 0.0000 4 135 870 900 675 Version 1.3\001 -4 0 0 100 0 0 12 0.0000 4 135 1005 900 855 27-Jan-1998\001 -4 0 0 200 0 20 8 0.0000 4 75 510 6210 4680 ->server\001 -4 0 0 200 0 20 8 0.0000 4 135 1095 8280 6120 ap_ctx_get(...,"ssl")\001 -4 0 0 200 0 20 8 0.0000 4 120 1425 7740 2700 ap_get_module_config(...\001 -4 0 0 200 0 20 8 0.0000 4 135 1020 7740 2835 ->module_config,\001 -4 0 0 200 0 20 8 0.0000 4 120 750 7740 2970 &ssl_module)\001 +4 0 0 100 0 0 12 0.0000 4 180 1035 900 855 12-Apr-1999\001 +4 0 0 200 0 20 8 0.0000 4 60 390 6210 4680 ->server\001 +4 0 0 200 0 20 8 0.0000 4 120 855 8280 6120 ap_ctx_get(...,"ssl")\001 +4 0 0 200 0 20 8 0.0000 4 120 1170 7740 2700 ap_get_module_config(...\001 +4 0 0 200 0 20 8 0.0000 4 120 810 7740 2835 ->module_config,\001 +4 0 0 200 0 20 8 0.0000 4 120 585 7740 2970 &ssl_module)\001 4 0 0 100 0 18 20 0.0000 4 270 1200 9000 8100 Chaining\001 4 0 0 100 0 18 20 0.0000 4 210 1095 2745 8100 Lifetime\001 4 0 0 100 0 18 12 0.0000 4 180 1215 810 6255 ap_global_ctx\001 @@ -308,7 +308,7 @@ Single 4 0 0 200 0 0 8 0.0000 4 90 1050 2025 7110 Connection Duration\001 4 0 0 200 0 0 8 0.0000 4 120 885 2835 6885 Request Duration\001 4 0 0 200 0 18 20 0.0000 4 195 90 6345 6795 t\001 -4 0 0 200 0 20 8 0.0000 4 105 465 7110 5985 ->client\001 +4 0 0 200 0 20 8 0.0000 4 90 345 7110 5985 ->client\001 4 0 0 100 0 18 12 0.0000 4 180 1305 6795 2430 SSLModConfig\001 4 0 0 100 0 18 12 0.0000 4 180 1260 8865 2430 SSLSrvConfig\001 4 0 0 100 0 18 12 0.0000 4 180 1215 6345 3555 ap_global_ctx\001 @@ -320,27 +320,27 @@ Single 4 0 0 100 0 18 12 0.0000 4 180 1305 11025 5355 SSL_METHOD\001 4 0 0 100 0 18 12 0.0000 4 180 840 11475 4455 SSL_CTX\001 4 0 0 100 0 18 24 0.0000 4 285 4365 3915 1080 Data Structure Overview\001 -4 0 0 200 0 20 8 0.0000 4 105 795 7065 5085 ->connection\001 -4 0 0 200 0 20 8 0.0000 4 75 510 7065 4770 ->server\001 -4 0 0 200 0 20 8 0.0000 4 120 1200 8010 5445 SSL_get_app_data()\001 -4 0 0 200 0 20 8 0.0000 4 120 705 10530 4050 ->pSSLCtx\001 -4 0 0 200 0 20 8 0.0000 4 120 1515 7875 4275 SSL_CTX_get_app_data()\001 -4 0 0 200 0 20 8 0.0000 4 120 1485 10305 5535 SSL_get_current_cipher()\001 +4 0 0 200 0 20 8 0.0000 4 90 615 7065 5085 ->connection\001 +4 0 0 200 0 20 8 0.0000 4 60 390 7065 4770 ->server\001 +4 0 0 200 0 20 8 0.0000 4 120 960 8010 5445 SSL_get_app_data()\001 +4 0 0 200 0 20 8 0.0000 4 120 510 10530 4050 ->pSSLCtx\001 +4 0 0 200 0 20 8 0.0000 4 120 1215 7875 4275 SSL_CTX_get_app_data()\001 +4 0 0 200 0 20 8 0.0000 4 120 1155 10305 5535 SSL_get_current_cipher()\001 4 0 0 100 0 18 12 0.0000 4 180 1170 11025 5760 SSL_CIPHER\001 4 0 0 100 0 18 12 0.0000 4 180 1350 10980 6165 SSL_SESSION\001 -4 0 0 200 0 20 8 0.0000 4 120 1095 10440 5940 SSL_get_session()\001 +4 0 0 200 0 20 8 0.0000 4 120 840 10440 5940 SSL_get_session()\001 4 0 0 100 0 18 12 0.0000 4 180 1665 10575 7110 X509_STORE_CTX\001 4 0 0 100 0 18 12 0.0000 4 135 345 9720 7110 BIO\001 -4 0 0 200 0 20 8 0.0000 4 135 1080 9540 7335 SSL_get_{r,w}bio()\001 -4 0 0 100 0 18 12 0.0000 4 180 720 10935 7785 [Crypto]\001 -4 0 0 100 0 18 20 0.0000 4 270 1050 10935 7605 SSLeay\001 -4 0 0 100 0 18 20 0.0000 4 270 1050 11115 3645 SSLeay\001 -4 0 0 100 0 18 12 0.0000 4 180 495 11115 3825 [SSL]\001 +4 0 0 200 0 20 8 0.0000 4 120 840 9540 7335 SSL_get_{r,w}bio()\001 4 0 0 100 0 18 20 0.0000 4 270 1170 8730 3465 mod_ssl\001 4 0 0 100 0 18 20 0.0000 4 270 1050 8145 6750 Apache\001 -4 0 0 200 0 20 8 0.0000 4 120 1245 10125 4680 SSL_get_SSL_CTX()\001 -4 0 0 200 0 20 8 0.0000 4 120 1530 10350 5175 SSL_get_SSL_METHOD()\001 -4 0 0 200 0 20 8 0.0000 4 105 585 11745 4770 ->method\001 -4 0 0 200 0 20 8 0.0000 4 120 2070 9945 6480 X509_STORE_CTX_get_app_data()\001 -4 0 0 200 0 20 8 0.0000 4 120 1560 10980 6705 SSL_CTX_get_cert_store()\001 -4 0 0 200 0 20 8 0.0000 4 120 1275 8280 5130 SSL_get_app_data2()\001 +4 0 0 200 0 20 8 0.0000 4 120 945 10125 4680 SSL_get_SSL_CTX()\001 +4 0 0 200 0 20 8 0.0000 4 120 1170 10350 5175 SSL_get_SSL_METHOD()\001 +4 0 0 200 0 20 8 0.0000 4 90 465 11745 4770 ->method\001 +4 0 0 200 0 20 8 0.0000 4 120 1665 9945 6480 X509_STORE_CTX_get_app_data()\001 +4 0 0 200 0 20 8 0.0000 4 120 1215 10980 6705 SSL_CTX_get_cert_store()\001 +4 0 0 200 0 20 8 0.0000 4 120 1020 8280 5130 SSL_get_app_data2()\001 +4 0 0 100 0 18 20 0.0000 4 270 1290 10710 7605 OpenSSL\001 +4 0 0 100 0 18 12 0.0000 4 180 720 10710 7785 [Crypto]\001 +4 0 0 100 0 18 20 0.0000 4 270 1290 10935 3645 OpenSSL\001 +4 0 0 100 0 18 12 0.0000 4 180 495 10935 3825 [SSL]\001 diff --git a/usr.sbin/httpd/src/modules/ssl/README.dsov.ps b/usr.sbin/httpd/src/modules/ssl/README.dsov.ps index 73ddf39aa2d..def19dbecfa 100644 --- a/usr.sbin/httpd/src/modules/ssl/README.dsov.ps +++ b/usr.sbin/httpd/src/modules/ssl/README.dsov.ps @@ -1,15 +1,15 @@ %!PS-Adobe-2.0 %%Title: README.dsov.ps %%Creator: fig2dev Version 3.2 Patchlevel 1 -%%CreationDate: Thu Jan 28 11:08:27 1999 +%%CreationDate: Mon Apr 12 17:09:11 1999 %%For: rse@en1.engelschall.com (Ralf S. Engelschall) %%Orientation: Landscape -%%BoundingBox: 42 11 570 781 +%%BoundingBox: 59 37 553 755 %%Pages: 1 %%BeginSetup %%IncludeFeature: *PageSize Letter %%EndSetup -%%Magnification: 1.0000 +%%Magnification: 0.9340 %%EndComments /$F2psDict 200 dict def $F2psDict begin @@ -55,7 +55,7 @@ $F2psDict /mtrx matrix put end save -30.0 -15.0 translate +48.0 12.0 translate 90 rotate 1 -1 scale @@ -137,7 +137,7 @@ newfontname newfont definefont pop end } def $F2psBegin 10 setmiterlimit n -1000 9572 m -1000 -1000 l 13622 -1000 l 13622 9572 l cp clip - 0.06299 0.06299 sc + 0.05883 0.05883 sc %%Page: 1 1 % Polyline 7.500 slw @@ -866,9 +866,9 @@ n 9690 6930 m 9630 6930 9630 7095 60 arcto 4 {pop} repeat 10170 7155 10170 6990 60 arcto 4 {pop} repeat 10170 6930 9690 6930 60 arcto 4 {pop} repeat cp gs col35 1.00 shd ef gr gs col35 s gr -/Helvetica-Narrow-iso ff 120.00 scf sf -8280 5130 m -gs 1 -1 sc (SSL_get_app_data2\(\)) col0 sh gr +/Times-Roman-iso ff 120.00 scf sf +900 7560 m +gs 1 -1 sc (Startup, Runtime, Shutdown) col0 sh gr /Helvetica-Narrow-iso ff 120.00 scf sf 6345 2970 m gs 1 -1 sc (ap_ctx_get\(...,) col0 sh gr @@ -943,9 +943,9 @@ gs 1 -1 sc (->module_config,) col0 sh gr /Helvetica-Narrow-iso ff 120.00 scf sf 7740 2970 m gs 1 -1 sc (&ssl_module\)) col0 sh gr -/Times-Roman-iso ff 120.00 scf sf -900 7560 m -gs 1 -1 sc (Startup, Runtime, Shutdown) col0 sh gr +/Helvetica-Narrow-iso ff 120.00 scf sf +6345 3105 m +gs 1 -1 sc ("ssl_module"\)) col0 sh gr /Times-Roman-iso ff 120.00 scf sf 1350 7335 m gs 1 -1 sc (Configuration Time) col0 sh gr @@ -1001,16 +1001,16 @@ gs 1 -1 sc (X509_STORE_CTX_get_app_data\(\)) col0 sh gr 10980 6705 m gs 1 -1 sc (SSL_CTX_get_cert_store\(\)) col0 sh gr /Helvetica-Narrow-iso ff 120.00 scf sf -6345 3105 m -gs 1 -1 sc ("ssl_module"\)) col0 sh gr +8280 5130 m +gs 1 -1 sc (SSL_get_app_data2\(\)) col0 sh gr /Helvetica-Bold-iso ff 180.00 scf sf 3645 1620 m gs 1 -1 sc (SSLDirConfig) col0 sh gr /Helvetica-Bold-iso ff 300.00 scf sf -11115 3645 m -gs 1 -1 sc (SSLeay) col0 sh gr +10935 3645 m +gs 1 -1 sc (OpenSSL) col0 sh gr /Helvetica-Bold-iso ff 180.00 scf sf -11115 3825 m +10935 3825 m gs 1 -1 sc ([SSL]) col0 sh gr /Helvetica-Bold-iso ff 180.00 scf sf 11025 5760 m @@ -1019,8 +1019,8 @@ gs 1 -1 sc (SSL_CIPHER) col0 sh gr 10980 6165 m gs 1 -1 sc (SSL_SESSION) col0 sh gr /Helvetica-Bold-iso ff 300.00 scf sf -8730 3465 m -gs 1 -1 sc (mod_ssl) col0 sh gr +10710 7605 m +gs 1 -1 sc (OpenSSL) col0 sh gr /Helvetica-Bold-iso ff 180.00 scf sf 10575 7110 m gs 1 -1 sc (X509_STORE_CTX) col0 sh gr @@ -1069,7 +1069,7 @@ gs 1 -1 sc (request_rec) col0 sh gr gs 1 -1 sc (Ralf S. Engelschall) col0 sh gr /Helvetica-Bold-iso ff 300.00 scf sf 4275 675 m -gs 1 -1 sc (Apache+mod_ssl+SSLeay) col0 sh gr +gs 1 -1 sc (Apache+mod_ssl+OpenSSL) col0 sh gr /Times-Roman-iso ff 150.00 scf sf 10575 855 m gs 1 -1 sc (rse@engelschall.com) col0 sh gr @@ -1081,22 +1081,22 @@ gs 1 -1 sc (www.engelschall.com) col0 sh gr gs 1 -1 sc (Version 1.3) col0 sh gr /Times-Roman-iso ff 180.00 scf sf 900 855 m -gs 1 -1 sc (27-Jan-1998) col0 sh gr +gs 1 -1 sc (12-Apr-1999) col0 sh gr /Helvetica-Bold-iso ff 360.00 scf sf 3915 1080 m gs 1 -1 sc (Data Structure Overview) col0 sh gr /Helvetica-Bold-iso ff 180.00 scf sf 9720 7110 m gs 1 -1 sc (BIO) col0 sh gr -/Helvetica-Bold-iso ff 300.00 scf sf -8145 6750 m -gs 1 -1 sc (Apache) col0 sh gr /Helvetica-Bold-iso ff 180.00 scf sf -10935 7785 m +10710 7785 m gs 1 -1 sc ([Crypto]) col0 sh gr /Helvetica-Bold-iso ff 300.00 scf sf -10935 7605 m -gs 1 -1 sc (SSLeay) col0 sh gr +8730 3465 m +gs 1 -1 sc (mod_ssl) col0 sh gr +/Helvetica-Bold-iso ff 300.00 scf sf +8145 6750 m +gs 1 -1 sc (Apache) col0 sh gr /Helvetica-Bold-iso ff 300.00 scf sf 9000 8100 m gs 1 -1 sc (Chaining) col0 sh gr diff --git a/usr.sbin/httpd/src/modules/ssl/libssl.module b/usr.sbin/httpd/src/modules/ssl/libssl.module index a9bb26c49a8..444a3818c5b 100644 --- a/usr.sbin/httpd/src/modules/ssl/libssl.module +++ b/usr.sbin/httpd/src/modules/ssl/libssl.module @@ -1,8 +1,8 @@ ## _ _ -## _ __ ___ ___ __| | ___ ___| | -## | '_ ` _ \ / _ \ / _` | / __/ __| | -## | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -## |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +## _ __ ___ ___ __| | ___ ___| | mod_ssl +## | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +## | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +## |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ## |_____| ## libssl.module ## Apache 1.3 Configuration mechanism module stub @@ -28,7 +28,7 @@ ## software must display the following acknowledgment: ## "This product includes software developed by ## Ralf S. Engelschall <rse@engelschall.com> for use in the -## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." +## mod_ssl project (http://www.modssl.org/)." ## ## 4. The names "mod_ssl" must not be used to endorse or promote ## products derived from this software without prior written @@ -43,7 +43,7 @@ ## acknowledgment: ## "This product includes software developed by ## Ralf S. Engelschall <rse@engelschall.com> for use in the -## mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." +## mod_ssl project (http://www.modssl.org/)." ## ## THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY ## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -139,10 +139,12 @@ ConfigStart my_rule_SSL_COMPAT=$SSL_COMPAT my_rule_SSL_SDBM=$SSL_SDBM my_rule_SSL_EXPERIMENTAL=$SSL_EXPERIMENTAL + my_rule_SSL_VENDOR=$SSL_VENDOR else my_rule_SSL_COMPAT=`./helpers/CutRule SSL_COMPAT $file` my_rule_SSL_SDBM=`./helpers/CutRule SSL_SDBM $file` my_rule_SSL_EXPERIMENTAL=`./helpers/CutRule SSL_EXPERIMENTAL $file` + my_rule_SSL_VENDOR=`./helpers/CutRule SSL_VENDOR $file` fi # @@ -165,6 +167,25 @@ ConfigStart echo "$my_prefix SSL interface experimental code: disabled" fi + # + # determine vendor mode + # + SSL_VENDOR_OBJS='' + SSL_VENDOR_OBJS_PIC='' + if [ ".$my_rule_SSL_VENDOR" = .yes ]; then + echo "$my_prefix SSL interface vendor extensions: enabled" + SSL_CFLAGS="$SSL_CFLAGS -DSSL_VENDOR" + my_src="`cd $my_dir && echo ssl_vendor*.c`" + if [ ".$my_src" != . -a ".$my_src" != ".ssl_vendor*.c" ]; then + SSL_CFLAGS="$SSL_CFLAGS -DSSL_VENDOR_OBJS" + SSL_VENDOR_OBJS="`echo $my_src | sed -e 's;\.c;.o;g'`" + SSL_VENDOR_OBJS_PIC="`echo $my_src | sed -e 's;\.c;.lo;g'`" + echo "$my_prefix SSL interface vendor objects: $SSL_VENDOR_OBJS" + fi + else + echo "$my_prefix SSL interface vendor extensions: disabled" + fi + # # determine DBM support library # (src/Configure has DBM_LIB predefined for some platforms) @@ -242,7 +263,7 @@ ConfigStart else if [ ! -d "$SSL_BASE" ]; then echo "Error: Cannot find SSL installation in $SSL_BASE" 1>&2 - echo "Hint: Please provide us with the location of SSLeay" 1>&2 + echo "Hint: Please provide us with the location of OpenSSL" 1>&2 echo " via the environment variable SSL_BASE." 1>&2 exit 1 fi @@ -250,7 +271,9 @@ ConfigStart fi # - # determine location of SSLeay binaries + # determine location of OpenSSL binaries + # (we still search also for `ssleay' to allow us to + # better complain about the actually installed version) # SSL_BINDIR="" if [ ".$SSL_BASE" = .SYSTEM ]; then @@ -267,8 +290,12 @@ ConfigStart fi done if [ ".$SSL_BINDIR" = . ]; then - echo "Error: Cannot find SSL binaries in $PATH" 1>&2 - exit 1 +# echo "Error: Cannot find SSL binaries in $PATH" 1>&2 +# exit 1 +# Kludge for OpenBSD - Make sure we work even if the stuff +# isn't there yet. + SSL_BINDIR="/usr/sbin" + SSL_PROGRAM="/usr/sbin/openssl" fi else for name in openssl ssleay; do @@ -290,12 +317,28 @@ ConfigStart fi # - # determine location of SSLeay headers + # SSL version + # +# kludged for OpenBSD - Don't want this retarded shit breaking make build +# when openssl isn't there yet. +# SSL_VERSION_ID="`$SSL_PROGRAM version`" +# echo "$my_prefix SSL library version: $SSL_VERSION_ID" +# case $SSL_VERSION_ID in +# *0.[5678].*|*0.9.[012]* ) +# echo "Error: OpenSSL VERSIONS BELOW 0.9.3 ARE NO LONGER SUPPORTED." +# echo "Hint: Use OpenSSL version 0.9.3 or higher!" +# exit 1 +# ;; +# esac + SSL_VERSION_ID=0.9.4 + + # + # determine location of OpenSSL headers # if [ ".$SSL_BASE" = .SYSTEM ]; then SSL_INCDIR="" for p in . /usr/include /usr/include/ssl/ /usr/local/include /usr/local/include/ssl; do - if [ -f "$p/ssl.h" ]; then + if [ -f "$p/openssl/ssl.h" ]; then SSL_INCDIR="$p" break fi @@ -306,21 +349,17 @@ ConfigStart exit 1 fi else - if [ -f "$SSL_BASE/include/ssl.h" ]; then + if [ -f "$SSL_BASE/include/openssl/ssl.h" ]; then SSL_INCDIR='$(SSL_BASE)/include' else - if [ -f "$SSL_BASE/ssl.h" ]; then - SSL_INCDIR='$(SSL_BASE)' - else - echo "Error: Cannot find SSL header files under $SSL_BASE" 1>&2 - exit 1 - fi + echo "Error: Cannot find SSL header files under $SSL_BASE" 1>&2 + exit 1 fi fi SSL_CFLAGS="$SSL_CFLAGS -I\$(SSL_INCDIR)" # - # determine location of SSLeay libraries + # determine location of OpenSSL libraries # if [ ".$SSL_BASE" = .SYSTEM ]; then SSL_LIBDIR="" @@ -337,17 +376,15 @@ ConfigStart exit 1 fi else - if [ -f "$SSL_BASE/lib/libssl.a" ]; then + if [ -f "$SSL_BASE/libssl.a" ]; then + SSL_LIBDIR='$(SSL_BASE)' + my_real_ssl_libdir="$SSL_BASE" + elif [ -f "$SSL_BASE/lib/libssl.a" ]; then SSL_LIBDIR='$(SSL_BASE)/lib' my_real_ssl_libdir="$SSL_BASE/lib" else - if [ -f "$SSL_BASE/libssl.a" ]; then - SSL_LIBDIR='$(SSL_BASE)' - my_real_ssl_libdir="$SSL_BASE" - else - echo "Error: Cannot find SSL library files under $SSL_BASE" 1>&2 - exit 1 - fi + echo "Error: Cannot find SSL library files under $SSL_BASE" 1>&2 + exit 1 fi fi SSL_LDFLAGS="$SSL_LDFLAGS -L\$(SSL_LIBDIR)" @@ -367,19 +404,6 @@ ConfigStart echo "$my_prefix SSL library type: $my_type $my_note" # - # SSL version - # - SSLEAY_VERSION="`$SSL_PROGRAM version`" - echo "$my_prefix SSL library version: $SSLEAY_VERSION" - case $SSLEAY_VERSION in - *0.[5678].* ) - echo "$my_prefixe WARNING: THE SSLeay VERSIONS BELOW 0.9.0 ARE NO LONGER SUPPORTED." - echo "$my_prefixe Hint: Use SSLeay version 0.9.0b or any OpenSSL version." - exit 1 - ;; - esac - - # # support for RSAref library # if [ ".$RSA_BASE" = . ]; then @@ -387,7 +411,7 @@ ConfigStart fi if [ ".$RSA_BASE" != . ]; then if [ ! -f "$my_real_ssl_libdir/libRSAglue.a" ]; then - echo "Error: Cannot find SSLeay's RSAglue library under $my_real_ssl_libdir" 1>&2 + echo "Error: Cannot find OpenSSL's RSAglue library under $my_real_ssl_libdir" 1>&2 exit 1 else SSL_LIBS="$SSL_LIBS -lRSAglue" @@ -443,18 +467,16 @@ ConfigStart SSL_LIBS="$SSL_LIBS -lrsaref" echo "$my_prefix SSL library plugin path: $RSA_BASE/librsaref.a" my_found=yes + elif [ -f "$RSA_BASE/rsaref.a" ]; then + SSL_LIBS="$SSL_LIBS $RSA_BASE/rsaref.a" + echo "$my_prefix SSL library plugin path: $RSA_BASE/rsaref.a" + my_found=yes else - if [ -f "$RSA_BASE/rsaref.a" ]; then - SSL_LIBS="$SSL_LIBS $RSA_BASE/rsaref.a" - echo "$my_prefix SSL library plugin path: $RSA_BASE/rsaref.a" + wild="`echo $RSA_BASE/*/rsaref.a`" + if [ -f "$wild" ]; then + SSL_LIBS="$SSL_LIBS $wild" + echo "$my_prefix SSL library plugin path: $wild" my_found=yes - else - wild="`echo $RSA_BASE/*/rsaref.a`" - if [ -f "$wild" ]; then - SSL_LIBS="$SSL_LIBS $wild" - echo "$my_prefix SSL library plugin path: $wild" - my_found=yes - fi fi fi if [ .$my_found = .no ]; then @@ -494,6 +516,8 @@ ConfigStart echo "SSL_PROGRAM=$SSL_PROGRAM" >>$my_outfile echo "SSL_VERSION=$SSL_VERSION" >>$my_outfile echo "SSL_CFLAGS=$SSL_CFLAGS" >>$my_outfile + echo "SSL_VENDOR_OBJS=$SSL_VENDOR_OBJS" >>$my_outfile + echo "SSL_VENDOR_OBJS_PIC=$SSL_VENDOR_OBJS_PIC" >>$my_outfile if [ ".$my_buildtype" = .DSO ]; then # under DSO we link ourself echo "SSL_LIBS=$SSL_LIBS" >>$my_outfile diff --git a/usr.sbin/httpd/src/modules/ssl/libssl.version b/usr.sbin/httpd/src/modules/ssl/libssl.version index 851544d6678..d6396570caf 100644 --- a/usr.sbin/httpd/src/modules/ssl/libssl.version +++ b/usr.sbin/httpd/src/modules/ssl/libssl.version @@ -1 +1 @@ -mod_ssl/2.2.3-1.3.4 +mod_ssl/2.4.2-1.3.9 diff --git a/usr.sbin/httpd/src/modules/ssl/mod_ssl.c b/usr.sbin/httpd/src/modules/ssl/mod_ssl.c index d0c0ae10d3b..d473c1237bd 100644 --- a/usr.sbin/httpd/src/modules/ssl/mod_ssl.c +++ b/usr.sbin/httpd/src/modules/ssl/mod_ssl.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** mod_ssl.c ** Apache API interface structures @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -74,7 +74,7 @@ * identify the module to SCCS `what' and RCS `ident' commands */ static char const sccsid[] = "@(#) mod_ssl/" MOD_SSL_VERSION " >"; -static char const rcsid[] = "$Id: mod_ssl.c,v 1.1 1999/03/01 04:28:50 beck Exp $"; +static char const rcsid[] = "$Id: mod_ssl.c,v 1.2 1999/09/29 06:29:45 beck Exp $"; /* * the table of configuration directives we provide @@ -107,9 +107,12 @@ static command_rec ssl_config_cmds[] = { "(`XXX:...:XXX' - see manual)") AP_SRV_CMD(CertificateFile, TAKE1, "SSL Server Certificate file " - "(`/path/to/file' - PEM encoded)") + "(`/path/to/file' - PEM or DER encoded)") AP_SRV_CMD(CertificateKeyFile, TAKE1, "SSL Server Private Key file " + "(`/path/to/file' - PEM or DER encoded)") + AP_SRV_CMD(CertificateChainFile, TAKE1, + "SSL Server CA Certificate Chain file " "(`/path/to/file' - PEM encoded)") #ifdef SSL_EXPERIMENTAL AP_ALL_CMD(CACertificatePath, TAKE1, @@ -126,12 +129,18 @@ static command_rec ssl_config_cmds[] = { "SSL CA Certificate file " "(`/path/to/file' - PEM encoded)") #endif + AP_SRV_CMD(CARevocationPath, TAKE1, + "SSL CA Certificate Revocation List (CRL) path " + "(`/path/to/dir' - contains PEM encoded files)") + AP_SRV_CMD(CARevocationFile, TAKE1, + "SSL CA Certificate Revocation List (CRL) file " + "(`/path/to/file' - PEM encoded)") AP_ALL_CMD(VerifyClient, TAKE1, "SSL Client verify type " "(`none', `optional', `require', `optional_no_ca')") AP_ALL_CMD(VerifyDepth, TAKE1, "SSL Client verify depth " - "(`N' - number of intermediate certifcates)") + "(`N' - number of intermediate certificates)") AP_SRV_CMD(SessionCacheTimeout, TAKE1, "SSL Session Cache object lifetime " "(`N' - number of seconds)") @@ -181,9 +190,9 @@ module MODULE_VAR_EXPORT ssl_module = { ssl_config_server_merge, /* merge per-server config structures */ ssl_config_cmds, /* table of config file commands */ ssl_config_handler, /* [#8] MIME-typed-dispatched handlers */ - NULL, /* [#1] URI to filename translation */ + ssl_hook_Translate, /* [#1] URI to filename translation */ ssl_hook_Auth, /* [#4] validate user id from request */ - NULL, /* [#5] check if the user is ok _here_ */ + ssl_hook_UserCheck, /* [#5] check if the user is ok _here_ */ ssl_hook_Access, /* [#3] check access by host address */ NULL, /* [#6] determine MIME type */ ssl_hook_Fixup, /* [#7] pre-run fixups */ @@ -198,7 +207,7 @@ module MODULE_VAR_EXPORT ssl_module = { ssl_hook_AddModule, /* after modules was added to core */ ssl_hook_RemoveModule, /* before module is removed from core */ ssl_hook_RewriteCommand, /* configuration command rewriting */ - ssl_hook_NewConnection /* configuration command rewriting */ + ssl_hook_NewConnection, /* socket connection open */ + ssl_hook_CloseConnection /* socket connection close */ }; - diff --git a/usr.sbin/httpd/src/modules/ssl/mod_ssl.h b/usr.sbin/httpd/src/modules/ssl/mod_ssl.h index d1481b83de1..812bf6f3c46 100644 --- a/usr.sbin/httpd/src/modules/ssl/mod_ssl.h +++ b/usr.sbin/httpd/src/modules/ssl/mod_ssl.h @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** mod_ssl.h ** Global header @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -75,16 +75,21 @@ #include <stdlib.h> #include <stdarg.h> #include <errno.h> +#include <time.h> +#ifndef WIN32 +#include <sys/time.h> +#endif #include <sys/stat.h> -/* SSLeay headers */ -#include <ssl.h> -#include <err.h> -#include <x509.h> -#include <pem.h> -#include <crypto.h> -#include <evp.h> -#include <rand.h> +/* OpenSSL headers */ +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/x509.h> +#include <openssl/x509v3.h> +#include <openssl/pem.h> +#include <openssl/crypto.h> +#include <openssl/evp.h> +#include <openssl/rand.h> /* Apache headers */ #define CORE_PRIVATE @@ -93,6 +98,7 @@ #include "http_config.h" #include "http_conf_globals.h" #include "http_protocol.h" +#include "http_request.h" #include "http_main.h" #include "http_core.h" #include "http_log.h" @@ -103,21 +109,32 @@ /* mod_ssl headers */ #include "ssl_expr.h" #include "ssl_util_ssl.h" +#include "ssl_util_table.h" /* * Provide reasonable default for some defines */ #ifndef FALSE -#define FALSE 0 +#define FALSE (0) #endif #ifndef TRUE -#define TRUE !FALSE +#define TRUE (!FALSE) +#endif +#ifndef PFALSE +#define PFALSE ((void *)FALSE) +#endif +#ifndef PTRUE +#define PTRUE ((void *)TRUE) #endif #ifndef UNSET -#define UNSET -1 +#define UNSET (-1) #endif #ifndef NUL -#define NUL '\0' +#define NUL '\0' +#endif +#ifndef RAND_MAX +#include <limits.h> +#define RAND_MAX INT_MAX #endif /* @@ -148,6 +165,7 @@ #define cfgMerge(el,unset) new->el = add->el == unset ? base->el : add->el #define cfgMergeArray(el) new->el = ap_append_arrays(p, add->el, base->el) #define cfgMergeTable(el) new->el = ap_overlay_tables(p, add->el, base->el) +#define cfgMergeCtx(el) new->el = ap_ctx_overlay(p, add->el, base->el) #define cfgMergeString(el) cfgMerge(el, NULL) #define cfgMergeBool(el) cfgMerge(el, UNSET) #define cfgMergeInt(el) cfgMerge(el, UNSET) @@ -189,7 +207,6 @@ /* * Defaults for the configuration */ - #ifndef SSL_SESSION_CACHE_TIMEOUT #define SSL_SESSION_CACHE_TIMEOUT 300 #endif @@ -246,6 +263,15 @@ #endif /* + * Support for MM library + */ +#ifndef WIN32 +#define SSL_MM_FILE_MODE ( S_IRUSR|S_IWUSR ) +#else +#define SSL_MM_FILE_MODE ( _S_IREAD|_S_IWRITE ) +#endif + +/* * Support for DBM library */ #ifndef WIN32 @@ -266,8 +292,13 @@ #define ssl_dbm_nextkey sdbm_nextkey #define SSL_DBM_FILE_SUFFIX_DIR ".dir" #define SSL_DBM_FILE_SUFFIX_PAG ".pag" +#else /* !SSL_USE_SDBM */ +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) \ + && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 +#include <db1/ndbm.h> #else #include <ndbm.h> +#endif #define ssl_dbm_open dbm_open #define ssl_dbm_close dbm_close #define ssl_dbm_store dbm_store @@ -275,7 +306,11 @@ #define ssl_dbm_delete dbm_delete #define ssl_dbm_firstkey dbm_firstkey #define ssl_dbm_nextkey dbm_nextkey -#if defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM)) +#if !defined(SSL_DBM_FILE_SUFFIX_DIR) && !defined(SSL_DBM_FILE_SUFFIX_PAG) +#if defined(DBM_SUFFIX) +#define SSL_DBM_FILE_SUFFIX_DIR DBM_SUFFIX +#define SSL_DBM_FILE_SUFFIX_PAG DBM_SUFFIX +#elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM)) #define SSL_DBM_FILE_SUFFIX_DIR ".db" #define SSL_DBM_FILE_SUFFIX_PAG ".db" #else @@ -283,13 +318,14 @@ #define SSL_DBM_FILE_SUFFIX_PAG ".pag" #endif #endif +#endif /* !SSL_USE_SDBM */ /* - * Check for SSLeay 0.9.0 and below - * and enabled Extended API (EAPI) + * Check for OpenSSL version and whether + * Extended API (EAPI) is enabled */ -#if SSL_LIBRARY_VERSION < 0x0900 -#error "SSLeay versions below 0.9.0 are no longer supported" +#if SSL_LIBRARY_VERSION < 0x00903100 +#error "mod_ssl requires OpenSSL 0.9.3 or higher" #endif #ifndef EAPI #error "mod_ssl requires Extended API (EAPI)" @@ -312,6 +348,21 @@ typedef struct { } ssl_ds_table; /* + * Define the certificate algorithm types + */ + +typedef int ssl_algo_t; + +#define SSL_ALGO_UNKNOWN (0) +#define SSL_ALGO_RSA (1<<0) +#define SSL_ALGO_DSA (1<<1) +#define SSL_ALGO_ALL (SSL_ALGO_RSA|SSL_ALGO_DSA) + +#define SSL_AIDX_RSA (0) +#define SSL_AIDX_DSA (1) +#define SSL_AIDX_MAX (2) + +/* * Define the SSL options */ #define SSL_OPT_NONE (0) @@ -319,13 +370,14 @@ typedef struct { #define SSL_OPT_COMPATENVVARS (1<<1) #define SSL_OPT_EXPORTCERTDATA (1<<2) #define SSL_OPT_FAKEBASICAUTH (1<<3) -#define SSL_OPT_ALL (SSL_OPT_COMPATENVVAR|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH) +#define SSL_OPT_STRICTREQUIRE (1<<4) +#define SSL_OPT_OPTRENEGOTIATE (1<<5) +#define SSL_OPT_ALL (SSL_OPT_COMPATENVVAR|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE) typedef int ssl_opt_t; /* * Define the SSL Protocol options */ - #define SSL_PROTOCOL_NONE (0) #define SSL_PROTOCOL_SSLV2 (1<<0) #define SSL_PROTOCOL_SSLV3 (1<<1) @@ -433,30 +485,29 @@ typedef struct { typedef struct { pool *pPool; BOOL bFixed; - - /* - * global config data - */ int nInitCount; - - RSA *pRSATmpKey; + RSA *pRSATmpKey512; + RSA *pRSATmpKey1024; + DH *pDHTmpParam512; + DH *pDHTmpParam1024; int nSessionCacheMode; char *szSessionCacheDataFile; + int nSessionCacheDataSize; + AP_MM *pSessionCacheDataMM; + table_t *tSessionCacheDataTable; ssl_mutexmode_t nMutexMode; char *szMutexFile; int nMutexFD; int nMutexSEMID; array_header *aRandSeed; - ssl_ds_table *tPublicCert; ssl_ds_table *tPrivateKey; - - /* - * arbitrary global context data - */ struct { void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9; } rCtx; +#ifdef SSL_VENDOR + ap_ctx *ctx; +#endif } SSLModConfigRec; /* @@ -466,8 +517,9 @@ typedef struct { */ typedef struct { BOOL bEnabled; - char *szCertificateFile; - char *szKeyFile; + char *szPublicCertFile[SSL_AIDX_MAX]; + char *szPrivateKeyFile[SSL_AIDX_MAX]; + char *szCertificateChain; char *szCACertificatePath; char *szCACertificateFile; char *szLogFile; @@ -476,13 +528,19 @@ typedef struct { int nLogLevel; int nVerifyDepth; ssl_verify_t nVerifyClient; - X509 *px509Certificate; - RSA *prsaKey; + X509 *pPublicCert[SSL_AIDX_MAX]; + EVP_PKEY *pPrivateKey[SSL_AIDX_MAX]; SSL_CTX *pSSLCtx; int nSessionCacheTimeout; int nPassPhraseDialogType; char *szPassPhraseDialogPath; ssl_proto_t nProtocol; + char *szCARevocationPath; + char *szCARevocationFile; + X509_STORE *pRevocationStore; +#ifdef SSL_VENDOR + ap_ctx *ctx; +#endif } SSLSrvConfigRec; /* @@ -503,6 +561,9 @@ typedef struct { char *szCACertificatePath; char *szCACertificateFile; #endif +#ifdef SSL_VENDOR + ap_ctx *ctx; +#endif } SSLDirConfigRec; /* @@ -523,13 +584,16 @@ void *ssl_config_perdir_merge(pool *, void *, void *); const char *ssl_cmd_SSLMutex(cmd_parms *, char *, char *); const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, char *, char *); const char *ssl_cmd_SSLRandomSeed(cmd_parms *, char *, char *, char *, char *); -const char *ssl_cmd_SSLEngine(cmd_parms *, char *, int flag); +const char *ssl_cmd_SSLEngine(cmd_parms *, char *, int); const char *ssl_cmd_SSLCipherSuite(cmd_parms *, SSLDirConfigRec *, char *); const char *ssl_cmd_SSLCertificateFile(cmd_parms *, char *, char *); const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, char *, char *); +const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, char *, char *); const char *ssl_cmd_SSLCACertificatePath(cmd_parms *, SSLDirConfigRec *, char *); const char *ssl_cmd_SSLCACertificateFile(cmd_parms *, SSLDirConfigRec *, char *); -const char *ssl_cmd_SSLVerifyClient(cmd_parms *, SSLDirConfigRec *, char *level); +const char *ssl_cmd_SSLCARevocationPath(cmd_parms *, SSLDirConfigRec *, char *); +const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, SSLDirConfigRec *, char *); +const char *ssl_cmd_SSLVerifyClient(cmd_parms *, SSLDirConfigRec *, char *); const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, SSLDirConfigRec *, char *); const char *ssl_cmd_SSLSessionCache(cmd_parms *, char *, char *); const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *, char *, char *); @@ -542,27 +606,35 @@ const char *ssl_cmd_SSLRequire(cmd_parms *, SSLDirConfigRec *, char *); /* module initialization */ void ssl_init_Module(server_rec *, pool *); -void ssl_init_SSLLibrary(server_rec *); -void ssl_init_GetCertAndKey(server_rec *, pool *, SSLSrvConfigRec *); -STACK *ssl_init_FindCAList(server_rec *, pool *, char *, char *); +void ssl_init_SSLLibrary(void); +void ssl_init_ConfigureServer(server_rec *, pool *, SSLSrvConfigRec *); +void ssl_init_CheckServers(server_rec *, pool *); +STACK_OF(X509_NAME) + *ssl_init_FindCAList(server_rec *, pool *, char *, char *); void ssl_init_Child(server_rec *, pool *); +void ssl_init_ChildKill(void *); +void ssl_init_ModuleKill(void *); /* Apache API hooks */ void ssl_hook_AddModule(module *); void ssl_hook_RemoveModule(module *); -char *ssl_hook_RewriteCommand(cmd_parms *, void *config, const char *); +char *ssl_hook_RewriteCommand(cmd_parms *, void *, const char *); void ssl_hook_NewConnection(conn_rec *); void ssl_hook_TimeoutConnection(int); -void ssl_hook_CloseConnection(void *); +void ssl_hook_CloseConnection(conn_rec *); +int ssl_hook_Translate(request_rec *); int ssl_hook_Auth(request_rec *); +int ssl_hook_UserCheck(request_rec *); int ssl_hook_Access(request_rec *); int ssl_hook_Fixup(request_rec *); int ssl_hook_ReadReq(request_rec *); int ssl_hook_Handler(request_rec *); -/* SSLeay callbacks */ -RSA *ssl_callback_TmpRSA(SSL *, int); +/* OpenSSL callbacks */ +RSA *ssl_callback_TmpRSA(SSL *, int, int); +DH *ssl_callback_TmpDH(SSL *, int, int); int ssl_callback_SSLVerify(int, X509_STORE_CTX *); +int ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, server_rec *); int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *); SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *); void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *); @@ -570,21 +642,36 @@ void ssl_callback_LogTracingState(SSL *, int, int); /* Session Cache Support */ void ssl_scache_init(server_rec *, pool *); -void ssl_scache_store(server_rec *, SSL_SESSION *, int); +void ssl_scache_kill(server_rec *); +BOOL ssl_scache_store(server_rec *, SSL_SESSION *, int); SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int); void ssl_scache_remove(server_rec *, SSL_SESSION *); -void ssl_scache_expire(server_rec *); +void ssl_scache_expire(server_rec *, time_t); +void ssl_scache_status(server_rec *, pool *, void (*)(char *, void *), void *); char *ssl_scache_id2sz(UCHAR *, int); void ssl_scache_dbm_init(server_rec *, pool *); -void ssl_scache_dbm_store(server_rec *, ssl_scinfo_t *); +void ssl_scache_dbm_kill(server_rec *); +BOOL ssl_scache_dbm_store(server_rec *, ssl_scinfo_t *); void ssl_scache_dbm_retrieve(server_rec *, ssl_scinfo_t *); void ssl_scache_dbm_remove(server_rec *, ssl_scinfo_t *); -void ssl_scache_dbm_expire(server_rec *); +void ssl_scache_dbm_expire(server_rec *, time_t); +void ssl_scache_dbm_status(server_rec *, pool *, void (*)(char *, void *), void *); +void ssl_scache_shm_init(server_rec *, pool *); +void ssl_scache_shm_kill(server_rec *); +BOOL ssl_scache_shm_store(server_rec *, ssl_scinfo_t *); +void ssl_scache_shm_retrieve(server_rec *, ssl_scinfo_t *); +void ssl_scache_shm_remove(server_rec *, ssl_scinfo_t *); +void ssl_scache_shm_expire(server_rec *, time_t); +void ssl_scache_shm_status(server_rec *, pool *, void (*)(char *, void *), void *); /* Pass Phrase Support */ void ssl_pphrase_Handle(server_rec *, pool *); int ssl_pphrase_Handle_CB(char *, int, int); +/* Diffie-Hellman Parameter Support */ +DH *ssl_dh_GetTmpParam(int); +DH *ssl_dh_GetParamFromFile(char *); + /* Data Structures */ ssl_ds_array *ssl_ds_array_make(pool *, int); BOOL ssl_ds_array_isempty(ssl_ds_array *); @@ -601,9 +688,10 @@ void ssl_ds_table_kill(ssl_ds_table *); /* Mutex Support */ void ssl_mutex_init(server_rec *, pool *); -void ssl_mutex_open(server_rec *, pool *); -void ssl_mutex_on(void); -void ssl_mutex_off(void); +void ssl_mutex_reinit(server_rec *, pool *); +void ssl_mutex_on(server_rec *); +void ssl_mutex_off(server_rec *); +void ssl_mutex_kill(server_rec *s); void ssl_mutex_file_create(server_rec *, pool *); void ssl_mutex_file_open(server_rec *, pool *); void ssl_mutex_file_remove(void *); @@ -616,7 +704,8 @@ BOOL ssl_mutex_sem_acquire(void); BOOL ssl_mutex_sem_release(void); /* Logfile Support */ -void ssl_log_open(server_rec *, pool *); +void ssl_log_open(server_rec *, server_rec *, pool *); +BOOL ssl_log_applies(server_rec *, int); void ssl_log(server_rec *, int, const char *, ...); void ssl_die(void); @@ -628,7 +717,10 @@ char *ssl_var_lookup(pool *, server_rec *, conn_rec *, request_rec *, cha /* I/O */ void ssl_io_register(void); void ssl_io_unregister(void); -long ssl_io_data_cb(BIO *, int, char *, int, long, long); +long ssl_io_data_cb(BIO *, int, const char *, int, long, long); +#ifdef SSL_EXPERIMENTAL +void ssl_io_suck(request_rec *, SSL *); +#endif /* PRNG */ int ssl_rand_seed(server_rec *, pool *, ssl_rsctx_t); @@ -653,7 +745,15 @@ int ssl_util_ppopen_child(void *, child_info *); void ssl_util_ppclose(server_rec *, pool *, FILE *); char *ssl_util_readfilter(server_rec *, pool *, char *); BOOL ssl_util_path_check(ssl_pathcheck_t, char *); +ssl_algo_t ssl_util_algotypeof(X509 *, EVP_PKEY *); +char *ssl_util_algotypestr(ssl_algo_t); char *ssl_util_ptxtsub(pool *, const char *, const char *, char *); void ssl_util_thread_setup(void); +/* Vendor extension support */ +#if defined(SSL_VENDOR) && defined(SSL_VENDOR_OBJS) +void ssl_vendor_register(void); +void ssl_vendor_unregister(void); +#endif + #endif /* MOD_SSL_H */ diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c index 967fb206bad..2690de05af2 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_compat.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_compat.c ** Backward Compatibility @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -78,9 +78,11 @@ * The mapping of obsolete directives to official ones... */ -static char *ssl_compat_SSLRequireCipher(pool *p, const char *, const char *, const char *); -static char *ssl_compat_SSLBanCipher(pool *p, const char *, const char *, const char *); -static char *ssl_compat_words2list(pool *p, const char *); +static char *ssl_compat_SSLSessionLockFile(pool *, const char *, const char *, const char *); +static char *ssl_compat_SSLCacheDisable(pool *, const char *, const char *, const char *); +static char *ssl_compat_SSLRequireCipher(pool *, const char *, const char *, const char *); +static char *ssl_compat_SSLBanCipher(pool *, const char *, const char *, const char *); +static char *ssl_compat_words2list(pool *, const char *); #define CRM_BEGIN /* nop */ #define CRM_ENTRY(what,action) { what, action }, @@ -143,8 +145,13 @@ static struct { /* * Stronghold 2.x backward compatibility */ + CRM_ENTRY( CRM_CMD("StrongholdAccelerator"), CRM_LOG("Not supported by mod_ssl") ) + CRM_ENTRY( CRM_CMD("StrongholdKey"), CRM_LOG("Not supported by mod_ssl") ) + CRM_ENTRY( CRM_CMD("StrongholdLicenseFile"), CRM_LOG("Not supported by mod_ssl") ) CRM_ENTRY( CRM_CMD("SSLFlag"), CRM_SUB("SSLEngine") ) - CRM_ENTRY( CRM_CMD("SSLSessionLockFile"), CRM_SUB("SSLMutex") ) + CRM_ENTRY( CRM_CMD("SSLClientCAfile"), CRM_SUB("SSLCACertificateFile") ) + CRM_ENTRY( CRM_CMD("SSLSessionLockFile"), CRM_CAL(ssl_compat_SSLSessionLockFile) ) + CRM_ENTRY( CRM_CMD("SSLCacheDisable"), CRM_CAL(ssl_compat_SSLCacheDisable) ) CRM_ENTRY( CRM_CMD("RequireSSL"), CRM_SUB("SSLRequireSSL") ) CRM_ENTRY( CRM_CMD("SSLCipherList"), CRM_SUB("SSLCipherSuite") ) CRM_ENTRY( CRM_CMD("SSLErrorFile"), CRM_LOG("Not needed for mod_ssl") ) @@ -162,6 +169,28 @@ static struct { CRM_END }; +static char *ssl_compat_SSLSessionLockFile( + pool *p, const char *oline, const char *cmd, const char *args) +{ + char *cp; + + for (cp = (char *)args; ap_isspace(*cp); cp++) + ; + return ap_pstrcat(p, "SSLMutex file:", cp, NULL); +} + +static char *ssl_compat_SSLCacheDisable( + pool *p, const char *oline, const char *cmd, const char *args) +{ + char *cp; + + for (cp = (char *)args; ap_isspace(*cp); cp++) + ; + if (strcEQ(cp, "on")) + return "SSLSessionCache none"; + return ""; +} + static char *ssl_compat_SSLRequireCipher(pool *p, const char *oline, const char *cmd, const char *args) { return ap_pstrcat(p, "SSLRequire %{SSL_CIPHER} in {", @@ -347,6 +376,8 @@ static struct { VRM_ENTRY( VRM_VAR("SSL_SERVER_CERTIFICATE"), VRM_SUB("SSL_SERVER_CERT") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_CERT_START"), VRM_SUB("SSL_SERVER_V_START") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_CERT_END"), VRM_SUB("SSL_SERVER_V_END") ) + VRM_ENTRY( VRM_VAR("SSL_SERVER_CERT_SERIAL"), VRM_SUB("SSL_SERVER_M_SERIAL") ) + VRM_ENTRY( VRM_VAR("SSL_SERVER_SIGNATURE_ALGORITHM"),VRM_SUB("SSL_SERVER_A_SIG") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_DN"), VRM_SUB("SSL_SERVER_S_DN") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_CN"), VRM_SUB("SSL_SERVER_S_DN_CN") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_EMAIL"), VRM_SUB("SSL_SERVER_S_DN_Email") ) @@ -366,6 +397,8 @@ static struct { VRM_ENTRY( VRM_VAR("SSL_CLIENT_CERTIFICATE"), VRM_SUB("SSL_CLIENT_CERT") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_CERT_START"), VRM_SUB("SSL_CLIENT_V_START") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_CERT_END"), VRM_SUB("SSL_CLIENT_V_END") ) + VRM_ENTRY( VRM_VAR("SSL_CLIENT_CERT_SERIAL"), VRM_SUB("SSL_CLIENT_M_SERIAL") ) + VRM_ENTRY( VRM_VAR("SSL_CLIENT_SIGNATURE_ALGORITHM"),VRM_SUB("SSL_CLIENT_A_SIG") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_DN"), VRM_SUB("SSL_CLIENT_S_DN") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_CN"), VRM_SUB("SSL_CLIENT_S_DN_CN") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_EMAIL"), VRM_SUB("SSL_CLIENT_S_DN_Email") ) @@ -382,10 +415,15 @@ static struct { VRM_ENTRY( VRM_VAR("SSL_CLIENT_IC"), VRM_SUB("SSL_CLIENT_I_DN_C") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_ISP"), VRM_SUB("SSL_CLIENT_I_DN_SP") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_IL"), VRM_SUB("SSL_CLIENT_I_DN_L") ) + VRM_ENTRY( VRM_VAR("SSL_EXPORT"), VRM_SUB("SSL_CIPHER_EXPORT") ) + VRM_ENTRY( VRM_VAR("SSL_KEYSIZE"), VRM_SUB("SSL_CIPHER_ALGKEYSIZE") ) + VRM_ENTRY( VRM_VAR("SSL_SECRETKEYSIZE"), VRM_SUB("SSL_CIPHER_USEKEYSIZE") ) + VRM_ENTRY( VRM_VAR("SSL_SSLEAY_VERSION"), VRM_SUB("SSL_VERSION_LIBRARY") ) + VRM_ENTRY( VRM_VAR("SSL_STRONG_CRYPTO"), VRM_LOG("Not supported by mod_ssl") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_KEY_EXP"), VRM_LOG("Not supported by mod_ssl") ) + VRM_ENTRY( VRM_VAR("SSL_SERVER_KEY_SIZE"), VRM_LOG("Not supported by mod_ssl") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_KEY_ALGORITHM"), VRM_LOG("Not supported by mod_ssl") ) - VRM_ENTRY( VRM_VAR("SSL_SERVER_SIGNATURE_ALGORITHM"),VRM_LOG("Not supported by mod_ssl") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_SESSIONDIR"), VRM_LOG("Not supported by mod_ssl") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_CERTIFICATELOGDIR"), VRM_LOG("Not supported by mod_ssl") ) VRM_ENTRY( VRM_VAR("SSL_SERVER_CERTFILE"), VRM_LOG("Not supported by mod_ssl") ) @@ -394,7 +432,6 @@ static struct { VRM_ENTRY( VRM_VAR("SSL_CLIENT_KEY_EXP"), VRM_LOG("Not supported by mod_ssl") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_KEY_ALGORITHM"), VRM_LOG("Not supported by mod_ssl") ) VRM_ENTRY( VRM_VAR("SSL_CLIENT_KEY_SIZE"), VRM_LOG("Not supported by mod_ssl") ) - VRM_ENTRY( VRM_VAR("SSL_CLIENT_SIGNATURE_ALGORITHM"),VRM_LOG("Not supported by mod_ssl") ) VRM_END }; @@ -417,9 +454,25 @@ void ssl_compat_variables(request_rec *r) ap_table_set(r->subprocess_env, cpOld, cpVal); } else if (cpMsg != NULL) { +#ifdef SSL_VENDOR + /* + * something that isn't provided by mod_ssl, so at least + * let vendor extensions provide a reasonable value first. + */ + cpVal = NULL; + ap_hook_use("ap::mod_ssl::vendor::compat_variables_lookup", + AP_HOOK_SIG3(ptr,ptr,ptr), + AP_HOOK_DECLINE(NULL), + &cpVal, r, cpOld); + if (cpVal != NULL) { + ap_table_set(r->subprocess_env, cpOld, cpVal); + continue; + } +#endif + /* - * we cannot print a message, so we at least the - * variables contents to the message + * we cannot print a message, so we set at least + * the variables content to the compat message */ ap_table_set(r->subprocess_env, cpOld, cpMsg); } diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c index 3adf553c20d..68b9c313fc5 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_config.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_config.c ** Apache Configuration Directives @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -85,6 +85,9 @@ void ssl_hook_AddModule(module *m) ssl_var_register(); ssl_ext_register(); ssl_io_register(); +#if defined(SSL_VENDOR) && defined(SSL_VENDOR_OBJS) + ssl_vendor_register(); +#endif } return; } @@ -98,6 +101,9 @@ void ssl_hook_RemoveModule(module *m) ssl_var_unregister(); ssl_ext_unregister(); ssl_io_unregister(); +#if defined(SSL_VENDOR) && defined(SSL_VENDOR_OBJS) + ssl_vendor_unregister(); +#endif } return; } @@ -121,18 +127,29 @@ void ssl_config_global_create(void) * initialize per-module configuration */ mc->nInitCount = 0; - mc->pRSATmpKey = NULL; + mc->pRSATmpKey512 = NULL; + mc->pRSATmpKey1024 = NULL; + mc->pDHTmpParam512 = NULL; + mc->pDHTmpParam1024 = NULL; mc->nSessionCacheMode = SSL_SCMODE_UNSET; mc->szSessionCacheDataFile = NULL; + mc->nSessionCacheDataSize = 0; + mc->pSessionCacheDataMM = NULL; + mc->tSessionCacheDataTable = NULL; mc->nMutexMode = SSL_MUTEXMODE_UNSET; mc->szMutexFile = NULL; mc->nMutexFD = -1; mc->nMutexSEMID = -1; mc->aRandSeed = ap_make_array(pPool, 4, sizeof(ssl_randseed_t)); - mc->tPrivateKey = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t)); mc->tPublicCert = ssl_ds_table_make(pPool, sizeof(ssl_asn1_t)); +#ifdef SSL_VENDOR + mc->ctx = ap_ctx_new(pPool); + ap_hook_use("ap::mod_ssl::vendor::config_global_create", + AP_HOOK_SIG2(void,ptr), AP_HOOK_MODE_ALL, mc); +#endif + /* * And push it into Apache's global context */ @@ -172,10 +189,9 @@ void *ssl_config_server_create(pool *p, server_rec *s) sc = ap_palloc(p, sizeof(SSLSrvConfigRec)); sc->bEnabled = UNSET; - sc->szCertificateFile = NULL; - sc->szKeyFile = NULL; sc->szCACertificatePath = NULL; sc->szCACertificateFile = NULL; + sc->szCertificateChain = NULL; sc->szLogFile = NULL; sc->szCipherSuite = NULL; sc->nLogLevel = SSL_LOG_NONE; @@ -186,9 +202,22 @@ void *ssl_config_server_create(pool *p, server_rec *s) sc->szPassPhraseDialogPath = NULL; sc->nProtocol = SSL_PROTOCOL_ALL; sc->fileLogFile = NULL; - sc->px509Certificate = NULL; - sc->prsaKey = NULL; sc->pSSLCtx = NULL; + sc->szCARevocationPath = NULL; + sc->szCARevocationFile = NULL; + sc->pRevocationStore = NULL; + + (void)memset(sc->szPublicCertFile, 0, SSL_AIDX_MAX*sizeof(char *)); + (void)memset(sc->szPrivateKeyFile, 0, SSL_AIDX_MAX*sizeof(char *)); + (void)memset(sc->pPublicCert, 0, SSL_AIDX_MAX*sizeof(X509 *)); + (void)memset(sc->pPrivateKey, 0, SSL_AIDX_MAX*sizeof(EVP_PKEY *)); + +#ifdef SSL_VENDOR + sc->ctx = ap_ctx_new(p); + ap_hook_use("ap::mod_ssl::vendor::config_server_create", + AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL, + p, s, sc); +#endif return sc; } @@ -201,12 +230,12 @@ void *ssl_config_server_merge(pool *p, void *basev, void *addv) SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev; SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv; SSLSrvConfigRec *new = (SSLSrvConfigRec *)ap_palloc(p, sizeof(SSLSrvConfigRec)); + int i; cfgMergeBool(bEnabled); - cfgMergeString(szCertificateFile); - cfgMergeString(szKeyFile); cfgMergeString(szCACertificatePath); cfgMergeString(szCACertificateFile); + cfgMergeString(szCertificateChain); cfgMergeString(szLogFile); cfgMergeString(szCipherSuite); cfgMerge(nLogLevel, SSL_LOG_NONE); @@ -217,9 +246,24 @@ void *ssl_config_server_merge(pool *p, void *basev, void *addv) cfgMergeString(szPassPhraseDialogPath); cfgMerge(nProtocol, SSL_PROTOCOL_ALL); cfgMerge(fileLogFile, NULL); - cfgMerge(px509Certificate, NULL); - cfgMerge(prsaKey, NULL); cfgMerge(pSSLCtx, NULL); + cfgMerge(szCARevocationPath, NULL); + cfgMerge(szCARevocationFile, NULL); + cfgMerge(pRevocationStore, NULL); + + for (i = 0; i < SSL_AIDX_MAX; i++) { + cfgMergeString(szPublicCertFile[i]); + cfgMergeString(szPrivateKeyFile[i]); + cfgMerge(pPublicCert[i], NULL); + cfgMerge(pPrivateKey[i], NULL); + } + +#ifdef SSL_VENDOR + cfgMergeCtx(ctx); + ap_hook_use("ap::mod_ssl::vendor::config_server_merge", + AP_HOOK_SIG5(void,ptr,ptr,ptr,ptr), AP_HOOK_MODE_ALL, + p, base, add, new); +#endif return new; } @@ -245,6 +289,13 @@ void *ssl_config_perdir_create(pool *p, char *dir) dc->szCACertificateFile = NULL; #endif +#ifdef SSL_VENDOR + dc->ctx = ap_ctx_new(p); + ap_hook_use("ap::mod_ssl::vendor::config_perdir_create", + AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL, + p, dir, dc); +#endif + return dc; } @@ -280,6 +331,13 @@ void *ssl_config_perdir_merge(pool *p, void *basev, void *addv) cfgMergeString(szCACertificateFile); #endif +#ifdef SSL_VENDOR + cfgMergeCtx(ctx); + ap_hook_use("ap::mod_ssl::vendor::config_perdir_merge", + AP_HOOK_SIG5(void,ptr,ptr,ptr,ptr), AP_HOOK_MODE_ALL, + p, base, add, new); +#endif + return new; } @@ -314,10 +372,14 @@ const char *ssl_cmd_SSLMutex( mc->nMutexMode = SSL_MUTEXMODE_NONE; } else if (strlen(arg) > 5 && strcEQn(arg, "file:", 5)) { +#ifndef WIN32 mc->nMutexMode = SSL_MUTEXMODE_FILE; mc->szMutexFile = ap_psprintf(mc->pPool, "%s.%lu", - ap_server_root_relative(cmd->pool, arg+5), + ap_server_root_relative(cmd->pool, arg+5), (unsigned long)getpid()); +#else + return "SSLMutex: Lockfiles not available on this platform"; +#endif } else if (strcEQ(arg, "sem")) { #ifdef SSL_CAN_USE_SEM @@ -394,12 +456,12 @@ const char *ssl_cmd_SSLRandomSeed( if (!ssl_util_path_check(SSL_PCM_EXISTS, pRS->cpPath)) return ap_pstrcat(cmd->pool, "SSLRandomSeed: source path '", pRS->cpPath, "' not exists", NULL); - if (arg3 == NULL) + if (arg3 == NULL) pRS->nBytes = 0; /* read whole file */ else { if (pRS->nSrc == SSL_RSSRC_BUILTIN) return "SSLRandomSeed: byte specification not " - "allowd for builtin seed source"; + "allowed for builtin seed source"; pRS->nBytes = atoi(arg3); if (pRS->nBytes < 0) return "SSLRandomSeed: invalid number of bytes specified"; @@ -433,12 +495,19 @@ const char *ssl_cmd_SSLCertificateFile( { SSLSrvConfigRec *sc = mySrvConfig(cmd->server); char *cpPath; + int i; cpPath = ap_server_root_relative(cmd->pool, arg); if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath)) return ap_pstrcat(cmd->pool, "SSLCertificateFile: file '", cpPath, "' not exists or empty", NULL); - sc->szCertificateFile = cpPath; + for (i = 0; i < SSL_AIDX_MAX && sc->szPublicCertFile[i] != NULL; i++) + ; + if (i == SSL_AIDX_MAX) + return ap_psprintf(cmd->pool, "SSLCertificateFile: only up to %d " + "different certificates per virtual host allowed", + SSL_AIDX_MAX); + sc->szPublicCertFile[i] = cpPath; return NULL; } @@ -447,12 +516,33 @@ const char *ssl_cmd_SSLCertificateKeyFile( { SSLSrvConfigRec *sc = mySrvConfig(cmd->server); char *cpPath; + int i; cpPath = ap_server_root_relative(cmd->pool, arg); if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath)) return ap_pstrcat(cmd->pool, "SSLCertificateKeyFile: file '", cpPath, "' not exists or empty", NULL); - sc->szKeyFile = cpPath; + for (i = 0; i < SSL_AIDX_MAX && sc->szPrivateKeyFile[i] != NULL; i++) + ; + if (i == SSL_AIDX_MAX) + return ap_psprintf(cmd->pool, "SSLCertificateKeyFile: only up to %d " + "different private keys per virtual host allowed", + SSL_AIDX_MAX); + sc->szPrivateKeyFile[i] = cpPath; + return NULL; +} + +const char *ssl_cmd_SSLCertificateChainFile( + cmd_parms *cmd, char *struct_ptr, char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + char *cpPath; + + cpPath = ap_server_root_relative(cmd->pool, arg); + if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath)) + return ap_pstrcat(cmd->pool, "SSLCertificateChainFile: file '", + cpPath, "' not exists or empty", NULL); + sc->szCertificateChain = cpPath; return NULL; } @@ -485,7 +575,7 @@ const char *ssl_cmd_SSLCACertificateFile( cpPath = ap_server_root_relative(cmd->pool, arg); if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath)) - return ap_pstrcat(cmd->pool, "SSLCACertificateKeyFile: file '", + return ap_pstrcat(cmd->pool, "SSLCACertificateFile: file '", cpPath, "' not exists or empty", NULL); #ifdef SSL_EXPERIMENTAL if (cmd->path == NULL || dc == NULL) @@ -498,6 +588,34 @@ const char *ssl_cmd_SSLCACertificateFile( return NULL; } +const char *ssl_cmd_SSLCARevocationPath( + cmd_parms *cmd, SSLDirConfigRec *dc, char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + char *cpPath; + + cpPath = ap_server_root_relative(cmd->pool, arg); + if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISDIR, cpPath)) + return ap_pstrcat(cmd->pool, "SSLCARecocationPath: directory '", + cpPath, "' not exists", NULL); + sc->szCARevocationPath = cpPath; + return NULL; +} + +const char *ssl_cmd_SSLCARevocationFile( + cmd_parms *cmd, SSLDirConfigRec *dc, char *arg) +{ + SSLSrvConfigRec *sc = mySrvConfig(cmd->server); + char *cpPath; + + cpPath = ap_server_root_relative(cmd->pool, arg); + if (!ssl_util_path_check(SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO, cpPath)) + return ap_pstrcat(cmd->pool, "SSLCARevocationFile: file '", + cpPath, "' not exists or empty", NULL); + sc->szCARevocationFile = cpPath; + return NULL; +} + const char *ssl_cmd_SSLVerifyClient( cmd_parms *cmd, SSLDirConfigRec *dc, char *level) { @@ -542,6 +660,8 @@ const char *ssl_cmd_SSLSessionCache( { const char *err; SSLModConfigRec *mc = myModConfig(); + char *cp, *cp2; + int maxsize; if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL) return err; @@ -556,7 +676,34 @@ const char *ssl_cmd_SSLSessionCache( mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool, ap_server_root_relative(cmd->pool, arg+4)); } - else + else if (strlen(arg) > 4 && strcEQn(arg, "shm:", 4)) { + if (!ap_mm_useable()) + return "SSLSessionCache: shared memory cache not useable on this platform"; + mc->nSessionCacheMode = SSL_SCMODE_SHM; + mc->szSessionCacheDataFile = ap_pstrdup(mc->pPool, + ap_server_root_relative(cmd->pool, arg+4)); + mc->tSessionCacheDataTable = NULL; + mc->nSessionCacheDataSize = 1024*512; /* 512KB */ + if ((cp = strchr(mc->szSessionCacheDataFile, '(')) != NULL) { + *cp++ = NUL; + if ((cp2 = strchr(cp, ')')) == NULL) + return "SSLSessionCache: Invalid argument: no closing parenthesis"; + *cp2 = NUL; + mc->nSessionCacheDataSize = atoi(cp); + if (mc->nSessionCacheDataSize <= 8192) + return "SSLSessionCache: Invalid argument: size has to be >= 8192 bytes"; + maxsize = ap_mm_core_maxsegsize(); + if (mc->nSessionCacheDataSize >= maxsize) + return ap_psprintf(cmd->pool, "SSLSessionCache: Invalid argument: " + "size has to be < %d bytes on this platform", maxsize); + } + } + else +#ifdef SSL_VENDOR + if (!ap_hook_use("ap::mod_ssl::vendor::cmd_sslsessioncache", + AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_MODE_ALL, + cmd, arg, mc)) +#endif return "SSLSessionCache: Invalid argument"; return NULL; } @@ -638,6 +785,10 @@ const char *ssl_cmd_SSLOptions( opt = SSL_OPT_EXPORTCERTDATA; else if (strcEQ(w, "FakeBasicAuth")) opt = SSL_OPT_FAKEBASICAUTH; + else if (strcEQ(w, "StrictRequire")) + opt = SSL_OPT_STRICTREQUIRE; + else if (strcEQ(w, "OptRenegotiate")) + opt = SSL_OPT_OPTRENEGOTIATE; else return ap_pstrcat(cmd->pool, "SSLOptions: Illegal option '", w, "'", NULL); diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c index 04d8c0bd38c..b83b5b93052 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ds.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_ds.c ** Additional Data Structures @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c index dab6fd269f6..14e1efd9089 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_ext.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_ext.c ** Extensions to other Apache parts @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -76,12 +76,15 @@ static void ssl_ext_mr_register(void); static void ssl_ext_mr_unregister(void); static void ssl_ext_mp_register(void); static void ssl_ext_mp_unregister(void); +static void ssl_ext_ms_register(void); +static void ssl_ext_ms_unregister(void); void ssl_ext_register(void) { ssl_ext_mlc_register(); ssl_ext_mr_register(); ssl_ext_mp_register(); + ssl_ext_ms_register(); return; } @@ -90,6 +93,7 @@ void ssl_ext_unregister(void) ssl_ext_mlc_unregister(); ssl_ext_mr_unregister(); ssl_ext_mp_unregister(); + ssl_ext_ms_unregister(); return; } @@ -119,7 +123,7 @@ static void ssl_ext_mlc_unregister(void) { ap_hook_unregister("ap::mod_log_config::log_c", ssl_ext_mlc_log_c); - ap_hook_unregister("ap::mod_log_config::log_x", + ap_hook_unregister("ap::mod_log_config::log_x", ssl_ext_mlc_log_x); return; } @@ -135,17 +139,17 @@ static char *ssl_ext_mlc_log_c(request_rec *r, char *a) if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL) return NULL; result = NULL; - if (strcmp(a, "version") == 0) + if (strEQ(a, "version")) result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_PROTOCOL"); - else if (strcmp(a, "cipher") == 0) + else if (strEQ(a, "cipher")) result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER"); - else if (strcmp(a, "subjectdn") == 0 || strcmp(a, "clientcert") == 0) + else if (strEQ(a, "subjectdn") || strEQ(a, "clientcert")) result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_S_DN"); - else if (strcmp(a, "issuerdn") == 0 || strcmp(a, "cacert") == 0) + else if (strEQ(a, "issuerdn") || strEQ(a, "cacert")) result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CLIENT_I_DN"); - else if (strcmp(a, "errcode") == 0) + else if (strEQ(a, "errcode")) result = "-"; - else if (strcmp(a, "errstr") == 0) + else if (strEQ(a, "errstr")) result = ap_ctx_get(r->connection->client->ctx, "ssl::verify::error"); if (result != NULL && result[0] == NUL) result = NULL; @@ -188,7 +192,7 @@ static void ssl_ext_mr_register(void) static void ssl_ext_mr_unregister(void) { - ap_hook_unregister("ap::mod_rewrite::lookup_variable", + ap_hook_unregister("ap::mod_rewrite::lookup_variable", ssl_ext_mr_lookup_variable); return; } @@ -251,7 +255,7 @@ static int ssl_ext_mp_canon(request_rec *r, char *url) { int rc; - if (strncasecmp(url, "https:", 6) == 0) { + if (strcEQn(url, "https:", 6)) { rc = OK; ap_hook_call("ap::mod_proxy::http::canon", &rc, r, url+6, "https", DEFAULT_HTTPS_PORT); @@ -265,18 +269,21 @@ static int ssl_ext_mp_handler( { int rc; - if (strcasecmp(protocol, "https") == 0) { - ap_ctx_set(r->ctx, "ssl_enabled", (void *)1); + if (strcEQ(protocol, "https")) { + ap_ctx_set(r->ctx, "ssl::proxy::enabled", PTRUE); ap_hook_call("ap::mod_proxy::http::handler", &rc, r, cr, url, proxyhost, proxyport); return rc; } + else { + ap_ctx_set(r->ctx, "ssl::proxy::enabled", PFALSE); + } return DECLINED; } static int ssl_ext_mp_set_destport(request_rec *r) { - if (ap_ctx_get(r->ctx, "ssl_enabled") == (void *)1) + if (ap_ctx_get(r->ctx, "ssl::proxy::enabled") == PTRUE) return DEFAULT_HTTPS_PORT; else return DEFAULT_HTTP_PORT; @@ -288,18 +295,30 @@ static char *ssl_ext_mp_new_connection(request_rec *r, BUFF *fb) SSL *ssl; char *errmsg; int rc; + char *cpVHostID; - if (ap_ctx_get(r->ctx, "ssl_enabled") != (void *)1) + if (ap_ctx_get(r->ctx, "ssl::proxy::enabled") == PFALSE) return NULL; + cpVHostID = ssl_util_vhostid(r->pool, r->server); /* * Create a SSL context and handle */ ssl_ctx = SSL_CTX_new(SSLv23_client_method()); - ssl = SSL_new(ssl_ctx); + if ((ssl = SSL_new(ssl_ctx)) == NULL) { + errmsg = ap_pstrcat(r->pool, "SSL new failed (%s): ", cpVHostID, + ERR_reason_error_string(ERR_get_error()), NULL); + ap_ctx_set(fb->ctx, "ssl", NULL); + return errmsg; + } SSL_clear(ssl); + SSL_set_session_id_context(ssl, (unsigned char *)cpVHostID, strlen(cpVHostID)); SSL_set_fd(ssl, fb->fd); ap_ctx_set(fb->ctx, "ssl", ssl); + + /* + * Give us a chance to gracefully close the connection + */ ap_register_cleanup(r->pool, (void *)fb, ssl_ext_mp_close_connection, ssl_ext_mp_close_connection); @@ -307,9 +326,10 @@ static char *ssl_ext_mp_new_connection(request_rec *r, BUFF *fb) * Establish the SSL connection */ if ((rc = SSL_connect(ssl)) <= 0) { - errmsg = ap_pstrcat(r->pool, "SSL connect failed: ", + errmsg = ap_pstrcat(r->pool, "SSL connect failed (%s): ", cpVHostID, ERR_reason_error_string(ERR_get_error()), NULL); SSL_free(ssl); + ap_ctx_set(fb->ctx, "ssl", NULL); return errmsg; } @@ -324,7 +344,7 @@ static void ssl_ext_mp_close_connection(void *_fb) ssl = ap_ctx_get(fb->ctx, "ssl"); if (ssl != NULL) { SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); } @@ -334,7 +354,7 @@ static void ssl_ext_mp_close_connection(void *_fb) static int ssl_ext_mp_write_host_header( request_rec *r, BUFF *fb, char *host, int port, char *portstr) { - if (ap_ctx_get(r->ctx, "ssl_enabled") != (void *)1) + if (ap_ctx_get(r->ctx, "ssl::proxy::enabled") == PFALSE) return DECLINED; if (portstr != NULL && port != DEFAULT_HTTPS_PORT) { @@ -344,3 +364,50 @@ static int ssl_ext_mp_write_host_header( return DECLINED; } + +/* _________________________________________________________________ +** +** SSL Extension to mod_status +** _________________________________________________________________ +*/ + +static void ssl_ext_ms_display(request_rec *, int, int); + +static void ssl_ext_ms_register(void) +{ + ap_hook_register("ap::mod_status::display", ssl_ext_ms_display, AP_HOOK_NOCTX); + return; +} + +static void ssl_ext_ms_unregister(void) +{ + ap_hook_unregister("ap::mod_status::display", ssl_ext_ms_display); + return; +} + +static void ssl_ext_ms_display_cb(char *str, void *_r) +{ + request_rec *r = (request_rec *)_r; + if (str != NULL) + ap_rputs(str, r); + return; +} + +static void ssl_ext_ms_display(request_rec *r, int no_table_report, int short_report) +{ + SSLSrvConfigRec *sc = mySrvConfig(r->server); + + if (sc == NULL) + return; + ap_rputs("<hr>\n", r); + ap_rputs("<table cellspacing=0 cellpadding=0>\n", r); + ap_rputs("<tr><td bgcolor=\"#000000\">\n", r); + ap_rputs("<b><font color=\"#ffffff\" face=\"Arial,Helvetica\">SSL/TLS Session Cache Status:</font></b>\r", r); + ap_rputs("</td></tr>\n", r); + ap_rputs("<tr><td bgcolor=\"#ffffff\">\n", r); + ssl_scache_status(r->server, r->pool, ssl_ext_ms_display_cb, r); + ap_rputs("</td></tr>\n", r); + ap_rputs("</table>\n", r); + return; +} + diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c index 1cb917793de..37c0e9ea33b 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_init.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_init.c ** Initialization of Servers @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -128,6 +128,11 @@ void ssl_init_Module(server_rec *s, pool *p) mc->nInitCount++; /* + * Let us cleanup on restarts and exists + */ + ap_register_cleanup(p, s, ssl_init_ModuleKill, ssl_init_ChildKill); + + /* * Any init round fixes the global config */ ssl_config_global_create(); /* just to avoid problems */ @@ -153,9 +158,21 @@ void ssl_init_Module(server_rec *s, pool *p) sc->nPassPhraseDialogType = SSL_PPTYPE_BUILTIN; /* Open the dedicated SSL logfile */ - ssl_log_open(s2, p); + ssl_log_open(s, s2, p); } + /* + * Identification + */ + if (mc->nInitCount == 1) + ssl_log(s, SSL_LOG_INFO, "Server: %s, Interface: %s, Library: %s", + SERVER_BASEVERSION, + ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_INTERFACE"), + ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_LIBRARY")); + + /* + * Initialization round information + */ if (mc->nInitCount == 1) ssl_log(s, SSL_LOG_INFO, "Init: 1st startup round (still not detached)"); else if (mc->nInitCount == 2) @@ -164,6 +181,11 @@ void ssl_init_Module(server_rec *s, pool *p) ssl_log(s, SSL_LOG_INFO, "Init: %d%s restart round (already detached)", mc->nInitCount-2, (mc->nInitCount-2) == 1 ? "st" : "nd"); +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::init_module", + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, p); +#endif + /* * The initialization phase inside the Apache API is totally bogus. * We actually have three non-trivial problems: @@ -200,10 +222,15 @@ void ssl_init_Module(server_rec *s, pool *p) */ #ifdef SHARED_MODULE - ssl_init_SSLLibrary(s); + ssl_log(s, SSL_LOG_INFO, "Init: %snitializing %s library", + mc->nInitCount == 1 ? "I" : "Rei", SSL_LIBRARY_NAME); + ssl_init_SSLLibrary(); #else - if (mc->nInitCount <= 2) - ssl_init_SSLLibrary(s); + if (mc->nInitCount <= 2) { + ssl_log(s, SSL_LOG_INFO, "Init: %snitializing %s library", + mc->nInitCount == 1 ? "I" : "Rei", SSL_LIBRARY_NAME); + ssl_init_SSLLibrary(); + } #endif if (mc->nInitCount == 1) { ssl_pphrase_Handle(s, p); @@ -235,23 +262,49 @@ void ssl_init_Module(server_rec *s, pool *p) ssl_log(s, SSL_LOG_INFO, "Init: Seeding PRNG with %d bytes of entropy", n); /* - * pre-generate the temporary RSA key + * pre-generate the temporary RSA keys */ - if (mc->pRSATmpKey == NULL) { - ssl_log(s, SSL_LOG_INFO, "Init: Generating temporary (512 bit) RSA private key"); - mc->pRSATmpKey = RSA_generate_key(512, RSA_F4, NULL, NULL); - if (mc->pRSATmpKey == NULL) { + if (mc->pRSATmpKey512 == NULL) { + ssl_log(s, SSL_LOG_INFO, "Init: Generating temporary RSA private keys (512/1024 bits)"); + mc->pRSATmpKey512 = RSA_generate_key(512, RSA_F4, NULL, NULL); + if (mc->pRSATmpKey512 == NULL) { #ifdef __OpenBSD__ - ssl_log(s, SSL_LOG_ERROR, "Init: Failed to generate temporary (512 bit) RSA private key (SSL won't work without an RSA capable shared library)"); - ssl_log(s, SSL_LOG_ERROR, "Init: pkg_add ftp://ftp.openbsd.org/pub/OpenBSD/<version>/packages/<arch>/libssl-1.1.tgz if you are able to use RSA"); - /* harmless in http only case. We'll get a fatal error below - * if this didn't work and we try to init https servers - */ - return; + ssl_log(s, SSL_LOG_ERROR, "Init: Failed to generate temporary (512 b +it) RSA private key (SSL won't work without an RSA capable shared library)"); + ssl_log(s, SSL_LOG_ERROR, "Init: pkg_add ftp://ftp.openbsd.org/pub/O +penBSD/<version>/packages/<arch>/libssl-2.1.tgz if you are able to use RSA"); + /* harmless in http only case. We'll get a fatal error below + * if this didn't work and we try to init https servers + */ + return; #else - ssl_log(s, SSL_LOG_ERROR, "Init: Failed to generate temporary (512 bit) RSA private key"); + ssl_log(s, SSL_LOG_ERROR, "Init: Failed to generate temporary (512 b +it) RSA private key"); ssl_die(); #endif + + } + mc->pRSATmpKey1024 = RSA_generate_key(1024, RSA_F4, NULL, NULL); + if (mc->pRSATmpKey1024 == NULL) { + ssl_log(s, SSL_LOG_ERROR, "Init: Failed to generate temporary 1024 bit RSA private key"); + ssl_die(); + } + } + + /* + * pre-configure the temporary DH parameters + */ + if (mc->pDHTmpParam512 == NULL) { + ssl_log(s, SSL_LOG_INFO, "Init: Configuring temporary DH parameters (512/1024 bits)"); + mc->pDHTmpParam512 = ssl_dh_GetTmpParam(512); + if (mc->pDHTmpParam512 == NULL) { + ssl_log(s, SSL_LOG_ERROR, "Init: Failed to configure temporary 512 bit DH parameters"); + ssl_die(); + } + mc->pDHTmpParam1024 = ssl_dh_GetTmpParam(1024); + if (mc->pDHTmpParam1024 == NULL) { + ssl_log(s, SSL_LOG_ERROR, "Init: Failed to configure temporary 1024 bit DH parameters"); + ssl_die(); } } @@ -259,40 +312,31 @@ void ssl_init_Module(server_rec *s, pool *p) * initialize servers */ ssl_log(s, SSL_LOG_INFO, "Init: Initializing (virtual) servers for SSL"); - for (; s != NULL; s = s->next) { - sc = mySrvConfig(s); - - /* - * Give out warnings when HTTPS is configured for - * the HTTP port or vice versa - */ - if (sc->bEnabled && s->port == DEFAULT_HTTP_PORT) - ssl_log(s, SSL_LOG_WARN, - "Init: You configured HTTPS(%d) on the standard HTTP(%d) port!", - DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT); - if (!sc->bEnabled && s->port == DEFAULT_HTTPS_PORT) - ssl_log(s, SSL_LOG_WARN, - "Init: You configured HTTP(%d) on the standard HTTPS(%d) port!", - DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT); - - /* + for (s2 = s; s2 != NULL; s2 = s2->next) { + sc = mySrvConfig(s2); + /* * Either now skip this server when SSL is disabled for * it or give out some information about what we're * configuring. */ if (!sc->bEnabled) continue; - ssl_log(s, SSL_LOG_INFO, + ssl_log(s2, SSL_LOG_INFO, "Init: Configuring server %s for SSL protocol", - ssl_util_vhostid(p, s)); + ssl_util_vhostid(p, s2)); /* * Read the server certificate and key */ - ssl_init_GetCertAndKey(s, p, sc); + ssl_init_ConfigureServer(s2, p, sc); } /* + * Configuration consistency checks + */ + ssl_init_CheckServers(s, p); + + /* * Announce mod_ssl and SSL library in HTTP Server field * as ``mod_ssl/X.X.X OpenSSL/X.X.X'' */ @@ -307,30 +351,36 @@ void ssl_init_Module(server_rec *s, pool *p) /* * Initialize SSL library (also already needed for the pass phrase dialog) */ -void ssl_init_SSLLibrary(server_rec *s) +void ssl_init_SSLLibrary(void) { - ssl_log(s, SSL_LOG_INFO, "Init: Initializing %s library", SSL_LIBRARY_NAME); #ifdef WIN32 CRYPTO_malloc_init(); #endif SSL_load_error_strings(); - SSLeay_add_ssl_algorithms(); + SSL_library_init(); ssl_util_thread_setup(); + X509V3_add_standard_extensions(); return; } /* - * Read the SSL Server Certificate and Key + * Configure a particular server */ -void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc) +void ssl_init_ConfigureServer(server_rec *s, pool *p, SSLSrvConfigRec *sc) { SSLModConfigRec *mc = myModConfig(); int nVerify; char *cpVHostID; + EVP_PKEY *pKey; SSL_CTX *ctx; - STACK *skCAList; + STACK_OF(X509_NAME) *skCAList; ssl_asn1_t *asn1; + unsigned char *ucp; char *cp; + BOOL ok; + BOOL bSkipFirst; + int isca, pathlen; + int i, n; /* * Create the server host:port string because we need it a lot @@ -341,7 +391,7 @@ void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc) * Now check for important parameters and the * possibility that the user forgot to set them. */ - if (sc->szCertificateFile == NULL) { + if (sc->szPublicCertFile[0] == NULL) { ssl_log(s, SSL_LOG_ERROR, "Init: (%s) No SSL Certificate set [hint: SSLCertificateFile]", cpVHostID); @@ -351,7 +401,8 @@ void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc) /* * Check for problematic re-initializations */ - if (sc->px509Certificate) { + if (sc->pPublicCert[SSL_AIDX_RSA] != NULL || + sc->pPublicCert[SSL_AIDX_DSA] != NULL ) { ssl_log(s, SSL_LOG_ERROR, "Init: (%s) Illegal attempt to re-initialise SSL for server " "(theoretically shouldn't happen!)", cpVHostID); @@ -367,26 +418,36 @@ void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc) cpVHostID); ssl_die(); } - cp = ap_pstrcat(p, (sc->nProtocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""), - (sc->nProtocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""), + cp = ap_pstrcat(p, (sc->nProtocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""), + (sc->nProtocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""), (sc->nProtocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""), NULL); cp[strlen(cp)-2] = NUL; - ssl_log(s, SSL_LOG_TRACE, + ssl_log(s, SSL_LOG_TRACE, "Init: (%s) Creating new SSL context (protocols: %s)", cpVHostID, cp); if (sc->nProtocol == SSL_PROTOCOL_SSLV2) - ctx = SSL_CTX_new(SSLv2_server_method()); /* only SSLv2 is left */ + ctx = SSL_CTX_new(SSLv2_server_method()); /* only SSLv2 is left */ else ctx = SSL_CTX_new(SSLv23_server_method()); /* be more flexible */ + SSL_CTX_set_options(ctx, SSL_OP_ALL); if (!(sc->nProtocol & SSL_PROTOCOL_SSLV2)) SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2); if (!(sc->nProtocol & SSL_PROTOCOL_SSLV3)) SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3); - if (!(sc->nProtocol & SSL_PROTOCOL_TLSV1)) + if (!(sc->nProtocol & SSL_PROTOCOL_TLSV1)) SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1); SSL_CTX_set_app_data(ctx, s); sc->pSSLCtx = ctx; /* + * Configure additional context ingredients + */ + SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); + if (mc->nSessionCacheMode == SSL_SCMODE_UNSET) + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + else + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); + + /* * Configure callbacks for SSL context */ nVerify = SSL_VERIFY_NONE; @@ -400,15 +461,17 @@ void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc) SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry); SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry); SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); + SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState); /* * Configure SSL Cipher Suite */ - ssl_log(s, SSL_LOG_TRACE, - "Init: (%s) Configuring permitted SSL ciphers", cpVHostID); if (sc->szCipherSuite != NULL) { - if (!SSL_CTX_set_cipher_list(sc->pSSLCtx, sc->szCipherSuite)) { + ssl_log(s, SSL_LOG_TRACE, + "Init: (%s) Configuring permitted SSL ciphers [%s]", + cpVHostID, sc->szCipherSuite); + if (!SSL_CTX_set_cipher_list(ctx, sc->szCipherSuite)) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, "Init: (%s) Unable to configure permitted SSL ciphers", cpVHostID); @@ -422,8 +485,8 @@ void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc) if (sc->szCACertificateFile != NULL || sc->szCACertificatePath != NULL) { ssl_log(s, SSL_LOG_TRACE, "Init: (%s) Configuring client authentication", cpVHostID); - if (!SSL_CTX_load_verify_locations(sc->pSSLCtx, - sc->szCACertificateFile, + if (!SSL_CTX_load_verify_locations(ctx, + sc->szCACertificateFile, sc->szCACertificatePath)) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, "Init: (%s) Unable to configure verify locations " @@ -441,41 +504,258 @@ void ssl_init_GetCertAndKey(server_rec *s, pool *p, SSLSrvConfigRec *sc) } /* + * Configure Certificate Revocation List (CRL) Details + */ + if (sc->szCARevocationFile != NULL || sc->szCARevocationPath != NULL) { + ssl_log(s, SSL_LOG_TRACE, + "Init: (%s) Configuring certificate revocation facility", cpVHostID); + if ((sc->pRevocationStore = + SSL_X509_STORE_create(sc->szCARevocationFile, + sc->szCARevocationPath)) == NULL) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: (%s) Unable to configure X.509 CRL storage " + "for certificate revocation", cpVHostID); + ssl_die(); + } + } + + /* * Give a warning when no CAs were configured but client authentication * should take place. This cannot work. */ if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE) { - skCAList = SSL_CTX_get_client_CA_list(sc->pSSLCtx); - if (sk_num(skCAList) == 0) - ssl_log(s, SSL_LOG_WARN, + skCAList = SSL_CTX_get_client_CA_list(ctx); + if (sk_X509_NAME_num(skCAList) == 0) + ssl_log(s, SSL_LOG_WARN, "Init: Ops, you want to request client authentication, " "but no CAs are known for verification!? " "[Hint: SSLCACertificate*]"); } /* - * Configure server certificate + * Configure server certificate(s) */ - ssl_log(s, SSL_LOG_TRACE, - "Init: (%s) Configuring server certificate", cpVHostID); - if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPublicCert, cpVHostID)) == NULL) { + ok = FALSE; + cp = ap_psprintf(p, "%s:RSA", cpVHostID); + if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPublicCert, cp)) != NULL) { + ssl_log(s, SSL_LOG_TRACE, + "Init: (%s) Configuring RSA server certificate", cpVHostID); + ucp = asn1->cpData; + sc->pPublicCert[SSL_AIDX_RSA] = d2i_X509(NULL, &ucp, asn1->nData); + if (SSL_CTX_use_certificate(ctx, sc->pPublicCert[SSL_AIDX_RSA]) <= 0) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: (%s) Unable to configure RSA server certificate", + cpVHostID); + ssl_die(); + } + ok = TRUE; + } + cp = ap_psprintf(p, "%s:DSA", cpVHostID); + if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPublicCert, cp)) != NULL) { + ssl_log(s, SSL_LOG_TRACE, + "Init: (%s) Configuring DSA server certificate", cpVHostID); + ucp = asn1->cpData; + sc->pPublicCert[SSL_AIDX_DSA] = d2i_X509(NULL, &ucp, asn1->nData); + if (SSL_CTX_use_certificate(ctx, sc->pPublicCert[SSL_AIDX_DSA]) <= 0) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: (%s) Unable to configure DSA server certificate", + cpVHostID); + ssl_die(); + } + ok = TRUE; + } + if (!ok) { ssl_log(s, SSL_LOG_ERROR, - "Init: (%s) Ops, can't find server certificate?!", cpVHostID); + "Init: (%s) Ops, no RSA or DSA server certificate found?!", cpVHostID); + ssl_log(s, SSL_LOG_ERROR, + "Init: (%s) You have to perform a *full* server restart when you added or removed a certificate and/or key file", cpVHostID); ssl_die(); } - sc->px509Certificate = d2i_X509(NULL, &(asn1->cpData), asn1->nData); /* - * Configure server private key + * Some information about the certificate(s) */ - ssl_log(s, SSL_LOG_TRACE, - "Init: (%s) Configuring server private key", cpVHostID); - if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPrivateKey, cpVHostID)) == NULL) { + for (i = 0; i < SSL_AIDX_MAX; i++) { + if (sc->pPublicCert[i] != NULL) { + if (SSL_X509_isSGC(sc->pPublicCert[i])) { + ssl_log(s, SSL_LOG_INFO, + "Init: (%s) %s server certificate enables " + "Server Gated Cryptography (SGC)", + cpVHostID, (i == SSL_AIDX_RSA ? "RSA" : "DSA")); + } + if (SSL_X509_getBC(sc->pPublicCert[i], &isca, &pathlen)) { + if (isca) + ssl_log(s, SSL_LOG_WARN, + "Init: (%s) %s server certificate is a CA certificate " + "(BasicConstraints: CA == TRUE !?)", + cpVHostID, (i == SSL_AIDX_RSA ? "RSA" : "DSA")); + if (pathlen > 0) + ssl_log(s, SSL_LOG_WARN, + "Init: (%s) %s server certificate is not a leaf certificate " + "(BasicConstraints: pathlen == %d > 0 !?)", + cpVHostID, (i == SSL_AIDX_RSA ? "RSA" : "DSA"), pathlen); + } + if (SSL_X509_getCN(p, sc->pPublicCert[i], &cp)) { + if (strNE(s->server_hostname, cp)) { + ssl_log(s, SSL_LOG_WARN, + "Init: (%s) %s server certificate CommonName (CN) `%s' " + "does NOT match server name!?", cpVHostID, + (i == SSL_AIDX_RSA ? "RSA" : "DSA"), cp); + } + } + } + } + + /* + * Configure server private key(s) + */ + ok = FALSE; + cp = ap_psprintf(p, "%s:RSA", cpVHostID); + if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPrivateKey, cp)) != NULL) { + ssl_log(s, SSL_LOG_TRACE, + "Init: (%s) Configuring RSA server private key", cpVHostID); + ucp = asn1->cpData; + sc->pPrivateKey[SSL_AIDX_RSA] = + d2i_PrivateKey(EVP_PKEY_RSA, NULL, &ucp, asn1->nData); + if (SSL_CTX_use_PrivateKey(ctx, sc->pPrivateKey[SSL_AIDX_RSA]) <= 0) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: (%s) Unable to configure server RSA private key", + cpVHostID); + ssl_die(); + } + ok = TRUE; + } + cp = ap_psprintf(p, "%s:DSA", cpVHostID); + if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPrivateKey, cp)) != NULL) { + ssl_log(s, SSL_LOG_TRACE, + "Init: (%s) Configuring DSA server private key", cpVHostID); + ucp = asn1->cpData; + sc->pPrivateKey[SSL_AIDX_DSA] = + d2i_PrivateKey(EVP_PKEY_DSA, NULL, &ucp, asn1->nData); + if (SSL_CTX_use_PrivateKey(ctx, sc->pPrivateKey[SSL_AIDX_DSA]) <= 0) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: (%s) Unable to configure server DSA private key", + cpVHostID); + ssl_die(); + } + ok = TRUE; + } + if (!ok) { ssl_log(s, SSL_LOG_ERROR, - "Init: (%s) Ops, can't find server private key?!", cpVHostID); + "Init: (%s) Ops, no RSA or DSA server private key found?!", cpVHostID); ssl_die(); } - sc->prsaKey = d2i_RSAPrivateKey(NULL, &(asn1->cpData), asn1->nData); + + /* + * Optionally copy DSA parameters for certificate from private key + * (see http://www.psy.uq.edu.au/~ftp/Crypto/ssleay/TODO.html) + */ + if ( sc->pPublicCert[SSL_AIDX_DSA] != NULL + && sc->pPrivateKey[SSL_AIDX_DSA] != NULL) { + pKey = X509_get_pubkey(sc->pPublicCert[SSL_AIDX_DSA]); + if ( pKey != NULL + && EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA + && EVP_PKEY_missing_parameters(pKey)) + EVP_PKEY_copy_parameters(pKey, sc->pPrivateKey[SSL_AIDX_DSA]); + } + + /* + * Optionally configure extra server certificate chain certificates. + * This is usually done by OpenSSL automatically when one of the + * server cert issuers are found under SSLCACertificatePath or in + * SSLCACertificateFile. But because these are intended for client + * authentication it can conflict. For instance when you use a + * Global ID server certificate you've to send out the intermediate + * CA certificate, too. When you would just configure this with + * SSLCACertificateFile and also use client authentication mod_ssl + * would accept all clients also issued by this CA. Obviously this + * isn't what we want in this situation. So this feature here exists + * to allow one to explicity configure CA certificates which are + * used only for the server certificate chain. + */ + if (sc->szCertificateChain != NULL) { + bSkipFirst = FALSE; + for (i = 0; i < SSL_AIDX_MAX && sc->szPublicCertFile[i] != NULL; i++) { + if (strEQ(sc->szPublicCertFile[i], sc->szCertificateChain)) { + bSkipFirst = TRUE; + break; + } + } + if ((n = SSL_CTX_use_certificate_chain(ctx, sc->szCertificateChain, + bSkipFirst, NULL)) < 0) { + ssl_log(s, SSL_LOG_ERROR, + "Init: (%s) Failed to configure CA certificate chain!", cpVHostID); + ssl_die(); + } + ssl_log(s, SSL_LOG_TRACE, "Init: (%s) Configuring " + "server certificate chain (%d CA certificate%s)", cpVHostID, + n, n == 1 ? "" : "s"); + } + + return; +} + +void ssl_init_CheckServers(server_rec *sm, pool *p) +{ + server_rec *s; + server_rec **ps; + SSLSrvConfigRec *sc; + ssl_ds_table *t; + pool *sp; + char *key; + BOOL bConflict; + + /* + * Give out warnings when a server has HTTPS configured + * for the HTTP port or vice versa + */ + for (s = sm; s != NULL; s = s->next) { + sc = mySrvConfig(s); + if (sc->bEnabled && s->port == DEFAULT_HTTP_PORT) + ssl_log(sm, SSL_LOG_WARN, + "Init: (%s) You configured HTTPS(%d) on the standard HTTP(%d) port!", + ssl_util_vhostid(p, s), DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT); + if (!sc->bEnabled && s->port == DEFAULT_HTTPS_PORT) + ssl_log(sm, SSL_LOG_WARN, + "Init: (%s) You configured HTTP(%d) on the standard HTTPS(%d) port!", + ssl_util_vhostid(p, s), DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT); + } + + /* + * Give out warnings when more than one SSL-aware virtual server uses the + * same IP:port. This doesn't work because mod_ssl then will always use + * just the certificate/keys of one virtual host (which one cannot be said + * easily - but that doesn't matter here). + */ + sp = ap_make_sub_pool(p); + t = ssl_ds_table_make(sp, sizeof(server_rec *)); + bConflict = FALSE; + for (s = sm; s != NULL; s = s->next) { + sc = mySrvConfig(s); + if (!sc->bEnabled) + continue; + key = ap_psprintf(sp, "%pA:%u", &s->addrs->host_addr, s->addrs->host_port); + ps = ssl_ds_table_get(t, key); + if (ps != NULL) { + ssl_log(sm, SSL_LOG_WARN, + "Init: SSL server IP/port conflict: %s (%s:%d) vs. %s (%s:%d)", + ssl_util_vhostid(p, s), + (s->defn_name != NULL ? s->defn_name : "unknown"), + s->defn_line_number, + ssl_util_vhostid(p, *ps), + ((*ps)->defn_name != NULL ? (*ps)->defn_name : "unknown"), + (*ps)->defn_line_number); + bConflict = TRUE; + continue; + } + ps = ssl_ds_table_push(t, key); + *ps = s; + } + ssl_ds_table_kill(t); + ap_destroy_pool(sp); + if (bConflict) + ssl_log(sm, SSL_LOG_WARN, + "Init: You cannot use name-based virtual hosts in conjunction with SSL!!"); return; } @@ -485,10 +765,10 @@ static int ssl_init_FindCAList_X509NameCmp(X509_NAME **a, X509_NAME **b) return(X509_NAME_cmp(*a, *b)); } -STACK *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApath) +STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApath) { - STACK *skCAList; - STACK *sk; + STACK_OF(X509_NAME) *skCAList; + STACK_OF(X509_NAME) *sk; DIR *dir; struct DIR_TYPE *direntry; char *cp; @@ -506,19 +786,19 @@ STACK *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApa * Start with a empty stack/list where new * entries get added in sorted order. */ - skCAList = sk_new(ssl_init_FindCAList_X509NameCmp); + skCAList = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp); /* * Process CA certificate bundle file */ if (cpCAfile != NULL) { sk = SSL_load_client_CA_file(cpCAfile); - for(n = 0; sk != NULL && n < sk_num(sk); n++) { + for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) { ssl_log(s, SSL_LOG_TRACE, "CA certificate: %s", - X509_NAME_oneline((X509_NAME *)sk_value(sk, n), NULL, 0)); - if (sk_find(skCAList, sk_value(sk, n)) < 0) - sk_push(skCAList, sk_value(sk, n)); + X509_NAME_oneline(sk_X509_NAME_value(sk, n), NULL, 0)); + if (sk_X509_NAME_find(skCAList, sk_X509_NAME_value(sk, n)) < 0) + sk_X509_NAME_push(skCAList, sk_X509_NAME_value(sk, n)); } } @@ -530,12 +810,12 @@ STACK *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApa while ((direntry = readdir(dir)) != NULL) { cp = ap_pstrcat(p, cpCApath, "/", direntry->d_name, NULL); sk = SSL_load_client_CA_file(cp); - for(n = 0; sk != NULL && n < sk_num(sk); n++) { + for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) { ssl_log(s, SSL_LOG_TRACE, "CA certificate: %s", - X509_NAME_oneline((X509_NAME *)sk_value(sk, n), NULL, 0)); - if (sk_find(skCAList, sk_value(sk, n)) < 0) - sk_push(skCAList, sk_value(sk, n)); + X509_NAME_oneline(sk_X509_NAME_value(sk, n), NULL, 0)); + if (sk_X509_NAME_find(skCAList, sk_X509_NAME_value(sk, n)) < 0) + sk_X509_NAME_push(skCAList, sk_X509_NAME_value(sk, n)); } } ap_pclosedir(p, dir); @@ -544,7 +824,7 @@ STACK *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApa /* * Cleanup */ - sk_set_cmp_func(skCAList, NULL); + sk_X509_NAME_set_cmp_func(skCAList, NULL); ap_destroy_pool(p); return skCAList; @@ -553,7 +833,54 @@ STACK *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApa void ssl_init_Child(server_rec *s, pool *p) { /* open the mutex lockfile */ - ssl_mutex_open(s, p); + ssl_mutex_reinit(s, p); return; } +void ssl_init_ChildKill(void *data) +{ + /* currently nothing to do */ + return; +} + +void ssl_init_ModuleKill(void *data) +{ + SSLSrvConfigRec *sc; + server_rec *s = (server_rec *)data; + + /* + * Drop the session cache and mutex + */ + ssl_scache_kill(s); + ssl_mutex_kill(s); + + /* + * Free the non-pool allocated structures + * in the per-server configurations + */ + for (; s != NULL; s = s->next) { + sc = mySrvConfig(s); + if (sc->pPublicCert[SSL_AIDX_RSA] != NULL) { + X509_free(sc->pPublicCert[SSL_AIDX_RSA]); + sc->pPublicCert[SSL_AIDX_RSA] = NULL; + } + if (sc->pPublicCert[SSL_AIDX_DSA] != NULL) { + X509_free(sc->pPublicCert[SSL_AIDX_DSA]); + sc->pPublicCert[SSL_AIDX_DSA] = NULL; + } + if (sc->pPrivateKey[SSL_AIDX_RSA] != NULL) { + EVP_PKEY_free(sc->pPrivateKey[SSL_AIDX_RSA]); + sc->pPrivateKey[SSL_AIDX_RSA] = NULL; + } + if (sc->pPrivateKey[SSL_AIDX_DSA] != NULL) { + EVP_PKEY_free(sc->pPrivateKey[SSL_AIDX_DSA]); + sc->pPrivateKey[SSL_AIDX_DSA] = NULL; + } + if (sc->pSSLCtx != NULL) { + SSL_CTX_free(sc->pSSLCtx); + sc->pSSLCtx = NULL; + } + } + return; +} + diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c index 851c937ab21..e6da098f11f 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_io.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_io.c ** I/O Functions @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -64,6 +64,216 @@ -- Unknown */ #include "mod_ssl.h" +/* _________________________________________________________________ +** +** I/O Request Body Sucking and Re-Injection +** _________________________________________________________________ +*/ + +#ifdef SSL_EXPERIMENTAL + +/* + * Background: + * + * 1. When the client sends a HTTP/HTTPS request, Apache's core code + * reads only the request line ("METHOD /path HTTP/x.y") and the + * attached MIME headers ("Foo: bar") up to the terminating line ("CR + * LF"). An attached request body (for instance the data of a POST + * method) is _NOT_ read. Instead it is read by mod_cgi's content + * handler and directly passed to the CGI script. + * + * 2. mod_ssl supports per-directory re-configuration of SSL parameters. + * This is implemented by performing an SSL renegotiation of the + * re-configured parameters after the request is read, but before the + * response is sent. In more detail: the renegotiation happens after the + * request line and MIME headers were read, but _before_ the attached + * request body is read. The reason simply is that in the HTTP protocol + * usually there is no acknowledgment step between the headers and the + * body (there is the 100-continue feature and the chunking facility + * only), so Apache has no API hook for this step. + * + * 3. the problem now occurs when the client sends a POST request for + * URL /foo via HTTPS the server and the server has SSL parameters + * re-configured on a per-URL basis for /foo. Then mod_ssl has to + * perform an SSL renegotiation after the request was read and before + * the response is sent. But the problem is the pending POST body data + * in the receive buffer of SSL (which Apache still has not read - it's + * pending until mod_cgi sucks it in). When mod_ssl now tries to perform + * the renegotiation the pending data leads to an I/O error. + * + * Solution Idea: + * + * There are only two solutions: Either to simply state that POST + * requests to URLs with SSL re-configurations are not allowed, or to + * renegotiate really after the _complete_ request (i.e. including + * the POST body) was read. Obviously the latter would be preferred, + * but it cannot be done easily inside Apache, because as already + * mentioned, there is no API step between the body reading and the body + * processing. And even when we mod_ssl would hook directly into the + * loop of mod_cgi, we wouldn't solve the problem for other handlers, of + * course. So the only general solution is to suck in the pending data + * of the request body from the OpenSSL BIO into the Apache BUFF. Then + * the renegotiation can be done and after this step Apache can proceed + * processing the request as before. + * + * Solution Implementation: + * + * We cannot simply suck in the data via an SSL_read-based loop because of + * HTTP chunking. Instead we _have_ to use the Apache API for this step which + * is aware of HTTP chunking. So the trick is to suck in the pending request + * data via the Apache API (which uses Apache's BUFF code and in the + * background mod_ssl's I/O glue code) and re-inject it later into the Apache + * BUFF code again. This way the data flows twice through the Apache BUFF, of + * course. But this way the solution doesn't depend on any Apache specifics + * and is fully transparent to Apache modules. + */ + +struct ssl_io_suck_st { + BOOL active; + char *bufptr; + int buflen; + char *pendptr; + int pendlen; +}; + +/* prepare request_rec structure for input sucking */ +static void ssl_io_suck_start(request_rec *r) +{ + struct ssl_io_suck_st *ss; + + ss = ap_ctx_get(r->ctx, "ssl::io::suck"); + if (ss == NULL) { + ss = ap_palloc(r->pool, sizeof(struct ssl_io_suck_st)); + ap_ctx_set(r->ctx, "ssl::io::suck", ss); + ss->buflen = 8192; + ss->bufptr = ap_palloc(r->pool, ss->buflen); + } + ss->pendptr = ss->bufptr; + ss->pendlen = 0; + ss->active = FALSE; + return; +} + +/* record a sucked input chunk */ +static void ssl_io_suck_record(request_rec *r, char *buf, int len) +{ + struct ssl_io_suck_st *ss; + + if ((ss = ap_ctx_get(r->ctx, "ssl::io::suck")) == NULL) + return; + if (((ss->bufptr+ss->buflen)-(ss->pendptr+ss->pendlen)) < len) { + /* "expand" buffer */ + int newlen; + char *newptr; + if (ss->buflen < len) + newlen = ss->buflen * 2; + else + newlen = ss->buflen + len; + newptr = ap_palloc(r->pool, newlen); + memcpy(newptr, ss->bufptr, ss->buflen); + ss->bufptr = newptr; + ss->buflen = newlen; + } + memcpy(ss->pendptr+ss->pendlen, buf, len); + ss->pendlen += len; + return; +} + +/* finish request_rec after input sucking */ +static void ssl_io_suck_end(request_rec *r) +{ + struct ssl_io_suck_st *ss; + + if ((ss = ap_ctx_get(r->ctx, "ssl::io::suck")) == NULL) + return; + ss->active = TRUE; + r->read_body = REQUEST_NO_BODY; + r->read_length = 0; + r->read_chunked = 0; + r->remaining = 0; + ap_bsetflag(r->connection->client, B_CHUNK, 0); + return; +} + +void ssl_io_suck(request_rec *r, SSL *ssl) +{ + int rc; + int len; + char *buf; + int buflen; + char c; + int sucked; + + if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) == OK) { + if (ap_should_client_block(r)) { + + /* read client request block through Apache API */ + buflen = HUGE_STRING_LEN; + buf = ap_palloc(r->pool, buflen); + ap_hard_timeout("SSL I/O request body pre-sucking", r); + sucked = 0; + ssl_io_suck_start(r); + while ((len = ap_get_client_block(r, buf, buflen)) > 0) { + ssl_io_suck_record(r, buf, len); + sucked += len; + } + ssl_io_suck_end(r); + ap_kill_timeout(r); + + /* suck trailing data (usually CR LF) which + is still in the Apache BUFF layer */ + while (ap_bpeekc(r->connection->client) != EOF) { + c = ap_bgetc(r->connection->client); + ssl_io_suck_record(r, &c, 1); + sucked++; + } + + ssl_log(r->server, SSL_LOG_TRACE, + "I/O: sucked %d bytes of input data from SSL/TLS I/O layer " + "for delayed injection into Apache I/O layer", sucked); + } + } + return; +} + +/* the SSL_read replacement routine which known about the suck buffer */ +static int ssl_io_suck_read(SSL *ssl, char *buf, int len) +{ + ap_ctx *actx; + struct ssl_io_suck_st *ss; + request_rec *r = NULL; + int rv; + + actx = (ap_ctx *)SSL_get_app_data2(ssl); + if (actx != NULL) + r = (request_rec *)ap_ctx_get(actx, "ssl::request_rec"); + + rv = -1; + if (r != NULL) { + ss = ap_ctx_get(r->ctx, "ssl::io::suck"); + if (ss != NULL) { + if (ss->active && ss->pendlen > 0) { + /* ok, there is pre-sucked data */ + len = (ss->pendlen > len ? len : ss->pendlen); + memcpy(buf, ss->pendptr, len); + ss->pendptr += len; + ss->pendlen -= len; + ssl_log(r->server, SSL_LOG_TRACE, + "I/O: injecting %d bytes of pre-sucked data " + "into Apache I/O layer", len); + rv = len; + } + } + } + if (rv == -1) + rv = SSL_read(ssl, buf, len); + return rv; +} + +/* override SSL_read in the following code... */ +#define SSL_read ssl_io_suck_read + +#endif /* SSL_EXPERIMENTAL */ /* _________________________________________________________________ ** @@ -94,9 +304,9 @@ void ssl_io_register(void) ap_hook_register("ap::buff::writev", ssl_io_hook_writev, AP_HOOK_NOCTX); #endif #ifdef WIN32 - ap_hook_register("ap::buff::recvwithtimeout", + ap_hook_register("ap::buff::recvwithtimeout", ssl_io_hook_recvwithtimeout, AP_HOOK_NOCTX); - ap_hook_register("ap::buff::sendwithtimeout", + ap_hook_register("ap::buff::sendwithtimeout", ssl_io_hook_sendwithtimeout, AP_HOOK_NOCTX); #endif return; @@ -125,9 +335,9 @@ static int ssl_io_hook_read(BUFF *fb, char *buf, int len) if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) { rc = SSL_read(ssl, buf, len); /* - * Simulate an EINTR in case SSLeay wants to read more. + * Simulate an EINTR in case OpenSSL wants to read more. * (This is usually the case when the client forces an SSL - * renegotation which is handled implicitly by SSLeay.) + * renegotation which is handled implicitly by OpenSSL.) */ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_READ) errno = EINTR; @@ -159,7 +369,7 @@ static int ssl_io_hook_write(BUFF *fb, char *buf, int len) if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) { rc = SSL_write(ssl, buf, len); /* - * Simulate an EINTR in case SSLeay wants to write more. + * Simulate an EINTR in case OpenSSL wants to write more. */ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) errno = EINTR; @@ -195,7 +405,7 @@ static int ssl_io_hook_writev(BUFF *fb, const struct iovec *iov, int iovcnt) if ((ssl = ap_ctx_get(fb->ctx, "ssl")) != NULL) { rc = SSL_writev(ssl, iov, iovcnt); /* - * Simulate an EINTR in case SSLeay wants to write more. + * Simulate an EINTR in case OpenSSL wants to write more. */ if (rc < 0 && SSL_get_error(ssl, rc) == SSL_ERROR_WANT_WRITE) errno = EINTR; @@ -257,7 +467,7 @@ static int ssl_io_hook_sendwithtimeout(BUFF *fb, const char *buf, int len) /* _________________________________________________________________ ** -** Special Functions for SSLeay +** Special Functions for OpenSSL ** _________________________________________________________________ */ @@ -372,8 +582,8 @@ static int SSL_recvwithtimeout(BUFF *fb, char *buf, int len) #endif /*WIN32*/ /* - * There is no SSL_writev() provided by SSLeay. The reason is mainly because - * SSLeay has to fragment the data itself again for the SSL record layer, so a + * There is no SSL_writev() provided by OpenSSL. The reason is mainly because + * OpenSSL has to fragment the data itself again for the SSL record layer, so a * writev() like interface makes not much sense. What we do is to emulate it * to at least being able to use the write() like interface. But keep in mind * that the network I/O performance is not write() like, of course. @@ -405,7 +615,7 @@ static int SSL_writev(SSL *ssl, const struct iovec *iov, int iovcnt) #define DUMP_WIDTH 16 -static void ssl_io_data_dump(server_rec *srvr, char *s, long len) +static void ssl_io_data_dump(server_rec *srvr, const char *s, long len) { char buf[256]; char tmp[64]; @@ -453,34 +663,39 @@ static void ssl_io_data_dump(server_rec *srvr, char *s, long len) return; } -long ssl_io_data_cb(BIO *bio, int cmd, char *argp, int argi, long argl, long len) +long ssl_io_data_cb(BIO *bio, int cmd, const char *argp, int argi, long argl, long rc) { SSL *ssl; conn_rec *c; server_rec *s; if ((ssl = (SSL *)BIO_get_callback_arg(bio)) == NULL) - return len; + return rc; if ((c = (conn_rec *)SSL_get_app_data(ssl)) == NULL) - return len; + return rc; s = c->server; - if (len >= 0) { - ssl_log(s, SSL_LOG_DEBUG, - "%s: %s %ld/%d bytes %s BIO#%08X [mem: %08lX] %s", - SSL_LIBRARY_NAME, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), - len, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"), - bio, argp, (argp != NULL ? "(BIO dump follows)" : "(Ops, no memory buffer?)")); - if (argp != NULL) - ssl_io_data_dump(s, argp, len); - } - else { - ssl_log(s, SSL_LOG_DEBUG, - "%s: I/O error, %d bytes expected to %s on BIO#%08X [mem: %08lX]", - SSL_LIBRARY_NAME, argi, - (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), - bio, argp); + if ( cmd == (BIO_CB_WRITE|BIO_CB_RETURN) + || cmd == (BIO_CB_READ |BIO_CB_RETURN) ) { + if (rc >= 0) { + ssl_log(s, SSL_LOG_DEBUG, + "%s: %s %ld/%d bytes %s BIO#%08X [mem: %08lX] %s", + SSL_LIBRARY_NAME, + (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), + rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"), + bio, argp, + (argp != NULL ? "(BIO dump follows)" : "(Ops, no memory buffer?)")); + if (argp != NULL) + ssl_io_data_dump(s, argp, rc); + } + else { + ssl_log(s, SSL_LOG_DEBUG, + "%s: I/O error, %d bytes expected to %s on BIO#%08X [mem: %08lX]", + SSL_LIBRARY_NAME, argi, + (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"), + bio, argp); + } } - return len; + return rc; } diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c index 99b19843c07..3addfce1275 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_kernel.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_kernel.c ** The SSL engine kernel @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -130,8 +130,11 @@ void ssl_hook_NewConnection(conn_rec *conn) server_rec *srvr; BUFF *fb; SSLSrvConfigRec *sc; + ap_ctx *apctx; SSL *ssl; char *cp; + char *cpVHostID; + X509 *xs; int rc; int n; @@ -158,8 +161,9 @@ void ssl_hook_NewConnection(conn_rec *conn) * Remember the connection information for * later access inside callback functions */ + cpVHostID = ssl_util_vhostid(conn->pool, srvr); ssl_log(srvr, SSL_LOG_INFO, "Connection to child %d established (server %s)", - conn->child_num, ssl_util_vhostid(conn->pool, srvr)); + conn->child_num, cpVHostID); /* * Seed the Pseudo Random Number Generator (PRNG) @@ -172,54 +176,41 @@ void ssl_hook_NewConnection(conn_rec *conn) * attach this to the socket. Additionally we register this attachment * so we can detach later. */ - ssl = SSL_new(sc->pSSLCtx); - SSL_set_app_data(ssl, conn); /* conn_rec (available now) */ - SSL_set_app_data2(ssl, NULL); /* request_rec (available later) */ + if ((ssl = SSL_new(sc->pSSLCtx)) == NULL) { + ssl_log(conn->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Unable to create a new SSL connection from the SSL context"); + ap_ctx_set(fb->ctx, "ssl", NULL); + ap_bsetflag(fb, B_EOF|B_EOUT, 1); + conn->aborted = 1; + return; + } + SSL_clear(ssl); + SSL_set_session_id_context(ssl, (unsigned char *)cpVHostID, strlen(cpVHostID)); + SSL_set_app_data(ssl, conn); + apctx = ap_ctx_new(conn->pool); + ap_ctx_set(apctx, "ssl::request_rec", NULL); + ap_ctx_set(apctx, "ssl::verify::depth", AP_CTX_NUM2PTR(0)); + SSL_set_app_data2(ssl, apctx); SSL_set_fd(ssl, fb->fd); ap_ctx_set(fb->ctx, "ssl", ssl); - ap_register_cleanup(conn->pool, (void *)conn, - ssl_hook_CloseConnection, ssl_hook_CloseConnection); /* - * Configure SSLeay BIO Data Logging + * Configure callbacks for SSL connection */ + SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA); + SSL_set_tmp_dh_callback(ssl, ssl_callback_TmpDH); if (sc->nLogLevel >= SSL_LOG_DEBUG) { BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb); BIO_set_callback_arg(SSL_get_rbio(ssl), ssl); } /* - * Configure the server certificate and private key - * which should be used for this connection. - */ - if (sc->szCertificateFile != NULL) { - if (SSL_use_certificate(ssl, sc->px509Certificate) <= 0) { - ssl_log(conn->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, - "Unable to configure server certificate for connection"); - SSL_free(ssl); - ap_ctx_set(fb->ctx, "ssl", NULL); - ap_bsetflag(fb, B_EOF|B_EOUT, 1); - conn->aborted = 1; - return; - } - if (SSL_use_RSAPrivateKey(ssl, sc->prsaKey) <= 0) { - ssl_log(conn->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, - "Unable to configure server private key for connection"); - SSL_free(ssl); - ap_ctx_set(fb->ctx, "ssl", NULL); - ap_bsetflag(fb, B_EOF|B_EOUT, 1); - conn->aborted = 1; - return; - } - } - - /* * Predefine some client verification results */ ap_ctx_set(fb->ctx, "ssl::client::dn", NULL); ap_ctx_set(fb->ctx, "ssl::verify::error", NULL); - /* + /* * We have to manage a I/O timeout ourself, because Apache * does it the first time when reading the request, but we're * working some time before this happens. @@ -243,7 +234,7 @@ void ssl_hook_NewConnection(conn_rec *conn) ssl_log(srvr, SSL_LOG_INFO, "SSL handshake stopped: connection was closed"); SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); @@ -252,16 +243,15 @@ void ssl_hook_NewConnection(conn_rec *conn) } else if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) { /* - * The case where SSLeay has recognized a HTTP request: + * The case where OpenSSL has recognized a HTTP request: * This means the client speaks plain HTTP on our HTTPS * port. Hmmmm... At least for this error we can be more friendly * and try to provide him with a HTML error page. We have only one - * problem: SSLeay has already read some bytes from the HTTP + * problem: OpenSSL has already read some bytes from the HTTP * request. So we have to skip the request line manually and * instead provide a faked one in order to continue the internal * Apache processing. * - * (This feature is only available for SSLeay 0.9.0 and higher) */ char ca[2]; int rv; @@ -287,7 +277,7 @@ void ssl_hook_NewConnection(conn_rec *conn) /* third: kick away the SSL stuff */ SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); @@ -295,11 +285,11 @@ void ssl_hook_NewConnection(conn_rec *conn) return; } else if (ap_ctx_get(ap_global_ctx, "ssl::handshake::timeout") == (void *)TRUE) { - ssl_log(srvr, SSL_LOG_ERROR, + ssl_log(srvr, SSL_LOG_ERROR, "SSL handshake timed out (client %s, server %s)", - conn->remote_ip, ssl_util_vhostid(conn->pool, srvr)); + conn->remote_ip, cpVHostID); SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); @@ -309,10 +299,16 @@ void ssl_hook_NewConnection(conn_rec *conn) else if (SSL_get_error(ssl, rc) == SSL_ERROR_SYSCALL) { if (errno == EINTR) continue; - ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_ERRNO, - "SSL handshake interrupted by system"); + if (errno > 0) + ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR|SSL_ADD_ERRNO, + "SSL handshake interrupted by system " + "[Hint: Stop button pressed in browser?!]"); + else + ssl_log(srvr, SSL_LOG_INFO|SSL_ADD_SSLERR|SSL_ADD_ERRNO, + "Spurious SSL handshake interrupt" + "[Hint: Usually just one of those OpenSSL confusions!?]"); SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); @@ -325,7 +321,7 @@ void ssl_hook_NewConnection(conn_rec *conn) */ ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR|SSL_ADD_ERRNO, "SSL handshake failed (client %s, server %s)", - conn->remote_ip, ssl_util_vhostid(conn->pool, srvr)); + conn->remote_ip, cpVHostID); /* * try to gracefully shutdown the connection: @@ -335,7 +331,7 @@ void ssl_hook_NewConnection(conn_rec *conn) * - block the socket, so Apache cannot operate any more */ SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); @@ -351,7 +347,7 @@ void ssl_hook_NewConnection(conn_rec *conn) ssl_log(srvr, SSL_LOG_ERROR|SSL_ADD_SSLERR, "SSL client authentication failed: %s", cp); SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); @@ -360,17 +356,12 @@ void ssl_hook_NewConnection(conn_rec *conn) } /* - * Remember the peer certificate when - * client authentication was done + * Remember the peer certificate's DN */ - if (sc->nVerifyClient != SSL_CVERIFY_NONE) { - char *s; - X509 *xs; - if ((xs = SSL_get_peer_certificate(ssl)) != NULL) { - s = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0); - ap_ctx_set(fb->ctx, "ssl::client::dn", ap_pstrdup(conn->pool, s)); - free(s); - } + if ((xs = SSL_get_peer_certificate(ssl)) != NULL) { + cp = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0); + ap_ctx_set(fb->ctx, "ssl::client::dn", ap_pstrdup(conn->pool, cp)); + free(cp); } /* @@ -382,7 +373,7 @@ void ssl_hook_NewConnection(conn_rec *conn) ssl_log(srvr, SSL_LOG_ERROR, "No acceptable peer certificate available"); SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); + SSL_smart_shutdown(ssl); SSL_free(ssl); ap_ctx_set(fb->ctx, "ssl", NULL); ap_bsetflag(fb, B_EOF|B_EOUT, 1); @@ -399,7 +390,7 @@ void ssl_hook_NewConnection(conn_rec *conn) /* * Improve I/O throughput by using - * SSLeay's read-ahead functionality + * OpenSSL's read-ahead functionality * (don't used under Win32, because * there we use select()) */ @@ -407,6 +398,12 @@ void ssl_hook_NewConnection(conn_rec *conn) SSL_set_read_ahead(ssl, TRUE); #endif +#ifdef SSL_VENDOR + /* Allow vendors to do more things on connection time... */ + ap_hook_use("ap::mod_ssl::vendor::new_connection", + AP_HOOK_SIG2(void,ptr), AP_HOOK_ALL, conn); +#endif + return; } @@ -422,29 +419,89 @@ void ssl_hook_TimeoutConnection(int sig) /* * Close the SSL part of the socket connection + * (called immediately _before_ the socket is closed) */ -void ssl_hook_CloseConnection(void *_conn) +void ssl_hook_CloseConnection(conn_rec *conn) { - conn_rec *conn = _conn; SSL *ssl; + char *cpType; + + ssl = ap_ctx_get(conn->client->ctx, "ssl"); + if (ssl == NULL) + return; /* - * Optionally shutdown the SSL session + * First make sure that no more data is pending in Apache's BUFF, + * because when it's (implicitly) flushed later by the ap_bclose() + * calls of Apache it would lead to an I/O error in the browser due + * to the fact that the SSL layer was already removed by us. + */ + ap_bflush(conn->client); + + /* + * Now close the SSL layer of the connection. We've to take + * the TLSv1 standard into account here: + * + * | 7.2.1. Closure alerts + * | + * | The client and the server must share knowledge that the connection is + * | ending in order to avoid a truncation attack. Either party may + * | initiate the exchange of closing messages. + * | + * | close_notify + * | This message notifies the recipient that the sender will not send + * | any more messages on this connection. The session becomes + * | unresumable if any connection is terminated without proper + * | close_notify messages with level equal to warning. + * | + * | Either party may initiate a close by sending a close_notify alert. + * | Any data received after a closure alert is ignored. + * | + * | Each party is required to send a close_notify alert before closing + * | the write side of the connection. It is required that the other party + * | respond with a close_notify alert of its own and close down the + * | connection immediately, discarding any pending writes. It is not + * | required for the initiator of the close to wait for the responding + * | close_notify alert before closing the read side of the connection. + * + * This means we've to send a close notify message, but haven't to wait + * for the close notify of the client. Actually we cannot wait for the + * close notify of the client because some clients (including Netscape + * 4.x) don't send one, so we would hang. */ - ssl = ap_ctx_get(conn->client->ctx, "ssl"); - if (ssl != NULL) { - SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); - while (!SSL_shutdown(ssl)); - SSL_free(ssl); - ap_ctx_set(conn->client->ctx, "ssl", NULL); - } /* - * And finally log the connection close + * exchange close notify messages, but allow the user + * to force the type of handshake via SetEnvIf directive */ - ssl_log(conn->server, SSL_LOG_INFO, "Connection to child %d closed (server %s)", - conn->child_num, ssl_util_vhostid(conn->pool, conn->server)); + if (ap_ctx_get(conn->client->ctx, "ssl::flag::unclean-shutdown") == PTRUE) { + /* perform no close notify handshake at all + (violates the SSL/TLS standard!) */ + SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); + cpType = "unclean"; + } + else if (ap_ctx_get(conn->client->ctx, "ssl::flag::accurate-shutdown") == PTRUE) { + /* send close notify and wait for clients close notify + (standard compliant, but usually causes connection hangs) */ + SSL_set_shutdown(ssl, 0); + cpType = "accurate"; + } + else { + /* send close notify, but don't wait for clients close notify + (standard compliant and safe, so it's the DEFAULT!) */ + SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN); + cpType = "standard"; + } + SSL_smart_shutdown(ssl); + + /* deallocate the SSL connection */ + SSL_free(ssl); + ap_ctx_set(conn->client->ctx, "ssl", NULL); + /* and finally log the fact that we've closed the connection */ + ssl_log(conn->server, SSL_LOG_INFO, + "Connection to child %d closed with %s shutdown (server %s)", + conn->child_num, cpType, ssl_util_vhostid(conn->pool, conn->server)); return; } @@ -454,14 +511,17 @@ void ssl_hook_CloseConnection(void *_conn) int ssl_hook_ReadReq(request_rec *r) { SSL *ssl; + ap_ctx *apctx; /* - * Get the SSL connection structure and perform the + * Get the SSL connection structure and perform the * delayed interlinking from SSL back to request_rec */ ssl = ap_ctx_get(r->connection->client->ctx, "ssl"); - if (ssl != NULL) - SSL_set_app_data2(ssl, r); + if (ssl != NULL) { + apctx = SSL_get_app_data2(ssl); + ap_ctx_set(apctx, "ssl::request_rec", r); + } /* * Force the mod_ssl content handler when URL indicates this @@ -480,6 +540,43 @@ int ssl_hook_ReadReq(request_rec *r) } /* + * URL Translation Handler + */ +int ssl_hook_Translate(request_rec *r) +{ + if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL) + return DECLINED; + + /* + * Log information about incoming HTTPS requests + */ + if (ap_is_initial_req(r)) + ssl_log(r->server, SSL_LOG_INFO, + "%s HTTPS request received for child %d (server %s)", + r->connection->keepalives <= 0 ? + "Initial (No.1)" : + ap_psprintf(r->pool, "Subsequent (No.%d)", + r->connection->keepalives+1), + r->connection->child_num, + ssl_util_vhostid(r->pool, r->server)); + + /* + * Move SetEnvIf information from request_rec to conn_rec/BUFF + * to allow the close connection handler to use them. + */ + if (ap_table_get(r->subprocess_env, "ssl-unclean-shutdown") != NULL) + ap_ctx_set(r->connection->client->ctx, "ssl::flag::unclean-shutdown", PTRUE); + else + ap_ctx_set(r->connection->client->ctx, "ssl::flag::unclean-shutdown", PFALSE); + if (ap_table_get(r->subprocess_env, "ssl-accurate-shutdown") != NULL) + ap_ctx_set(r->connection->client->ctx, "ssl::flag::accurate-shutdown", PTRUE); + else + ap_ctx_set(r->connection->client->ctx, "ssl::flag::accurate-shutdown", PFALSE); + + return DECLINED; +} + +/* * Content Handler */ int ssl_hook_Handler(request_rec *r) @@ -510,55 +607,6 @@ int ssl_hook_Handler(request_rec *r) } /* - * Auth Handler: - * Fake a Basic authentication from the X509 client certificate. - * - * This must be run fairly early on to prevent a real authentication from - * occuring, in particular it must be run before anything else that - * authenticates a user. This means that the Module statement for this - * module should be LAST in the Configuration file. - */ -int ssl_hook_Auth(request_rec *r) -{ - SSLSrvConfigRec *sc = mySrvConfig(r->server); - SSLDirConfigRec *dc = myDirConfig(r); - char b1[MAX_STRING_LEN], b2[MAX_STRING_LEN]; - char *clientdn; - - /* - * We decline operation in various situations.. - */ - if (!sc->bEnabled) - return DECLINED; - if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL) - return DECLINED; - if (!(dc->nOptions & SSL_OPT_FAKEBASICAUTH)) - return DECLINED; - if (r->connection->user) - return DECLINED; - if ((clientdn = (char *)ap_ctx_get(r->connection->client->ctx, "ssl::client::dn")) == NULL) - return DECLINED; - - /* - * Fake a password - which one would be immaterial, as, it seems, an empty - * password in the users file would match ALL incoming passwords, if only - * we were using the standard crypt library routine. Unfortunately, SSLeay - * "fixes" a "bug" in crypt and thus prevents blank passwords from - * working. (IMHO what they really fix is a bug in the users of the code - * - failing to program correctly for shadow passwords). We need, - * therefore, to provide a password. This password can be matched by - * adding the string "xxj31ZMTZzkVA" as the password in the user file. - * This is just the crypted variant of the word "password" ;-) - */ - ap_snprintf(b1, sizeof(b1), "%s:password", clientdn); - ssl_util_uuencode(b2, b1, FALSE); - ap_snprintf(b1, sizeof(b1), "Basic %s", b2); - ap_table_set(r->headers_in, "Authorization", b1); - - return DECLINED; -} - -/* * Access Handler */ int ssl_hook_Access(request_rec *r) @@ -566,25 +614,35 @@ int ssl_hook_Access(request_rec *r) SSLDirConfigRec *dc; SSLSrvConfigRec *sc; SSL *ssl; - SSL_CTX *ctx; + SSL_CTX *ctx = NULL; array_header *apRequirement; ssl_require_t *pRequirements; ssl_require_t *pRequirement; char *cp; int ok; int i; - BOOL renegotiate; + BOOL renegotiate; + BOOL renegotiate_quick; #ifdef SSL_EXPERIMENTAL BOOL reconfigured_locations; - STACK *skCAList; + STACK_OF(X509_NAME) *skCAList; char *cpCAPath; char *cpCAFile; #endif - STACK *skCipherOld; - STACK *skCipher; + X509 *cert; + STACK_OF(X509) *certstack; + X509_STORE *certstore; + X509_STORE_CTX certstorectx; + int depth; + STACK_OF(SSL_CIPHER) *skCipherOld; + STACK_OF(SSL_CIPHER) *skCipher; + SSL_CIPHER *pCipher; + ap_ctx *apctx; int nVerifyOld; int nVerify; int n; + void *vp; + int rc; dc = myDirConfig(r); sc = mySrvConfig(r->server); @@ -597,6 +655,8 @@ int ssl_hook_Access(request_rec *r) */ if (dc->bSSLRequired && ssl == NULL) { ap_log_reason("SSL connection required", r->filename, r); + /* remember forbidden access for strict require option */ + ap_table_setn(r->notes, "ssl-access-forbidden", (void *)1); return FORBIDDEN; } @@ -609,83 +669,154 @@ int ssl_hook_Access(request_rec *r) return DECLINED; /* - * Support for per-directory SSL connection parameters. - * + * Support for per-directory reconfigured SSL connection parameters. + * * This is implemented by forcing an SSL renegotiation with the * reconfigured parameter suite. But Apache's internal API processing - * makes our life very hard, because when internal sub-requests occur we - * nevertheless should avoid multiple unnecessary SSL handshakes (they - * need network I/O and time to perform). But the optimization for - * filtering out the unnecessary handshakes isn't such obvious. - * Especially because while Apache is in its sub-request processing the - * client could force additional handshakes, too. And these take place - * perhaps without our notice. So the only possibility is to ask - * SSLeay/OpenSSL whether the renegotiation has to be performed or not. It - * has to performed when some parameters which were previously known (by - * us) are not those we've now reconfigured (as known by SSLeay/OpenSSL). - */ - renegotiate = FALSE; + * makes our life very hard here, because when internal sub-requests occur + * we nevertheless should avoid multiple unnecessary SSL handshakes (they + * require extra network I/O and especially time to perform). + * + * But the optimization for filtering out the unnecessary handshakes isn't + * obvious and trivial. Especially because while Apache is in its + * sub-request processing the client could force additional handshakes, + * too. And these take place perhaps without our notice. So the only + * possibility is to explicitly _ask_ OpenSSL whether the renegotiation + * has to be performed or not. It has to performed when some parameters + * which were previously known (by us) are not those we've now + * reconfigured (as known by OpenSSL) or (in optimized way) at least when + * the reconfigured parameter suite is stronger (more restrictions) than + * the currently active one. + */ + renegotiate = FALSE; + renegotiate_quick = FALSE; #ifdef SSL_EXPERIMENTAL reconfigured_locations = FALSE; #endif - /* - * override of SSLCipherSuite + /* + * Override of SSLCipherSuite + * + * We provide two options here: + * + * o The paranoid and default approach where we force a renegotiation when + * the cipher suite changed in _any_ way (which is straight-forward but + * often forces renegotiations too often and is perhaps not what the + * user actually wanted). + * + * o The optimized and still secure way where we force a renegotiation + * only if the currently active cipher is no longer contained in the + * reconfigured/new cipher suite. Any other changes are not important + * because it's the servers choice to select a cipher from the ones the + * client supports. So as long as the current cipher is still in the new + * cipher suite we're happy. Because we can assume we would have + * selected it again even when other (better) ciphers exists now in the + * new cipher suite. This approach is fine because the user explicitly + * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no + * implicit optimizations. */ if (dc->szCipherSuite != NULL) { - /* remember old cipher suite for comparison */ - if ((skCipherOld = SSL_get_ciphers(ssl)) != NULL) - skCipherOld = sk_dup(skCipherOld); - /* configure new cipher suite */ + /* remember old state */ + pCipher = NULL; + skCipherOld = NULL; + if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) + pCipher = SSL_get_current_cipher(ssl); + else { + skCipherOld = SSL_get_ciphers(ssl); + if (skCipherOld != NULL) + skCipherOld = sk_SSL_CIPHER_dup(skCipherOld); + } + /* configure new state */ if (!SSL_set_cipher_list(ssl, dc->szCipherSuite)) { ssl_log(r->server, SSL_LOG_WARN|SSL_ADD_SSLERR, "Unable to reconfigure (per-directory) permitted SSL ciphers"); + if (skCipherOld != NULL) + sk_SSL_CIPHER_free(skCipherOld); return FORBIDDEN; } - /* determine whether the cipher suite was actually changed */ + /* determine whether a renegotiation has to be forced */ skCipher = SSL_get_ciphers(ssl); - if ((skCipherOld == NULL && skCipher != NULL) || - (skCipherOld != NULL && skCipher == NULL) ) - renegotiate = TRUE; - else if (skCipherOld != NULL && skCipher != NULL) { - for (n = 0; n < sk_num(skCipher); n++) { - if (sk_find(skCipherOld, sk_value(skCipher, n)) < 0) { - renegotiate = TRUE; - break; - } + if (dc->nOptions & SSL_OPT_OPTRENEGOTIATE) { + /* optimized way */ + if ((pCipher == NULL && skCipher != NULL) || + (pCipher != NULL && skCipher == NULL) ) + renegotiate = TRUE; + else if (pCipher != NULL && skCipher != NULL + && sk_SSL_CIPHER_find(skCipher, pCipher) < 0) { + renegotiate = TRUE; } - for (n = 0; n < sk_num(skCipherOld); n++) { - if (sk_find(skCipher, sk_value(skCipherOld, n)) < 0) { - renegotiate = TRUE; - break; + } + else { + /* paranoid way */ + if ((skCipherOld == NULL && skCipher != NULL) || + (skCipherOld != NULL && skCipher == NULL) ) + renegotiate = TRUE; + else if (skCipherOld != NULL && skCipher != NULL) { + for (n = 0; !renegotiate && n < sk_SSL_CIPHER_num(skCipher); n++) { + if (sk_SSL_CIPHER_find(skCipherOld, sk_SSL_CIPHER_value(skCipher, n)) < 0) + renegotiate = TRUE; + } + for (n = 0; !renegotiate && n < sk_SSL_CIPHER_num(skCipherOld); n++) { + if (sk_SSL_CIPHER_find(skCipher, sk_SSL_CIPHER_value(skCipherOld, n)) < 0) + renegotiate = TRUE; } } } - /* free old cipher suite */ + /* cleanup */ if (skCipherOld != NULL) - sk_free(skCipherOld); + sk_SSL_CIPHER_free(skCipherOld); + /* tracing */ + if (renegotiate) + ssl_log(r->server, SSL_LOG_TRACE, + "Reconfigured cipher suite will force renegotiation"); } /* - * override of SSLVerifyDepth: - * This is handled by us manually inside the verify callback - * function and not by SSLeay internally. And our function is - * aware of both the per-server and per-directory contexts. - * All we have to do is to force the renegotiation when the - * maximum allowed depth is changed. + * override of SSLVerifyDepth + * + * The depth checks are handled by us manually inside the verify callback + * function and not by OpenSSL internally (and our function is aware of + * both the per-server and per-directory contexts). So we cannot ask + * OpenSSL about the currently verify depth. Instead we remember it in our + * ap_ctx attached to the SSL* of OpenSSL. We've to force the + * renegotiation if the reconfigured/new verify depth is less than the + * currently active/remembered verify depth (because this means more + * restriction on the certificate chain). */ if (dc->nVerifyDepth != UNSET) { - if (dc->nVerifyDepth != sc->nVerifyDepth) + apctx = SSL_get_app_data2(ssl); + if ((vp = ap_ctx_get(apctx, "ssl::verify::depth")) != NULL) + n = AP_CTX_PTR2NUM(vp); + else + n = sc->nVerifyDepth; + ap_ctx_set(apctx, "ssl::verify::depth", + AP_CTX_NUM2PTR(dc->nVerifyDepth)); + /* determine whether a renegotiation has to be forced */ + if (dc->nVerifyDepth < n) { renegotiate = TRUE; + ssl_log(r->server, SSL_LOG_TRACE, + "Reduced client verification depth will force renegotiation"); + } } - /* + /* * override of SSLVerifyClient + * + * We force a renegotiation if the reconfigured/new verify type is + * stronger than the currently active verify type. + * + * The order is: none << optional_no_ca << optional << require + * + * Additionally the following optimization is possible here: When the + * currently active verify type is "none" but a client certificate is + * already known/present, it's enough to manually force a client + * verification but at least skip the I/O-intensive renegotation + * handshake. */ if (dc->nVerifyClient != SSL_CVERIFY_UNSET) { - /* remember old verify mode */ + /* remember old state */ nVerifyOld = SSL_get_verify_mode(ssl); - /* configure new verify mode */ + /* configure new state */ nVerify = SSL_VERIFY_NONE; if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) nVerify |= SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT; @@ -694,9 +825,25 @@ int ssl_hook_Access(request_rec *r) nVerify |= SSL_VERIFY_PEER; SSL_set_verify(ssl, nVerify, ssl_callback_SSLVerify); SSL_set_verify_result(ssl, X509_V_OK); - /* determine whether the verify mode was actually changed */ - if (nVerify != nVerifyOld) - renegotiate = TRUE; + /* determine whether we've to force a renegotiation */ + if (nVerify != nVerifyOld) { + if ( ( (nVerifyOld == SSL_VERIFY_NONE) + && (nVerify != SSL_VERIFY_NONE)) + || ( !(nVerifyOld & SSL_VERIFY_PEER) + && (nVerify & SSL_VERIFY_PEER)) + || ( !(nVerifyOld & (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) + && (nVerify & (SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT)))) { + renegotiate = TRUE; + /* optimization */ + if ( dc->nOptions & SSL_OPT_OPTRENEGOTIATE + && nVerifyOld == SSL_VERIFY_NONE + && SSL_get_peer_certificate(ssl) != NULL) + renegotiate_quick = TRUE; + ssl_log(r->server, SSL_LOG_TRACE, + "Changed client verification type will force %srenegotiation", + renegotiate_quick ? "quick " : ""); + } + } } /* @@ -710,13 +857,13 @@ int ssl_hook_Access(request_rec *r) * chance to provide this functionality... */ #ifdef SSL_EXPERIMENTAL - if ( ( dc->szCACertificateFile != NULL - && ( sc->szCACertificateFile == NULL - || ( sc->szCACertificateFile != NULL + if ( ( dc->szCACertificateFile != NULL + && ( sc->szCACertificateFile == NULL + || ( sc->szCACertificateFile != NULL && strNE(dc->szCACertificateFile, sc->szCACertificateFile)))) - || ( dc->szCACertificatePath != NULL - && ( sc->szCACertificatePath == NULL - || ( sc->szCACertificatePath != NULL + || ( dc->szCACertificatePath != NULL + && ( sc->szCACertificatePath == NULL + || ( sc->szCACertificatePath != NULL && strNE(dc->szCACertificatePath, sc->szCACertificatePath)))) ) { cpCAFile = dc->szCACertificateFile != NULL ? dc->szCACertificateFile : sc->szCACertificateFile; @@ -724,8 +871,8 @@ int ssl_hook_Access(request_rec *r) dc->szCACertificatePath : sc->szCACertificatePath; /* FIXME: This should be... - if (!SSL_load_verify_locations(ssl, cpCAFile, cpCAPath)) { - ...but SSLeay/OpenSSL still doesn't provide this! + if (!SSL_load_verify_locations(ssl, cpCAFile, cpCAPath)) { + ...but OpenSSL still doesn't provide this! */ if (!SSL_CTX_load_verify_locations(ctx, cpCAFile, cpCAPath)) { ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, @@ -733,7 +880,7 @@ int ssl_hook_Access(request_rec *r) "for client authentication"); return FORBIDDEN; } - if ((skCAList = ssl_init_FindCAList(r->server, r->pool, + if ((skCAList = ssl_init_FindCAList(r->server, r->pool, cpCAFile, cpCAPath)) == NULL) { ssl_log(r->server, SSL_LOG_ERROR, "Unable to determine list of available " @@ -743,17 +890,33 @@ int ssl_hook_Access(request_rec *r) SSL_set_client_CA_list(ssl, skCAList); renegotiate = TRUE; reconfigured_locations = TRUE; + ssl_log(r->server, SSL_LOG_TRACE, + "Changed client verification locations will force renegotiation"); } #endif /* SSL_EXPERIMENTAL */ +#ifndef SSL_EXPERIMENTAL /* + * SSL renegotiations in conjunction with HTTP + * requests using the POST method are not supported. + */ + if (renegotiate && r->method_number == M_POST) { + ssl_log(r->server, SSL_LOG_ERROR, + "SSL Re-negotiation in conjunction with POST method not supported!"); + ssl_log(r->server, SSL_LOG_INFO, + "There is only experimental support which has to be enabled first"); + return METHOD_NOT_ALLOWED; + } +#endif /* not SSL_EXPERIMENTAL */ + + /* * now do the renegotiation if anything was actually reconfigured */ if (renegotiate) { - /* + /* * Now we force the SSL renegotation by sending the Hello Request * message to the client. Here we have to do a workaround: Actually - * SSLeay returns immediately after sending the Hello Request (the + * OpenSSL returns immediately after sending the Hello Request (the * intent AFAIK is because the SSL/TLS protocol says it's not a must * that the client replies to a Hello Request). But because we insist * on a reply (anything else is an error for us) we have to go to the @@ -762,33 +925,83 @@ int ssl_hook_Access(request_rec *r) * state explicitly and continue the handshake manually. */ ssl_log(r->server, SSL_LOG_INFO, "Requesting connection re-negotiation"); - SSL_renegotiate(ssl); - SSL_do_handshake(ssl); - if (SSL_get_state(ssl) != SSL_ST_OK) { - ssl_log(r->server, SSL_LOG_ERROR, "Re-negotation request failed"); - return FORBIDDEN; + if (renegotiate_quick) { + /* perform just a manual re-verification of the peer */ + ssl_log(r->server, SSL_LOG_TRACE, + "Performing quick renegotiation: just re-verifying the peer"); + certstore = SSL_CTX_get_cert_store(ctx); + if (certstore == NULL) { + ssl_log(r->server, SSL_LOG_ERROR, "Cannot find certificate storage"); + return FORBIDDEN; + } + certstack = SSL_get_peer_cert_chain(ssl); + if (certstack == NULL || sk_X509_num(certstack) == 0) { + ssl_log(r->server, SSL_LOG_ERROR, "Cannot find peer certificate chain"); + return FORBIDDEN; + } + cert = sk_X509_value(certstack, 0); + X509_STORE_CTX_init(&certstorectx, certstore, cert, certstack); + depth = SSL_get_verify_depth(ssl); + if (depth >= 0) + X509_STORE_CTX_set_depth(&certstorectx, depth); + X509_STORE_CTX_set_ex_data(&certstorectx, + SSL_get_ex_data_X509_STORE_CTX_idx(), (char *)ssl); + if (!X509_verify_cert(&certstorectx)) + ssl_log(r->server, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Re-negotiation verification step failed"); + SSL_set_verify_result(ssl, certstorectx.error); + X509_STORE_CTX_cleanup(&certstorectx); } - ssl_log(r->server, SSL_LOG_INFO, "Awaiting re-negotiation handshake"); - SSL_set_state(ssl, SSL_ST_ACCEPT); - SSL_do_handshake(ssl); - if (SSL_get_state(ssl) != SSL_ST_OK) { - ssl_log(r->server, SSL_LOG_ERROR, - "Re-negotiation handshake failed: Not accepted by client!?"); - return FORBIDDEN; + else { + /* do a full renegotiation */ + ssl_log(r->server, SSL_LOG_TRACE, + "Performing full renegotiation: complete handshake protocol"); + if (r->main != NULL) + SSL_set_session_id_context(ssl, (unsigned char *)&(r->main), sizeof(r->main)); + else + SSL_set_session_id_context(ssl, (unsigned char *)&r, sizeof(r)); +#ifdef SSL_EXPERIMENTAL + ssl_io_suck(r, ssl); +#endif + SSL_renegotiate(ssl); + SSL_do_handshake(ssl); + if (SSL_get_state(ssl) != SSL_ST_OK) { + ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation request failed"); + return FORBIDDEN; + } + ssl_log(r->server, SSL_LOG_INFO, "Awaiting re-negotiation handshake"); + SSL_set_state(ssl, SSL_ST_ACCEPT); + SSL_do_handshake(ssl); + if (SSL_get_state(ssl) != SSL_ST_OK) { + ssl_log(r->server, SSL_LOG_ERROR, + "Re-negotiation handshake failed: Not accepted by client!?"); + return FORBIDDEN; + } + } + + /* + * Remember the peer certificate's DN + */ + if ((cert = SSL_get_peer_certificate(ssl)) != NULL) { + cp = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); + ap_ctx_set(r->connection->client->ctx, "ssl::client::dn", + ap_pstrdup(r->connection->pool, cp)); + free(cp); } /* * Finally check for acceptable renegotiation results */ if (dc->nVerifyClient != SSL_CVERIFY_NONE) { - if (SSL_get_verify_result(ssl) != X509_V_OK) { - ssl_log(r->server, SSL_LOG_ERROR, + if ( dc->nVerifyClient == SSL_CVERIFY_REQUIRE + && SSL_get_verify_result(ssl) != X509_V_OK ) { + ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation handshake failed: Client verification failed"); return FORBIDDEN; } - if ( dc->nVerifyClient == SSL_CVERIFY_REQUIRE + if ( dc->nVerifyClient == SSL_CVERIFY_REQUIRE && SSL_get_peer_certificate(ssl) == NULL ) { - ssl_log(r->server, SSL_LOG_ERROR, + ssl_log(r->server, SSL_LOG_ERROR, "Re-negotiation handshake failed: Client certificate missing"); return FORBIDDEN; } @@ -796,10 +1009,10 @@ int ssl_hook_Access(request_rec *r) } /* - * Under old SSLeay we had to change the X509_STORE inside the SSL_CTX - * instead inside the SSL structure, so we have to reconfigure it to the - * old values. This should be changed with forthcoming OpenSSL version - * when better functionality is avaiable. + * Under old OpenSSL we had to change the X509_STORE inside the + * SSL_CTX instead inside the SSL structure, so we have to reconfigure it + * to the old values. This should be changed with forthcoming OpenSSL + * versions when better functionality is avaiable. */ #ifdef SSL_EXPERIMENTAL if (renegotiate && reconfigured_locations) { @@ -817,7 +1030,7 @@ int ssl_hook_Access(request_rec *r) * Check SSLRequire boolean expressions */ apRequirement = dc->aRequirement; - pRequirements = (ssl_require_t *)apRequirement->elts; + pRequirements = (ssl_require_t *)apRequirement->elts; for (i = 0; i < apRequirement->nelts; i++) { pRequirement = &pRequirements[i]; ok = ssl_expr_exec(r, pRequirement->mpExpr); @@ -825,6 +1038,8 @@ int ssl_hook_Access(request_rec *r) cp = ap_psprintf(r->pool, "Failed to execute SSL requirement expression: %s", ssl_expr_get_error()); ap_log_reason(cp, r->filename, r); + /* remember forbidden access for strict require option */ + ap_table_setn(r->notes, "ssl-access-forbidden", (void *)1); return FORBIDDEN; } if (ok != 1) { @@ -835,14 +1050,97 @@ int ssl_hook_Access(request_rec *r) "Failed expression: %s", pRequirement->cpExpr); ap_log_reason("SSL requirement expression not fulfilled " "(see SSL logfile for more details)", r->filename, r); + /* remember forbidden access for strict require option */ + ap_table_setn(r->notes, "ssl-access-forbidden", (void *)1); return FORBIDDEN; } } /* * Else access is granted... + * (except vendor handlers override) */ - return OK; + rc = OK; +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::access_handler", + AP_HOOK_SIG2(int,ptr), AP_HOOK_DECLINE(DECLINED), + &rc, r); +#endif + return rc; +} + +/* + * Auth Handler: + * Fake a Basic authentication from the X509 client certificate. + * + * This must be run fairly early on to prevent a real authentication from + * occuring, in particular it must be run before anything else that + * authenticates a user. This means that the Module statement for this + * module should be LAST in the Configuration file. + */ +int ssl_hook_Auth(request_rec *r) +{ + SSLSrvConfigRec *sc = mySrvConfig(r->server); + SSLDirConfigRec *dc = myDirConfig(r); + char b1[MAX_STRING_LEN], b2[MAX_STRING_LEN]; + char *clientdn; + + /* + * Additionally forbid access (again) + * when strict require option is used. + */ + if ( (dc->nOptions & SSL_OPT_STRICTREQUIRE) + && (ap_table_get(r->notes, "ssl-access-forbidden") != NULL)) + return FORBIDDEN; + + /* + * We decline operation in various situations... + */ + if (!sc->bEnabled) + return DECLINED; + if (ap_ctx_get(r->connection->client->ctx, "ssl") == NULL) + return DECLINED; + if (!(dc->nOptions & SSL_OPT_FAKEBASICAUTH)) + return DECLINED; + if (r->connection->user) + return DECLINED; + if ((clientdn = (char *)ap_ctx_get(r->connection->client->ctx, "ssl::client::dn")) == NULL) + return DECLINED; + + /* + * Fake a password - which one would be immaterial, as, it seems, an empty + * password in the users file would match ALL incoming passwords, if only + * we were using the standard crypt library routine. Unfortunately, OpenSSL + * "fixes" a "bug" in crypt and thus prevents blank passwords from + * working. (IMHO what they really fix is a bug in the users of the code + * - failing to program correctly for shadow passwords). We need, + * therefore, to provide a password. This password can be matched by + * adding the string "xxj31ZMTZzkVA" as the password in the user file. + * This is just the crypted variant of the word "password" ;-) + */ + ap_snprintf(b1, sizeof(b1), "%s:password", clientdn); + ssl_util_uuencode(b2, b1, FALSE); + ap_snprintf(b1, sizeof(b1), "Basic %s", b2); + ap_table_set(r->headers_in, "Authorization", b1); + ssl_log(r->server, SSL_LOG_INFO, + "Faking HTTP Basic Auth header: \"Authorization: %s\"", b1); + + return DECLINED; +} + +int ssl_hook_UserCheck(request_rec *r) +{ + SSLDirConfigRec *dc = myDirConfig(r); + + /* + * Additionally forbid access (again) + * when strict require option is used. + */ + if ( (dc->nOptions & SSL_OPT_STRICTREQUIRE) + && (ap_table_get(r->notes, "ssl-access-forbidden") != NULL)) + return FORBIDDEN; + + return DECLINED; } /* @@ -901,6 +1199,7 @@ static const char *ssl_hook_Fixup_vars[] = { "SSL_SERVER_I_DN_Email", "SSL_SERVER_A_KEY", "SSL_SERVER_A_SIG", + "SSL_SESSION_ID", NULL }; @@ -955,22 +1254,95 @@ int ssl_hook_Fixup(request_rec *r) /* _________________________________________________________________ ** -** SSLeay Callback Functions +** OpenSSL Callback Functions ** _________________________________________________________________ */ /* - * Handle out the already generated RSA key... + * Handle out temporary RSA private keys on demand + * + * The background of this as the TLSv1 standard explains it: + * + * | D.1. Temporary RSA keys + * | + * | US Export restrictions limit RSA keys used for encryption to 512 + * | bits, but do not place any limit on lengths of RSA keys used for + * | signing operations. Certificates often need to be larger than 512 + * | bits, since 512-bit RSA keys are not secure enough for high-value + * | transactions or for applications requiring long-term security. Some + * | certificates are also designated signing-only, in which case they + * | cannot be used for key exchange. + * | + * | When the public key in the certificate cannot be used for encryption, + * | the server signs a temporary RSA key, which is then exchanged. In + * | exportable applications, the temporary RSA key should be the maximum + * | allowable length (i.e., 512 bits). Because 512-bit RSA keys are + * | relatively insecure, they should be changed often. For typical + * | electronic commerce applications, it is suggested that keys be + * | changed daily or every 500 transactions, and more often if possible. + * | Note that while it is acceptable to use the same temporary key for + * | multiple transactions, it must be signed each time it is used. + * | + * | RSA key generation is a time-consuming process. In many cases, a + * | low-priority process can be assigned the task of key generation. + * | Whenever a new key is completed, the existing temporary key can be + * | replaced with the new one. + * + * So we generated 512 and 1024 bit temporary keys on startup + * which we now just handle out on demand.... + * */ -RSA *ssl_callback_TmpRSA(SSL *pSSL, int nExport) +RSA *ssl_callback_TmpRSA(SSL *pSSL, int nExport, int nKeyLen) { SSLModConfigRec *mc = myModConfig(); + RSA *rsa; + + rsa = NULL; + if (nExport) { + /* It's because an export cipher is used */ + if (nKeyLen == 512) + rsa = mc->pRSATmpKey512; + else if (nKeyLen == 1024) + rsa = mc->pRSATmpKey1024; + else + /* it's too expensive to generate on-the-fly, so keep 1024bit */ + rsa = mc->pRSATmpKey1024; + } + else { + /* It's because a sign-only certificate situation exists */ + rsa = mc->pRSATmpKey1024; + } + return rsa; +} - return mc->pRSATmpKey; +/* + * Handle out the already generated DH parameters... + */ +DH *ssl_callback_TmpDH(SSL *pSSL, int nExport, int nKeyLen) +{ + SSLModConfigRec *mc = myModConfig(); + DH *dh; + + dh = NULL; + if (nExport) { + /* It's because an export cipher is used */ + if (nKeyLen == 512) + dh = mc->pDHTmpParam512; + else if (nKeyLen == 1024) + dh = mc->pDHTmpParam1024; + else + /* it's too expensive to generate on-the-fly, so keep 1024bit */ + dh = mc->pDHTmpParam1024; + } + else { + /* It's because a sign-only certificate situation exists */ + dh = mc->pDHTmpParam1024; + } + return dh; } /* - * This SSLeay callback function is called when SSLeay + * This OpenSSL callback function is called when OpenSSL * does client authentication and verifies the certificate chain. */ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) @@ -981,19 +1353,22 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) request_rec *r; SSLSrvConfigRec *sc; SSLDirConfigRec *dc; + ap_ctx *actx; X509 *xs; int errnum; int errdepth; char *cp; char *cp2; int depth; + int verify; /* - * Get Apache context back through SSLeay context + * Get Apache context back through OpenSSL context */ ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx); conn = (conn_rec *)SSL_get_app_data(ssl); - r = (request_rec *)SSL_get_app_data2(ssl); + actx = (ap_ctx *)SSL_get_app_data2(ssl); + r = (request_rec *)ap_ctx_get(actx, "ssl::request_rec"); s = conn->server; sc = mySrvConfig(s); dc = (r != NULL ? myDirConfig(r) : NULL); @@ -1022,11 +1397,15 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) /* * Check for optionally acceptable non-verifiable issuer situation */ + if (dc != NULL && dc->nVerifyClient != SSL_CVERIFY_UNSET) + verify = dc->nVerifyClient; + else + verify = sc->nVerifyClient; if ( ( errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN || errnum == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY || errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE ) - && sc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA ) { + && verify == SSL_CVERIFY_OPTIONAL_NO_CA ) { ssl_log(s, SSL_LOG_TRACE, "Certificate Verification: Verifiable Issuer is configured as " "optional, therefore we're accepting the certificate"); @@ -1034,6 +1413,14 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) } /* + * Additionally perform CRL-based revocation checks + */ + if (ok) { + ok = ssl_callback_SSLVerify_CRL(ok, ctx, s); + errnum = X509_STORE_CTX_get_error(ctx); + } + + /* * If we already know it's not ok, log the real reason */ if (!ok) { @@ -1041,7 +1428,7 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) errnum, X509_verify_cert_error_string(errnum)); ap_ctx_set(conn->client->ctx, "ssl::client::dn", NULL); ap_ctx_set(conn->client->ctx, "ssl::verify::error", - X509_verify_cert_error_string(errnum)); + (void *)X509_verify_cert_error_string(errnum)); } /* @@ -1049,27 +1436,191 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx) */ if (dc != NULL && dc->nVerifyDepth != UNSET) depth = dc->nVerifyDepth; - else + else depth = sc->nVerifyDepth; if (errdepth > depth) { ssl_log(s, SSL_LOG_ERROR, "Certificate Verification: Certificate Chain too long " - "(chain has %d certificates, but maximum allowed are only %d)", + "(chain has %d certificates, but maximum allowed are only %d)", errdepth, depth); ap_ctx_set(conn->client->ctx, "ssl::verify::error", - X509_verify_cert_error_string(X509_V_ERR_CERT_CHAIN_TOO_LONG)); + (void *)X509_verify_cert_error_string(X509_V_ERR_CERT_CHAIN_TOO_LONG)); ok = FALSE; } /* - * And finally signal SSLeay the (perhaps changed) state + * And finally signal OpenSSL the (perhaps changed) state */ return (ok); } +int ssl_callback_SSLVerify_CRL( + int ok, X509_STORE_CTX *ctx, server_rec *s) +{ + SSLSrvConfigRec *sc; + X509_OBJECT obj; + X509_NAME *subject; + X509_NAME *issuer; + X509 *xs; + X509_CRL *crl; + X509_REVOKED *revoked; + long serial; + BIO *bio; + int i, n, rc; + char *cp; + char *cp2; + + /* + * Unless a revocation store for CRLs was created we + * cannot do any CRL-based verification, of course. + */ + sc = mySrvConfig(s); + if (sc->pRevocationStore == NULL) + return ok; + + /* + * Determine certificate ingredients in advance + */ + xs = X509_STORE_CTX_get_current_cert(ctx); + subject = X509_get_subject_name(xs); + issuer = X509_get_issuer_name(xs); + + /* + * OpenSSL provides the general mechanism to deal with CRLs but does not + * use them automatically when verifying certificates, so we do it + * explicitly here. We will check the CRL for the currently checked + * certificate, if there is such a CRL in the store. + * + * We come through this procedure for each certificate in the certificate + * chain, starting with the root-CA's certificate. At each step we've to + * both verify the signature on the CRL (to make sure it's a valid CRL) + * and it's revocation list (to make sure the current certificate isn't + * revoked). But because to check the signature on the CRL we need the + * public key of the issuing CA certificate (which was already processed + * one round before), we've a little problem. But we can both solve it and + * at the same time optimize the processing by using the following + * verification scheme (idea and code snippets borrowed from the GLOBUS + * project): + * + * 1. We'll check the signature of a CRL in each step when we find a CRL + * through the _subject_ name of the current certificate. This CRL + * itself will be needed the first time in the next round, of course. + * But we do the signature processing one round before this where the + * public key of the CA is available. + * + * 2. We'll check the revocation list of a CRL in each step when + * we find a CRL through the _issuer_ name of the current certificate. + * This CRLs signature was then already verified one round before. + * + * This verification scheme allows a CA to revoke its own certificate as + * well, of course. + */ + + /* + * Try to retrieve a CRL corresponding to the _subject_ of + * the current certificate in order to verify it's integrity. + */ + memset((char *)&obj, 0, sizeof(obj)); + rc = SSL_X509_STORE_lookup(sc->pRevocationStore, X509_LU_CRL, subject, &obj); + crl = obj.data.crl; + if (rc > 0 && crl != NULL) { + /* + * Log information about CRL + * (A little bit complicated because of ASN.1 and BIOs...) + */ + if (ssl_log_applies(s, SSL_LOG_TRACE)) { + bio = BIO_new(BIO_s_mem()); + BIO_printf(bio, "lastUpdate: "); + ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl)); + BIO_printf(bio, ", nextUpdate: "); + ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl)); + n = BIO_pending(bio); + cp = malloc(n+1); + n = BIO_read(bio, cp, n); + cp[n] = NUL; + BIO_free(bio); + cp2 = X509_NAME_oneline(subject, NULL, 0); + ssl_log(s, SSL_LOG_TRACE, "CA CRL: Issuer: %s, %s", cp2, cp); + free(cp2); + free(cp); + } + + /* + * Verify the signature on this CRL + */ + if (X509_CRL_verify(crl, X509_get_pubkey(xs)) <= 0) { + ssl_log(s, SSL_LOG_WARN, "Invalid signature on CRL"); + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); + X509_OBJECT_free_contents(&obj); + return FALSE; + } + + /* + * Check date of CRL to make sure it's not expired + */ + i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); + if (i == 0) { + ssl_log(s, SSL_LOG_WARN, "Found CRL has invalid nextUpdate field"); + X509_STORE_CTX_set_error(ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); + X509_OBJECT_free_contents(&obj); + return FALSE; + } + if (i < 0) { + ssl_log(s, SSL_LOG_WARN, + "Found CRL is expired - " + "revoking all certificates until you get updated CRL"); + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); + X509_OBJECT_free_contents(&obj); + return FALSE; + } + X509_OBJECT_free_contents(&obj); + } + + /* + * Try to retrieve a CRL corresponding to the _issuer_ of + * the current certificate in order to check for revocation. + */ + memset((char *)&obj, 0, sizeof(obj)); + rc = SSL_X509_STORE_lookup(sc->pRevocationStore, X509_LU_CRL, issuer, &obj); + crl = obj.data.crl; + if (rc > 0 && crl != NULL) { + /* + * Check if the current certificate is revoked by this CRL + */ +#if SSL_LIBRARY_VERSION < 0x00904000 + n = sk_num(X509_CRL_get_REVOKED(crl)); +#else + n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); +#endif + for (i = 0; i < n; i++) { +#if SSL_LIBRARY_VERSION < 0x00904000 + revoked = (X509_REVOKED *)sk_value(X509_CRL_get_REVOKED(crl), i); +#else + revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); +#endif + if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(xs)) == 0) { + + serial = ASN1_INTEGER_get(revoked->serialNumber); + cp = X509_NAME_oneline(issuer, NULL, 0); + ssl_log(s, SSL_LOG_INFO, + "Certificate with serial %ld (0x%lX) " + "revoked per CRL from issuer %s", + serial, serial, cp); + free(cp); + + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); + X509_OBJECT_free_contents(&obj); + return FALSE; + } + } + X509_OBJECT_free_contents(&obj); + } + return ok; +} + /* - * This callback function is executed by SSLeay whenever a new SSL_SESSION is - * added to the internal SSLeay session cache. We use this hook to spread the + * This callback function is executed by OpenSSL whenever a new SSL_SESSION is + * added to the internal OpenSSL session cache. We use this hook to spread the * SSL_SESSION also to the inter-process disk-cache to make share it with our * other Apache pre-forked server processes. */ @@ -1079,16 +1630,17 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew) server_rec *s; SSLSrvConfigRec *sc; long t; + BOOL rc; /* - * Get Apache context back through SSLeay context + * Get Apache context back through OpenSSL context */ conn = (conn_rec *)SSL_get_app_data(ssl); s = conn->server; sc = mySrvConfig(s); /* - * Set the timeout also for the internal SSLeay cache, because this way + * Set the timeout also for the internal OpenSSL cache, because this way * our inter-process cache is consulted only when it's really necessary. */ t = (SSL_get_time(pNew) + sc->nSessionCacheTimeout); @@ -1098,26 +1650,27 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *pNew) * Store the SSL_SESSION in the inter-process cache with the * same expire time, so it expires automatically there, too. */ - ssl_scache_store(s, pNew, t); + rc = ssl_scache_store(s, pNew, t); /* * Log this cache operation */ ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache: " - "request=SET id=%s timeout=%ds (session caching)", + "request=SET status=%s id=%s timeout=%ds (session caching)", + rc == TRUE ? "OK" : "BAD", ssl_scache_id2sz(pNew->session_id, pNew->session_id_length), t-time(NULL)); /* - * return 0 which means to SSLeay that the pNew is still + * return 0 which means to OpenSSL that the pNew is still * valid and was not freed by us with SSL_SESSION_free(). */ return 0; } /* - * This callback function is executed by SSLeay whenever a - * SSL_SESSION is looked up in the internal SSLeay cache and it + * This callback function is executed by OpenSSL whenever a + * SSL_SESSION is looked up in the internal OpenSSL cache and it * was not found. We use this to lookup the SSL_SESSION in the * inter-process disk-cache where it was perhaps stored by one * of our other Apache pre-forked server processes. @@ -1130,7 +1683,7 @@ SSL_SESSION *ssl_callback_GetSessionCacheEntry( SSL_SESSION *pSession; /* - * Get Apache context back through SSLeay context + * Get Apache context back through OpenSSL context */ conn = (conn_rec *)SSL_get_app_data(ssl); s = conn->server; @@ -1163,8 +1716,8 @@ SSL_SESSION *ssl_callback_GetSessionCacheEntry( } /* - * This callback function is executed by SSLeay whenever a - * SSL_SESSION is removed from the the internal SSLeay cache. + * This callback function is executed by OpenSSL whenever a + * SSL_SESSION is removed from the the internal OpenSSL cache. * We use this to remove the SSL_SESSION in the inter-process * disk-cache, too. */ @@ -1174,9 +1727,11 @@ void ssl_callback_DelSessionCacheEntry( server_rec *s; /* - * Get Apache context back through SSLeay context + * Get Apache context back through OpenSSL context */ s = (server_rec *)SSL_CTX_get_app_data(ctx); + if (s == NULL) /* on server shutdown Apache is already gone */ + return; /* * Remove the SSL_SESSION from the inter-process cache @@ -1195,9 +1750,9 @@ void ssl_callback_DelSessionCacheEntry( } /* - * This callback function is executed while SSLeay processes the + * This callback function is executed while OpenSSL processes the * SSL handshake and does SSL record layer stuff. We use it to - * trace SSLeay's processing in out SSL logfile. + * trace OpenSSL's processing in out SSL logfile. */ void ssl_callback_LogTracingState(SSL *ssl, int where, int rc) { @@ -1224,26 +1779,27 @@ void ssl_callback_LogTracingState(SSL *ssl, int where, int rc) else if (where & SSL_CB_HANDSHAKE_DONE) ssl_log(s, SSL_LOG_TRACE, "%s: Handshake: done", SSL_LIBRARY_NAME); else if (where & SSL_CB_LOOP) - ssl_log(s, SSL_LOG_TRACE, "%s: Loop: %s", + ssl_log(s, SSL_LOG_TRACE, "%s: Loop: %s", SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); else if (where & SSL_CB_READ) ssl_log(s, SSL_LOG_TRACE, "%s: Read: %s", SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); else if (where & SSL_CB_WRITE) - ssl_log(s, SSL_LOG_TRACE, "%s: Write: %s", + ssl_log(s, SSL_LOG_TRACE, "%s: Write: %s", SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); else if (where & SSL_CB_ALERT) { str = (where & SSL_CB_READ) ? "read" : "write"; - ssl_log(s, SSL_LOG_TRACE, "%s: Alert: %s:%s\n", SSL_LIBRARY_NAME, + ssl_log(s, SSL_LOG_TRACE, "%s: Alert: %s:%s:%s\n", + SSL_LIBRARY_NAME, str, SSL_alert_type_string_long(rc), SSL_alert_desc_string_long(rc)); } else if (where & SSL_CB_EXIT) { if (rc == 0) - ssl_log(s, SSL_LOG_TRACE, "%s: Exit: failed in %s", + ssl_log(s, SSL_LOG_TRACE, "%s: Exit: failed in %s", SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); else if (rc < 0) - ssl_log(s, SSL_LOG_TRACE, "%s: Exit: error in %s", + ssl_log(s, SSL_LOG_TRACE, "%s: Exit: error in %s", SSL_LIBRARY_NAME, SSL_state_string_long(ssl)); } } diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c index b020fd6f865..7b57f399056 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_log.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_log.c ** Logging Facility @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -74,13 +74,27 @@ /* * Open the SSL logfile */ -void ssl_log_open(server_rec *s, pool *p) +void ssl_log_open(server_rec *s_main, server_rec *s, pool *p) { char *szLogFile; + SSLSrvConfigRec *sc_main = mySrvConfig(s_main); SSLSrvConfigRec *sc = mySrvConfig(s); piped_log *pl; - if (sc->szLogFile != NULL) { + /* + * Short-circuit for inherited logfiles in order to save + * filedescriptors in mass-vhost situation. Be careful, this works + * fine because the close happens implicitly by the pool facility. + */ + if ( s != s_main + && sc_main->fileLogFile != NULL + && ( (sc->szLogFile == NULL) + || ( sc->szLogFile != NULL + && sc_main->szLogFile != NULL + && strEQ(sc->szLogFile, sc_main->szLogFile)))) { + sc->fileLogFile = sc_main->fileLogFile; + } + else if (sc->szLogFile != NULL) { if (strEQ(sc->szLogFile, "/dev/null")) return; else if (sc->szLogFile[0] == '|') { @@ -128,6 +142,7 @@ static struct { { "*SSL3_READ_BYTES:sslv3*alert*bad*certificate*", "Subject CN in certificate not server name!?" }, { "*self signed certificate in certificate chain*", "Client certificate signed by CA not known to server?" }, { "*peer did not return a certificate*", "No CAs known to server for verification?" }, + { "*no shared cipher*", "Too restrictive SSLCipherSuite or using DSA server certificate?" }, { NULL, NULL } }; @@ -146,6 +161,20 @@ static char *ssl_log_annotation(char *error) return errstr; } +BOOL ssl_log_applies(server_rec *s, int level) +{ + SSLSrvConfigRec *sc; + + sc = mySrvConfig(s); + if ( sc->fileLogFile == NULL + && !(level & SSL_LOG_ERROR)) + return FALSE; + if ( level > sc->nLogLevel + && !(level & SSL_LOG_ERROR)) + return FALSE; + return TRUE; +} + void ssl_log(server_rec *s, int level, const char *msg, ...) { char tstr[80]; diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c index 8d5a14132cc..266c797649b 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_mutex.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_mutex.c ** Semaphore for Mutual Exclusion @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -75,18 +75,14 @@ void ssl_mutex_init(server_rec *s, pool *p) { SSLModConfigRec *mc = myModConfig(); - if (mc->nMutexMode == SSL_MUTEXMODE_FILE) { + if (mc->nMutexMode == SSL_MUTEXMODE_FILE) ssl_mutex_file_create(s, p); - ap_register_cleanup(p, (void *)s, ssl_mutex_file_remove, ap_null_cleanup); - } - else if (mc->nMutexMode == SSL_MUTEXMODE_SEM) { + else if (mc->nMutexMode == SSL_MUTEXMODE_SEM) ssl_mutex_sem_create(s, p); - ap_register_cleanup(p, (void *)s, ssl_mutex_sem_remove, ap_null_cleanup); - } return; } -void ssl_mutex_open(server_rec *s, pool *p) +void ssl_mutex_reinit(server_rec *s, pool *p) { SSLModConfigRec *mc = myModConfig(); @@ -97,25 +93,42 @@ void ssl_mutex_open(server_rec *s, pool *p) return; } -void ssl_mutex_on(void) +void ssl_mutex_on(server_rec *s) { SSLModConfigRec *mc = myModConfig(); + BOOL ok = TRUE; if (mc->nMutexMode == SSL_MUTEXMODE_FILE) - ssl_mutex_file_acquire(); + ok = ssl_mutex_file_acquire(); else if (mc->nMutexMode == SSL_MUTEXMODE_SEM) - ssl_mutex_sem_acquire(); + ok = ssl_mutex_sem_acquire(); + if (!ok) + ssl_log(s, SSL_LOG_WARN, "Failed to acquire global mutex lock"); return; } -void ssl_mutex_off(void) +void ssl_mutex_off(server_rec *s) { SSLModConfigRec *mc = myModConfig(); + BOOL ok = TRUE; if (mc->nMutexMode == SSL_MUTEXMODE_FILE) - ssl_mutex_file_release(); + ok = ssl_mutex_file_release(); else if (mc->nMutexMode == SSL_MUTEXMODE_SEM) - ssl_mutex_sem_release(); + ok = ssl_mutex_sem_release(); + if (!ok) + ssl_log(s, SSL_LOG_WARN, "Failed to release global mutex lock"); + return; +} + +void ssl_mutex_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(); + + if (mc->nMutexMode == SSL_MUTEXMODE_FILE) + ssl_mutex_file_remove(s); + else if (mc->nMutexMode == SSL_MUTEXMODE_SEM) + ssl_mutex_sem_remove(s); return; } @@ -140,9 +153,20 @@ void ssl_mutex_file_create(server_rec *s, pool *p) mc->szMutexFile); ssl_die(); } + ap_pclosef(p, mc->nMutexFD); + /* make sure the childs have access to this file */ if (geteuid() == 0 /* is superuser */) chown(mc->szMutexFile, ap_user_id, -1 /* no gid change */); + + /* open the lockfile for real */ + if ((mc->nMutexFD = ap_popenf(p, mc->szMutexFile, + O_WRONLY, SSL_MUTEX_LOCK_MODE)) < 0) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, + "Parent could not open SSLMutex lockfile %s", + mc->szMutexFile); + ssl_die(); + } #endif return; } @@ -154,7 +178,7 @@ void ssl_mutex_file_open(server_rec *s, pool *p) /* open the lockfile (once per child) to get a unique fd */ if ((mc->nMutexFD = ap_popenf(p, mc->szMutexFile, - O_WRONLY, SSL_MUTEX_LOCK_MODE)) < 0) { + O_WRONLY, SSL_MUTEX_LOCK_MODE)) < 0) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, "Child could not open SSLMutex lockfile %s", mc->szMutexFile); @@ -312,7 +336,7 @@ BOOL ssl_mutex_sem_acquire(void) rc = semop(mc->nMutexSEMID, sb, 2); #endif #ifdef SSL_HAVE_W32SEM - rc = ap_acquire_mutex((mutex *)mc->nMutexSEMID); + rc = (ap_acquire_mutex((mutex *)mc->nMutexSEMID) == 0); #endif #endif return rc; @@ -326,7 +350,7 @@ BOOL ssl_mutex_sem_release(void) #ifdef SSL_HAVE_IPCSEM struct sembuf sb[] = { - { 0, -1, SEM_UNDO } /* derements semaphore */ + { 0, -1, SEM_UNDO } /* decrements semaphore */ }; rc = semop(mc->nMutexSEMID, sb, 1); diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c index f4caa4ad64d..11261aee565 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_pphrase.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_pphrase.c ** Pass Phrase Dialog @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -83,9 +83,9 @@ void ssl_pphrase_Handle(server_rec *s, pool *p) server_rec *pServ; char *cpVHostID; char szPath[MAX_STRING_LEN]; + EVP_PKEY *pPrivateKey; ssl_asn1_t *asn1; unsigned char *ucp; - RSA *pRSAKey; X509 *pX509Cert; FILE *fp; BOOL bReadable; @@ -98,6 +98,10 @@ void ssl_pphrase_Handle(server_rec *s, pool *p) int nPassPhraseDialogCur; BOOL bPassPhraseDialogOnce; char **cpp; + int i, j; + ssl_algo_t algoCert, algoKey, at; + char *an; + char *cp; /* * Start with a fresh pass phrase array @@ -116,196 +120,245 @@ void ssl_pphrase_Handle(server_rec *s, pool *p) continue; cpVHostID = ssl_util_vhostid(p, pServ); - ssl_log(pServ, SSL_LOG_INFO, - "Init: Loading certificate & private key of SSL-aware server %s", + ssl_log(pServ, SSL_LOG_INFO, + "Init: Loading certificate & private key of SSL-aware server %s", cpVHostID); /* - * Read in server certificate: This is the easy part + * Read in server certificate(s): This is the easy part * because this file isn't encrypted in any way. */ - if (sc->szCertificateFile == NULL) { + if (sc->szPublicCertFile[0] == NULL) { ssl_log(pServ, SSL_LOG_ERROR, "Init: Server %s should be SSL-aware but has no certificate configured " "[Hint: SSLCertifcateFile]", cpVHostID); ssl_die(); } - ap_cpystrn(szPath, sc->szCertificateFile, sizeof(szPath)); - if ((fp = ap_pfopen(p, szPath, "r")) == NULL) { - ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, - "Init: Can't open server certificate file %s", szPath); - ssl_die(); - } - pX509Cert = X509_new(); - if (!PEM_read_X509(fp, &pX509Cert, NULL)) { - ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, - "Init: Unable to read server certificate from file %s", szPath); - ssl_die(); - } - ap_pfclose(p, fp); + algoCert = SSL_ALGO_UNKNOWN; + algoKey = SSL_ALGO_UNKNOWN; + for (i = 0, j = 0; i < SSL_AIDX_MAX && sc->szPublicCertFile[i] != NULL; i++) { - /* - * Insert the certificate into global module configuration to let it - * survive the processing between the 1st Apache API init round (where - * we operate here) and the 2nd Apache init round (where the - * certificate is actually used to configure mod_ssl's per-server - * configuration structures). - */ - asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tPublicCert, cpVHostID); - asn1->nData = i2d_X509(pX509Cert, NULL); - asn1->cpData = ap_palloc(mc->pPool, asn1->nData); - ucp = asn1->cpData; i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */ + ap_cpystrn(szPath, sc->szPublicCertFile[i], sizeof(szPath)); + if ((fp = ap_pfopen(p, szPath, "r")) == NULL) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, + "Init: Can't open server certificate file %s", szPath); + ssl_die(); + } + if ((pX509Cert = SSL_read_X509(fp, NULL, NULL)) == NULL) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: Unable to read server certificate from file %s", szPath); + ssl_die(); + } + ap_pfclose(p, fp); - /* - * Free the X509 structure - */ - X509_free(pX509Cert); + /* + * check algorithm type of certificate and make + * sure only one certificate per type is used. + */ + at = ssl_util_algotypeof(pX509Cert, NULL); + an = ssl_util_algotypestr(at); + if (algoCert & at) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: Multiple %s server certificates not allowed", an); + ssl_die(); + } + algoCert |= at; - /* - * Read in the private key: This is the non-trivial part, because the - * key is typically encrypted, so a pass phrase dialog has to be used - * to request it from the user (or it has to be alternatively gathered - * from a dialog program). The important point here is that ISPs - * usually have hundrets of virtual servers configured and a lot of - * them use SSL, so really we have to minimize the pass phrase - * dialogs. - * - * The idea is this: When N virtual hosts are configured and all of - * them use encrypted private keys with different pass phrases, we - * have no chance and have to pop up N pass phrase dialogs. But - * usually the admin is clever enough and uses the same pass phrase - * for more private key files (typically he even uses one single pass - * phrase for all). When this is the case we can minimize the dialogs - * by trying to re-use already known/entered pass phrases. - */ - if (sc->szKeyFile) - ap_cpystrn(szPath, sc->szKeyFile, sizeof(szPath)); + /* + * Insert the certificate into global module configuration to let it + * survive the processing between the 1st Apache API init round (where + * we operate here) and the 2nd Apache init round (where the + * certificate is actually used to configure mod_ssl's per-server + * configuration structures). + */ + cp = ap_psprintf(mc->pPool, "%s:%s", cpVHostID, an); + asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tPublicCert, cp); + asn1->nData = i2d_X509(pX509Cert, NULL); + asn1->cpData = ap_palloc(mc->pPool, asn1->nData); + ucp = asn1->cpData; i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */ - /* - * Spread context variables for callback function - */ - myCtxVarSet(mc, 1, pServ); - myCtxVarSet(mc, 2, p); - myCtxVarSet(mc, 3, aPassPhrase); - myCtxVarSet(mc, 4, &nPassPhraseCur); - myCtxVarSet(mc, 5, &cpPassPhraseCur); - myCtxVarSet(mc, 6, cpVHostID); - myCtxVarSet(mc, 7, &nPassPhraseDialog); - myCtxVarSet(mc, 8, &nPassPhraseDialogCur); - myCtxVarSet(mc, 9, &bPassPhraseDialogOnce); - - pRSAKey = RSA_new(); - nPassPhraseCur = 0; - nPassPhraseRetry = 0; - nPassPhraseDialogCur = 0; - bPassPhraseDialogOnce = TRUE; + /* + * Free the X509 structure + */ + X509_free(pX509Cert); + + /* + * Read in the private key: This is the non-trivial part, because the + * key is typically encrypted, so a pass phrase dialog has to be used + * to request it from the user (or it has to be alternatively gathered + * from a dialog program). The important point here is that ISPs + * usually have hundrets of virtual servers configured and a lot of + * them use SSL, so really we have to minimize the pass phrase + * dialogs. + * + * The idea is this: When N virtual hosts are configured and all of + * them use encrypted private keys with different pass phrases, we + * have no chance and have to pop up N pass phrase dialogs. But + * usually the admin is clever enough and uses the same pass phrase + * for more private key files (typically he even uses one single pass + * phrase for all). When this is the case we can minimize the dialogs + * by trying to re-use already known/entered pass phrases. + */ + if (sc->szPrivateKeyFile[j] != NULL) + ap_cpystrn(szPath, sc->szPrivateKeyFile[j++], sizeof(szPath)); - for (;;) { /* * Try to read the private key file with the help of * the callback function which serves the pass - * phrases to SSLeay + * phrases to OpenSSL */ - if ((fp = ap_pfopen(p, szPath, "r")) == NULL) { - ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, - "Init: Can't open server private key file %s", szPath); + myCtxVarSet(mc, 1, pServ); + myCtxVarSet(mc, 2, p); + myCtxVarSet(mc, 3, aPassPhrase); + myCtxVarSet(mc, 4, &nPassPhraseCur); + myCtxVarSet(mc, 5, &cpPassPhraseCur); + myCtxVarSet(mc, 6, cpVHostID); + myCtxVarSet(mc, 7, &nPassPhraseDialog); + myCtxVarSet(mc, 8, &nPassPhraseDialogCur); + myCtxVarSet(mc, 9, &bPassPhraseDialogOnce); + + nPassPhraseCur = 0; + nPassPhraseRetry = 0; + nPassPhraseDialogCur = 0; + bPassPhraseDialogOnce = TRUE; + + pPrivateKey = NULL; + + for (;;) { + /* + * Try to read the private key file with the help of + * the callback function which serves the pass + * phrases to OpenSSL + */ + if ((fp = ap_pfopen(p, szPath, "r")) == NULL) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, + "Init: Can't open server private key file %s", szPath); + ssl_die(); + } + cpPassPhraseCur = NULL; + bReadable = ((pPrivateKey = SSL_read_PrivateKey(fp, NULL, + ssl_pphrase_Handle_CB)) != NULL ? TRUE : FALSE); + ap_pfclose(p, fp); + + /* + * when the private key file now was readable, + * it's fine and we go out of the loop + */ + if (bReadable) + break; + + /* + * when we have more remembered pass phrases + * try to reuse these first. + */ + if (nPassPhraseCur < nPassPhrase) { + nPassPhraseCur++; + continue; + } + + /* + * else it's not readable and we have no more + * remembered pass phrases. Then this has to mean + * that the callback function popped up the dialog + * but a wrong pass phrase was entered. We give the + * user (but not the dialog program) a few more + * chances... + */ + if ( sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN + && cpPassPhraseCur != NULL + && nPassPhraseRetry < BUILTIN_DIALOG_RETRIES ) { + fprintf(stdout, "Apache:mod_ssl:Error: Pass phrase incorrect " + "(%d more retr%s permitted).\n", + (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry), + (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry) == 1 ? "y" : "ies"); + nPassPhraseRetry++; + if (nPassPhraseRetry > BUILTIN_DIALOG_BACKOFF) + sleep((nPassPhraseRetry-BUILTIN_DIALOG_BACKOFF)*5); + continue; + } + + /* + * Ok, anything else now means a fatal error. + */ + if (cpPassPhraseCur == NULL) + ssl_log(pServ, SSL_LOG_ERROR|SSL_ADD_SSLERR, "Init: Private key not found."); + if (sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN) { + fprintf(stdout, "Apache:mod_ssl:Error: Private key not found.\n"); + fprintf(stdout, "**Stopped\n"); + } + else { + ssl_log(pServ, SSL_LOG_ERROR|SSL_ADD_SSLERR, "Init: Pass phrase incorrect."); + if (sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN) { + fprintf(stdout, "Apache:mod_ssl:Error: Pass phrase incorrect.\n"); + fprintf(stdout, "**Stopped\n"); + } + } ssl_die(); } - cpPassPhraseCur = NULL; - bReadable = (PEM_read_RSAPrivateKey(fp, &pRSAKey, - ssl_pphrase_Handle_CB) ? TRUE : FALSE); - ap_pfclose(p, fp); - /* - * when the private key file now was readable, - * it's fine and we go out of the loop - */ - if (bReadable) - break; + if (pPrivateKey == NULL) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: Unable to read server private key from file %s", szPath); + ssl_die(); + } /* - * when we have more remembered pass phrases - * try to reuse these first. + * check algorithm type of private key and make + * sure only one private key per type is used. */ - if (nPassPhraseCur < nPassPhrase) { - nPassPhraseCur++; - continue; + at = ssl_util_algotypeof(NULL, pPrivateKey); + an = ssl_util_algotypestr(at); + if (algoKey & at) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR, + "Init: Multiple %s server private keys not allowed", an); + ssl_die(); } + algoKey |= at; /* - * else it's not readable and we have no more - * remembered pass phrases. Then this has to mean - * that the callback function popped up the dialog - * but a wrong pass phrase was entered. We give the - * user (but not the dialog program) a few more - * chances... + * Log the type of reading */ - if ( sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN - && cpPassPhraseCur != NULL - && nPassPhraseRetry < BUILTIN_DIALOG_RETRIES ) { - fprintf(stdout, "Apache:mod_ssl:Error: Pass phrase incorrect " - "(%d more retr%s permitted).\n", - (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry), - (BUILTIN_DIALOG_RETRIES-nPassPhraseRetry) == 1 ? "y" : "ies"); - nPassPhraseRetry++; - if (nPassPhraseRetry > BUILTIN_DIALOG_BACKOFF) - sleep((nPassPhraseRetry-BUILTIN_DIALOG_BACKOFF)*5); - continue; + if (nPassPhraseDialogCur == 0) + ssl_log(pServ, SSL_LOG_TRACE, + "Init: (%s) unencrypted %s private key - pass phrase not required", + cpVHostID, an); + else { + if (cpPassPhraseCur != NULL) + ssl_log(pServ, SSL_LOG_TRACE, + "Init: (%s) encrypted %s private key - pass phrase requested", + cpVHostID, an); + else + ssl_log(pServ, SSL_LOG_TRACE, + "Init: (%s) encrypted %s private key - pass phrase reused", + cpVHostID, an); } /* - * Ok, anything else now means a fatal error. + * Ok, when we have one more pass phrase store it */ - if (sc->nPassPhraseDialogType == SSL_PPTYPE_BUILTIN) { - fprintf(stdout, "Apache:mod_ssl:Error: Pass phrase incorrect.\n"); - fprintf(stdout, "**Stopped\n"); + if (cpPassPhraseCur != NULL) { + cpp = (char **)ssl_ds_array_push(aPassPhrase); + *cpp = cpPassPhraseCur; + nPassPhrase++; } - ssl_log(pServ, SSL_LOG_ERROR, "Init: Pass phrase incorrect."); - ssl_die(); - } - /* - * Log the type of reading - */ - if (nPassPhraseDialogCur == 0) - ssl_log(pServ, SSL_LOG_TRACE, - "Init: (%s) unencrypted private key - pass phrase not required", - cpVHostID); - else { - if (cpPassPhraseCur != NULL) - ssl_log(pServ, SSL_LOG_TRACE, - "Init: (%s) encrypted private key - pass phrase requested", - cpVHostID); - else - ssl_log(pServ, SSL_LOG_TRACE, - "Init: (%s) encrypted private key - pass phrase reused", - cpVHostID); - } + /* + * Insert private key into the global module configuration + * (we convert it to a stand-alone DER byte sequence + * because the SSL library uses static variables inside a + * RSA structure which do not survive DSO reloads!) + */ + cp = ap_psprintf(mc->pPool, "%s:%s", cpVHostID, an); + asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tPrivateKey, cp); + asn1->nData = i2d_PrivateKey(pPrivateKey, NULL); + asn1->cpData = ap_palloc(mc->pPool, asn1->nData); + ucp = asn1->cpData; i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */ - /* - * Ok, when have one more pass phrase store it - */ - if (cpPassPhraseCur != NULL) { - cpp = (char **)ssl_ds_array_push(aPassPhrase); - *cpp = cpPassPhraseCur; - nPassPhrase++; + /* + * Free the private key structure + */ + EVP_PKEY_free(pPrivateKey); } - - /* - * Insert private key into the global module configuration - * (we convert it to a stand-alone DER byte sequence - * because the SSL library uses static variables inside a - * RSA structure which do not survive DSO reloads!) - */ - asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tPrivateKey, cpVHostID); - asn1->nData = i2d_RSAPrivateKey(pRSAKey, NULL); - asn1->cpData = ap_palloc(mc->pPool, asn1->nData); - ucp = asn1->cpData; i2d_RSAPrivateKey(pRSAKey, &ucp); /* 2nd arg increments */ - - /* - * Free the RSA structure - */ - RSA_free(pRSAKey); } /* @@ -332,7 +385,7 @@ void ssl_pphrase_Handle(server_rec *s, pool *p) return; } -int ssl_pphrase_Handle_CB(char *buf, int bufsize, int w) +int ssl_pphrase_Handle_CB(char *buf, int bufsize, int ask_twice) { SSLModConfigRec *mc = myModConfig(); server_rec *s; @@ -411,19 +464,19 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int w) } /* - * Emulate the SSLeay internal pass phrase dialog + * Emulate the OpenSSL internal pass phrase dialog * (see crypto/pem/pem_lib.c:def_callback() for details) */ prompt = "Enter pass phrase:"; for (;;) { - if ((i = EVP_read_pw_string(buf, bufsize, prompt, w)) != 0) { + if ((i = EVP_read_pw_string(buf, bufsize, prompt, ask_twice)) != 0) { PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); memset(buf, 0, (unsigned int)bufsize); return (-1); } len = strlen(buf); - if (len < 4) - fprintf(stderr, "Apache:mod_ssl:Error: Pass phrase too short (needs to be at least 4 chars).\n"); + if (len < 1) + fprintf(stderr, "Apache:mod_ssl:Error: Pass phrase empty (needs to be at least 1 character).\n"); else break; } @@ -457,7 +510,7 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int w) *cppPassPhraseCur = ap_pstrdup(p, buf); /* - * And return it's length to SSLeay... + * And return it's length to OpenSSL... */ return (len); } diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c index fe150c8fb45..4ae847f8865 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_rand.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_rand.c ** Random Number Generator Seeding @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -58,7 +58,7 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */ - /* ``The generation of random + /* ``The generation of random numbers is too important to be left to chance.'' */ @@ -108,13 +108,14 @@ int ssl_rand_seed(server_rec *s, pool *p, ssl_rsctx_t nCtx) /* * seed in contents generated by an external program */ - if ((fp = ssl_util_ppopen(s, p, pRandSeed->cpPath)) == NULL) + if ((fp = ssl_util_ppopen(s, p, ap_psprintf(p, "%s %d", + pRandSeed->cpPath, pRandSeed->nBytes))) == NULL) continue; nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes); ssl_util_ppclose(s, p, fp); } else if (pRandSeed->nSrc == SSL_RSSRC_BUILTIN) { - /* + /* * seed in the current time (usually just 4 bytes) */ t = time(NULL); @@ -130,7 +131,7 @@ int ssl_rand_seed(server_rec *s, pool *p, ssl_rsctx_t nCtx) RAND_seed((unsigned char *)&pid, l); nDone += l; - /* + /* * seed in an 1KB extract of the current scoreboard */ if (ap_scoreboard_image != NULL) { @@ -174,10 +175,10 @@ static int ssl_rand_feedfp(pool *p, FILE *fp, int nReq) } static int ssl_rand_choosenum(int l, int h) -{ +{ int i; char buf[50]; - + srand((unsigned int)time(NULL)); ap_snprintf(buf, sizeof(buf), "%.0f", (((double)(rand()%RAND_MAX)/RAND_MAX)*(h-l))); diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c index 4ba070ce386..768cc3edaa6 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_scache.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_scache.c ** Session Cache @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -73,7 +73,7 @@ */ /* - * FIXME: There is no define in SSLeay, but SSLeay uses 1024*10, + * FIXME: There is no define in OpenSSL, but OpenSSL uses 1024*10, * so 1024*20 should be ok. */ #define MAX_SESSION_DER 1024*20 @@ -84,16 +84,41 @@ void ssl_scache_init(server_rec *s, pool *p) if (mc->nSessionCacheMode == SSL_SCMODE_DBM) ssl_scache_dbm_init(s, p); - ssl_scache_expire(s); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + ssl_scache_shm_init(s, p); + ssl_scache_expire(s, time(NULL)); + +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::scache_init", + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, p); +#endif + + return; +} + +void ssl_scache_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(); + + if (mc->nSessionCacheMode == SSL_SCMODE_DBM) + ssl_scache_dbm_kill(s); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + ssl_scache_shm_kill(s); + +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::scache_kill", + AP_HOOK_SIG1(void), AP_HOOK_ALL); +#endif return; } -void ssl_scache_store(server_rec *s, SSL_SESSION *pSession, int timeout) +BOOL ssl_scache_store(server_rec *s, SSL_SESSION *pSession, int timeout) { SSLModConfigRec *mc = myModConfig(); ssl_scinfo_t SCI; UCHAR buf[MAX_SESSION_DER]; UCHAR *b; + BOOL rc = FALSE; /* add the key */ SCI.ucaKey = pSession->session_id; @@ -106,9 +131,19 @@ void ssl_scache_store(server_rec *s, SSL_SESSION *pSession, int timeout) /* and store it... */ if (mc->nSessionCacheMode == SSL_SCMODE_DBM) - ssl_scache_dbm_store(s, &SCI); + rc = ssl_scache_dbm_store(s, &SCI); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + rc = ssl_scache_shm_store(s, &SCI); - return; +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::scache_store", + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI); +#endif + + /* allow the regular expiring to occur */ + ssl_scache_expire(s, time(NULL)); + + return rc; } SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen) @@ -118,6 +153,12 @@ SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen) ssl_scinfo_t SCI; time_t tNow; + /* determine current time */ + tNow = time(NULL); + + /* allow the regular expiring to occur */ + ssl_scache_expire(s, tNow); + /* create cache query */ SCI.ucaKey = id; SCI.nKey = idlen; @@ -128,16 +169,28 @@ SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen) /* perform cache query */ if (mc->nSessionCacheMode == SSL_SCMODE_DBM) ssl_scache_dbm_retrieve(s, &SCI); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + ssl_scache_shm_retrieve(s, &SCI); + +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::scache_retrieve", + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI); +#endif /* return immediately if not found */ if (SCI.ucaData == NULL) return NULL; /* check for expire time */ - tNow = time(NULL); if (SCI.tExpiresAt <= tNow) { if (mc->nSessionCacheMode == SSL_SCMODE_DBM) ssl_scache_dbm_remove(s, &SCI); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + ssl_scache_shm_remove(s, &SCI); +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::scache_remove", + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI); +#endif return NULL; } @@ -161,16 +214,55 @@ void ssl_scache_remove(server_rec *s, SSL_SESSION *pSession) /* perform remove */ if (mc->nSessionCacheMode == SSL_SCMODE_DBM) ssl_scache_dbm_remove(s, &SCI); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + ssl_scache_shm_remove(s, &SCI); + +#ifdef SSL_VENDOR + ap_hook_use("ap::mod_ssl::vendor::scache_remove", + AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, &SCI); +#endif return; } -void ssl_scache_expire(server_rec *s) +void ssl_scache_expire(server_rec *s, time_t now) { SSLModConfigRec *mc = myModConfig(); + SSLSrvConfigRec *sc = mySrvConfig(s); + static time_t last = 0; + /* + * make sure the expiration for still not-accessed session + * cache entries is done only from time to time + */ + if (now < last+sc->nSessionCacheTimeout) + return; + last = now; + + /* + * Now perform the expiration + */ if (mc->nSessionCacheMode == SSL_SCMODE_DBM) - ssl_scache_dbm_expire(s); + ssl_scache_dbm_expire(s, now); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + ssl_scache_shm_expire(s, now); + + return; +} + +void ssl_scache_status(server_rec *s, pool *p, void (*func)(char *, void *), void *arg) +{ + SSLModConfigRec *mc = myModConfig(); + + /* allow the regular expiring to occur */ + ssl_scache_expire(s, time(NULL)); + + if (mc->nSessionCacheMode == SSL_SCMODE_DBM) + ssl_scache_dbm_status(s, p, func, arg); + else if (mc->nSessionCacheMode == SSL_SCMODE_SHM) + ssl_scache_shm_status(s, p, func, arg); + else + func("N.A.", arg); return; } @@ -213,75 +305,113 @@ void ssl_scache_dbm_init(server_rec *s, pool *p) * Open it once to create it and to make sure it * _can_ be created. */ - ssl_mutex_on(); + ssl_mutex_on(s); if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile, O_RDWR|O_CREAT, SSL_DBM_FILE_MODE)) == NULL) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, "Cannot create SSLSessionCache DBM file `%s'", mc->szSessionCacheDataFile); - ssl_mutex_off(); + ssl_mutex_off(s); return; } ssl_dbm_close(dbm); -#ifndef WIN32 +#if !defined(OS2) && !defined(WIN32) /* - * we have to make sure the Apache child processes - * have access to the DBM file... + * We have to make sure the Apache child processes + * have access to the DBM file. But because there + * are brain-dead platforms where we cannot exactly + * determine the suffixes we try all possibilities. */ if (geteuid() == 0 /* is superuser */) { - chown(mc->szSessionCacheDataFile, - ap_user_id, -1 /* no gid change */); - chown(ap_pstrcat(p, mc->szSessionCacheDataFile, - SSL_DBM_FILE_SUFFIX_DIR, NULL), - ap_user_id, -1 /* no gid change */); - chown(ap_pstrcat(p, mc->szSessionCacheDataFile, - SSL_DBM_FILE_SUFFIX_PAG, NULL), - ap_user_id, -1 /* no gid change */); + chown(mc->szSessionCacheDataFile, ap_user_id, -1 /* no gid change */); + if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL), + ap_user_id, -1) == -1) { + if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), + ap_user_id, -1) == -1) + chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL), + ap_user_id, -1); + } + if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL), + ap_user_id, -1) == -1) { + if (chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL), + ap_user_id, -1) == -1) + chown(ap_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL), + ap_user_id, -1); + } } #endif - ssl_mutex_off(); + ssl_mutex_off(s); return; } -void ssl_scache_dbm_store(server_rec *s, ssl_scinfo_t *SCI) +void ssl_scache_dbm_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(); + pool *p; + + if ((p = ap_make_sub_pool(NULL)) != NULL) { + /* the correct way */ + unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL)); + unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL)); + /* the additional ways to be sure */ + unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL)); + unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL)); + unlink(ap_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL)); + unlink(mc->szSessionCacheDataFile); + ap_destroy_pool(p); + } + return; +} + +BOOL ssl_scache_dbm_store(server_rec *s, ssl_scinfo_t *SCI) { SSLModConfigRec *mc = myModConfig(); DBM *dbm; datum dbmkey; datum dbmval; + /* be careful: do not try to store too much bytes in a DBM file! */ +#ifdef SSL_USE_SDBM + if ((SCI->nKey + SCI->nData) >= PAIRMAX) + return FALSE; +#else + if ((SCI->nKey + SCI->nData) >= 1024) + return FALSE; +#endif + /* create DBM key */ - dbmkey.dptr = SCI->ucaKey; + dbmkey.dptr = (char *)(SCI->ucaKey); dbmkey.dsize = SCI->nKey; /* create DBM value */ dbmval.dsize = sizeof(time_t)+SCI->nData; - dbmval.dptr = (UCHAR *)malloc(dbmval.dsize); + dbmval.dptr = (char *)malloc(dbmval.dsize); if (dbmval.dptr == NULL) - return; - memcpy(dbmval.dptr, &SCI->tExpiresAt, sizeof(time_t)); + return FALSE; + memcpy((char *)dbmval.dptr, &SCI->tExpiresAt, sizeof(time_t)); memcpy((char *)dbmval.dptr+sizeof(time_t), SCI->ucaData, SCI->nData); /* and store it to the DBM file */ - ssl_mutex_on(); + ssl_mutex_on(s); if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile, O_RDWR, SSL_DBM_FILE_MODE)) == NULL) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, "Cannot open SSLSessionCache DBM file `%s' for writing (store)", mc->szSessionCacheDataFile); - ssl_mutex_off(); - return; + free(dbmval.dptr); + ssl_mutex_off(s); + return FALSE; } ssl_dbm_store(dbm, dbmkey, dbmval, DBM_INSERT); ssl_dbm_close(dbm); - ssl_mutex_off(); + ssl_mutex_off(s); /* free temporary buffers */ free(dbmval.dptr); - return; + return TRUE; } void ssl_scache_dbm_retrieve(server_rec *s, ssl_scinfo_t *SCI) @@ -297,22 +427,22 @@ void ssl_scache_dbm_retrieve(server_rec *s, ssl_scinfo_t *SCI) SCI->tExpiresAt = 0; /* create DBM key and values */ - dbmkey.dptr = SCI->ucaKey; + dbmkey.dptr = (char *)(SCI->ucaKey); dbmkey.dsize = SCI->nKey; /* and fetch it from the DBM file */ - ssl_mutex_on(); + ssl_mutex_on(s); if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile, O_RDONLY, SSL_DBM_FILE_MODE)) == NULL) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, "Cannot open SSLSessionCache DBM file `%s' for reading (fetch)", mc->szSessionCacheDataFile); - ssl_mutex_off(); + ssl_mutex_off(s); return; } dbmval = ssl_dbm_fetch(dbm, dbmkey); ssl_dbm_close(dbm); - ssl_mutex_off(); + ssl_mutex_off(s); /* immediately return if not found */ if (dbmval.dptr == NULL || dbmval.dsize < sizeof(time_t)) @@ -338,71 +468,423 @@ void ssl_scache_dbm_remove(server_rec *s, ssl_scinfo_t *SCI) datum dbmkey; /* create DBM key and values */ - dbmkey.dptr = SCI->ucaKey; + dbmkey.dptr = (char *)(SCI->ucaKey); dbmkey.dsize = SCI->nKey; /* and delete it from the DBM file */ - ssl_mutex_on(); + ssl_mutex_on(s); if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile, O_RDWR, SSL_DBM_FILE_MODE)) == NULL) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, "Cannot open SSLSessionCache DBM file `%s' for writing (delete)", mc->szSessionCacheDataFile); - ssl_mutex_off(); + ssl_mutex_off(s); return; } ssl_dbm_delete(dbm, dbmkey); ssl_dbm_close(dbm); - ssl_mutex_off(); + ssl_mutex_off(s); return; } -void ssl_scache_dbm_expire(server_rec *s) +void ssl_scache_dbm_expire(server_rec *s, time_t tNow) { SSLModConfigRec *mc = myModConfig(); - static int nExpireCalls = 0; DBM *dbm; datum dbmkey; datum dbmval; - time_t tNow; + pool *p; time_t tExpiresAt; + int nElements = 0; + int nDeleted = 0; + int bDelete; + datum *keylist; + int keyidx; + int i; /* - * It's to expensive to expire allways, - * so do it only from time to time... + * Here we have to be very carefully: Not all DBM libraries are + * smart enough to allow one to iterate over the elements and at the + * same time delete expired ones. Some of them get totally crazy + * while others have no problems. So we have to do it the slower but + * more safe way: we first iterate over all elements and remember + * those which have to be expired. Then in a second pass we delete + * all those expired elements. Additionally we reopen the DBM file + * to be really safe in state. */ - if (nExpireCalls++ < 100) - return; - else - nExpireCalls = 0; - ssl_mutex_on(); +#define KEYMAX 1024 + + ssl_mutex_on(s); + for (;;) { + /* allocate the key array in a memory sub pool */ + if ((p = ap_make_sub_pool(NULL)) == NULL) + break; + if ((keylist = ap_palloc(p, sizeof(dbmkey)*KEYMAX)) == NULL) { + ap_destroy_pool(p); + break; + } + + /* pass 1: scan DBM database */ + keyidx = 0; + if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile, + O_RDWR, SSL_DBM_FILE_MODE)) == NULL) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, + "Cannot open SSLSessionCache DBM file `%s' for scanning", + mc->szSessionCacheDataFile); + ap_destroy_pool(p); + break; + } + dbmkey = ssl_dbm_firstkey(dbm); + while (dbmkey.dptr != NULL) { + nElements++; + bDelete = FALSE; + dbmval = ssl_dbm_fetch(dbm, dbmkey); + if (dbmval.dsize < sizeof(time_t) || dbmval.dptr == NULL) + bDelete = TRUE; + else { + memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t)); + if (tExpiresAt >= tNow) + bDelete = TRUE; + } + if (bDelete) { + if ((keylist[keyidx].dptr = ap_palloc(p, dbmkey.dsize)) != NULL) { + memcpy(keylist[keyidx].dptr, dbmkey.dptr, dbmkey.dsize); + keylist[keyidx].dsize = dbmkey.dsize; + keyidx++; + if (keyidx == KEYMAX) + break; + } + } + dbmkey = ssl_dbm_nextkey(dbm); + } + ssl_dbm_close(dbm); + + /* pass 2: delete expired elements */ + if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile, + O_RDWR, SSL_DBM_FILE_MODE)) == NULL) { + ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, + "Cannot re-open SSLSessionCache DBM file `%s' for expiring", + mc->szSessionCacheDataFile); + ap_destroy_pool(p); + break; + } + for (i = 0; i < keyidx; i++) { + ssl_dbm_delete(dbm, keylist[i]); + nDeleted++; + } + ssl_dbm_close(dbm); + + /* destroy temporary pool */ + ap_destroy_pool(p); + + if (keyidx < KEYMAX) + break; + } + ssl_mutex_off(s); + + ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache (DBM) Expiry: " + "old: %d, new: %d, removed: %d", nElements, nElements-nDeleted, nDeleted); + return; +} + +void ssl_scache_dbm_status(server_rec *s, pool *p, void (*func)(char *, void *), void *arg) +{ + SSLModConfigRec *mc = myModConfig(); + DBM *dbm; + datum dbmkey; + datum dbmval; + int nElem; + int nSize; + int nAverage; + + nElem = 0; + nSize = 0; + ssl_mutex_on(s); if ((dbm = ssl_dbm_open(mc->szSessionCacheDataFile, - O_RDWR, SSL_DBM_FILE_MODE)) == NULL) { + O_RDONLY, SSL_DBM_FILE_MODE)) == NULL) { ssl_log(s, SSL_LOG_ERROR|SSL_ADD_ERRNO, - "Cannot open SSLSessionCache DBM file `%s' for expiring", + "Cannot open SSLSessionCache DBM file `%s' for status retrival", mc->szSessionCacheDataFile); - ssl_mutex_off(); + ssl_mutex_off(s); return; } - tNow = time(NULL); dbmkey = ssl_dbm_firstkey(dbm); for ( ; dbmkey.dptr != NULL; dbmkey = ssl_dbm_nextkey(dbm)) { dbmval = ssl_dbm_fetch(dbm, dbmkey); if (dbmval.dptr == NULL) continue; - if (dbmval.dsize < sizeof(time_t)) { - ssl_dbm_delete(dbm, dbmkey); - continue; - } - memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t)); - if (tExpiresAt >= tNow) - ssl_dbm_delete(dbm, dbmkey); + nElem += 1; + nSize += dbmval.dsize; } ssl_dbm_close(dbm); - ssl_mutex_off(); + ssl_mutex_off(s); + if (nSize > 0 && nElem > 0) + nAverage = nSize / nElem; + else + nAverage = 0; + func(ap_psprintf(p, "cache type: <b>DBM</b>, maximum size: <b>unlimited</b><br>"), arg); + func(ap_psprintf(p, "current sessions: <b>%d</b>, current size: <b>%d</b> bytes<br>", nElem, nSize), arg); + func(ap_psprintf(p, "average session size: <b>%d</b> bytes<br>", nAverage), arg); + return; +} + +/* _________________________________________________________________ +** +** Session Cache Support (SHM) +** _________________________________________________________________ +*/ + +/* + * Wrapper functions for table library which resemble malloc(3) & Co + * but use the variants from the MM shared memory library. + */ + +static void *ssl_scache_shm_malloc(size_t size) +{ + SSLModConfigRec *mc = myModConfig(); + return ap_mm_malloc(mc->pSessionCacheDataMM, size); +} + +static void *ssl_scache_shm_calloc(size_t number, size_t size) +{ + SSLModConfigRec *mc = myModConfig(); + return ap_mm_calloc(mc->pSessionCacheDataMM, number, size); +} + +static void *ssl_scache_shm_realloc(void *ptr, size_t size) +{ + SSLModConfigRec *mc = myModConfig(); + return ap_mm_realloc(mc->pSessionCacheDataMM, ptr, size); +} + +static void ssl_scache_shm_free(void *ptr) +{ + SSLModConfigRec *mc = myModConfig(); + ap_mm_free(mc->pSessionCacheDataMM, ptr); + return; +} + +/* + * Now the actual session cache implementation + * based on a hash table inside a shared memory segment. + */ + +void ssl_scache_shm_init(server_rec *s, pool *p) +{ + SSLModConfigRec *mc = myModConfig(); + AP_MM *mm; + table_t *ta; + int ta_errno; + int avail; + int n; + + /* + * Create shared memory segment + */ + if (mc->szSessionCacheDataFile == NULL) { + ssl_log(s, SSL_LOG_ERROR, "SSLSessionCache required"); + ssl_die(); + } + if ((mm = ap_mm_create(mc->nSessionCacheDataSize, + mc->szSessionCacheDataFile)) == NULL) { + ssl_log(s, SSL_LOG_ERROR, + "Cannot allocate shared memory: %s", ap_mm_error()); + ssl_die(); + } + mc->pSessionCacheDataMM = mm; + + /* + * Make sure the childs have access to the underlaying files + */ + ap_mm_permission(mm, SSL_MM_FILE_MODE, ap_user_id, -1); + + /* + * Create hash table in shared memory segment + */ + avail = ap_mm_available(mm); + n = (avail/2) / 1024; + n = n < 10 ? 10 : n; + if ((ta = table_alloc(n, &ta_errno, + ssl_scache_shm_malloc, + ssl_scache_shm_calloc, + ssl_scache_shm_realloc, + ssl_scache_shm_free )) == NULL) { + ssl_log(s, SSL_LOG_ERROR, + "Cannot allocate hash table in shared memory: %s", + table_strerror(ta_errno)); + ssl_die(); + } + table_attr(ta, TABLE_FLAG_AUTO_ADJUST|TABLE_FLAG_ADJUST_DOWN); + table_set_data_alignment(ta, sizeof(char *)); + table_clear(ta); + mc->tSessionCacheDataTable = ta; + + /* + * Log the done work + */ + ssl_log(s, SSL_LOG_INFO, + "Init: Created hash-table (%d buckets) " + "in shared memory (%d bytes) for SSL session cache", n, avail); + return; +} + +void ssl_scache_shm_kill(server_rec *s) +{ + SSLModConfigRec *mc = myModConfig(); + + if (mc->pSessionCacheDataMM != NULL) { + ap_mm_destroy(mc->pSessionCacheDataMM); + mc->pSessionCacheDataMM = NULL; + } + return; +} + +BOOL ssl_scache_shm_store(server_rec *s, ssl_scinfo_t *SCI) +{ + SSLModConfigRec *mc = myModConfig(); + void *vp; + + ssl_mutex_on(s); + if (table_insert_kd(mc->tSessionCacheDataTable, + SCI->ucaKey, SCI->nKey, + NULL, sizeof(time_t)+SCI->nData, + NULL, &vp, 1) != TABLE_ERROR_NONE) { + ssl_mutex_off(s); + return FALSE; + } + memcpy(vp, &SCI->tExpiresAt, sizeof(time_t)); + memcpy((char *)vp+sizeof(time_t), SCI->ucaData, SCI->nData); + ssl_mutex_off(s); + return TRUE; +} + +void ssl_scache_shm_retrieve(server_rec *s, ssl_scinfo_t *SCI) +{ + SSLModConfigRec *mc = myModConfig(); + void *vp; + int n; + /* initialize result */ + SCI->ucaData = NULL; + SCI->nData = 0; + SCI->tExpiresAt = 0; + + /* lookup key in table */ + ssl_mutex_on(s); + if (table_retrieve(mc->tSessionCacheDataTable, + SCI->ucaKey, SCI->nKey, + &vp, &n) != TABLE_ERROR_NONE) { + ssl_mutex_off(s); + return; + } + + /* copy over the information to the SCI */ + SCI->nData = n-sizeof(time_t); + SCI->ucaData = (UCHAR *)malloc(SCI->nData); + if (SCI->ucaData == NULL) { + SCI->nData = 0; + ssl_mutex_off(s); + return; + } + memcpy(&SCI->tExpiresAt, vp, sizeof(time_t)); + memcpy(SCI->ucaData, (char *)vp+sizeof(time_t), SCI->nData); + ssl_mutex_off(s); + + return; +} + +void ssl_scache_shm_remove(server_rec *s, ssl_scinfo_t *SCI) +{ + SSLModConfigRec *mc = myModConfig(); + + /* remove value under key in table */ + ssl_mutex_on(s); + table_delete(mc->tSessionCacheDataTable, + SCI->ucaKey, SCI->nKey, NULL, NULL); + ssl_mutex_off(s); + return; +} + +void ssl_scache_shm_expire(server_rec *s, time_t tNow) +{ + SSLModConfigRec *mc = myModConfig(); + table_linear_t iterator; + time_t tExpiresAt; + void *vpKey; + void *vpKeyThis; + void *vpData; + int nKey; + int nKeyThis; + int nData; + int nElements = 0; + int nDeleted = 0; + int bDelete; + int rc; + + ssl_mutex_on(s); + if (table_first_r(mc->tSessionCacheDataTable, &iterator, + &vpKey, &nKey, &vpData, &nData) == TABLE_ERROR_NONE) { + do { + bDelete = FALSE; + nElements++; + if (nData < sizeof(time_t) || vpData == NULL) + bDelete = TRUE; + else { + memcpy(&tExpiresAt, vpData, sizeof(time_t)); + if (tExpiresAt >= tNow) + bDelete = TRUE; + } + vpKeyThis = vpKey; + nKeyThis = nKey; + rc = table_next_r(mc->tSessionCacheDataTable, &iterator, + &vpKey, &nKey, &vpData, &nData); + if (bDelete) { + table_delete(mc->tSessionCacheDataTable, + vpKeyThis, nKeyThis, NULL, NULL); + nDeleted++; + } + } while (rc == TABLE_ERROR_NONE); + } + ssl_mutex_off(s); + ssl_log(s, SSL_LOG_TRACE, "Inter-Process Session Cache (SHM) Expiry: " + "old: %d, new: %d, removed: %d", nElements, nElements-nDeleted, nDeleted); + return; +} + +void ssl_scache_shm_status(server_rec *s, pool *p, void (*func)(char *, void *), void *arg) +{ + SSLModConfigRec *mc = myModConfig(); + void *vpKey; + void *vpData; + int nKey; + int nData; + int nElem; + int nSize; + int nAverage; + + nElem = 0; + nSize = 0; + ssl_mutex_on(s); + if (table_first(mc->tSessionCacheDataTable, + &vpKey, &nKey, &vpData, &nData) == TABLE_ERROR_NONE) { + do { + if (vpKey == NULL || vpData == NULL) + continue; + nElem += 1; + nSize += nData; + } while (table_next(mc->tSessionCacheDataTable, + &vpKey, &nKey, &vpData, &nData) == TABLE_ERROR_NONE); + } + ssl_mutex_off(s); + if (nSize > 0 && nElem > 0) + nAverage = nSize / nElem; + else + nAverage = 0; + func(ap_psprintf(p, "cache type: <b>SHM</b>, maximum size: <b>%d</b> bytes<br>", mc->nSessionCacheDataSize), arg); + func(ap_psprintf(p, "current sessions: <b>%d</b>, current size: <b>%d</b> bytes<br>", nElem, nSize), arg); + func(ap_psprintf(p, "average session size: <b>%d</b> bytes<br>", nAverage), arg); return; } diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c b/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c index ef54924d3e1..e0c2c817c89 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_engine_vars.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_engine_vars.c ** Variable Lookup Facility @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -77,7 +77,7 @@ static char *ssl_var_lookup_ssl_cert(pool *p, X509 *xs, char *var); static char *ssl_var_lookup_ssl_cert_dn(pool *p, X509_NAME *xsname, char *var); static char *ssl_var_lookup_ssl_cert_valid(pool *p, ASN1_UTCTIME *tm); static char *ssl_var_lookup_ssl_cert_serial(pool *p, X509 *xs); -static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK *sk, char *var); +static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK_OF(X509) *sk, char *var); static char *ssl_var_lookup_ssl_cert_PEM(pool *p, X509 *xs); static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var); static void ssl_var_lookup_ssl_cipher_bits(char *cipher, int *usekeysize, int *algkeysize); @@ -145,7 +145,7 @@ char *ssl_var_lookup(pool *p, server_rec *s, conn_rec *c, request_rec *r, char * else if (strcEQ(var, "THE_REQUEST")) result = r->the_request; else if (strcEQ(var, "REQUEST_METHOD")) - result = r->method; + result = (char *)(r->method); else if (strcEQ(var, "REQUEST_SCHEME")) result = ap_http_method(r); else if (strcEQ(var, "REQUEST_URI")) @@ -279,33 +279,35 @@ static char *ssl_var_lookup_ssl(pool *p, conn_rec *c, char *var) { char *result; X509 *xs; - STACK *sk; + STACK_OF(X509) *sk; SSL *ssl; result = NULL; + ssl = ap_ctx_get(c->client->ctx, "ssl"); if (strlen(var) > 8 && strcEQn(var, "VERSION_", 8)) { result = ssl_var_lookup_ssl_version(p, var+8); } - else if (strcEQ(var, "PROTOCOL")) { - ssl = ap_ctx_get(c->client->ctx, "ssl"); + else if (ssl != NULL && strcEQ(var, "PROTOCOL")) { result = SSL_get_version(ssl); } - else if (strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) { + else if (ssl != NULL && strcEQ(var, "SESSION_ID")) { + SSL_SESSION *pSession = SSL_get_session(ssl); + result = ap_pstrdup(p, ssl_scache_id2sz(pSession->session_id, + pSession->session_id_length)); + } + else if (ssl != NULL && strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) { result = ssl_var_lookup_ssl_cipher(p, c, var+6); } - else if (strlen(var) > 18 && strcEQn(var, "CLIENT_CERT_CHAIN_", 18)) { - ssl = ap_ctx_get(c->client->ctx, "ssl"); + else if (ssl != NULL && strlen(var) > 18 && strcEQn(var, "CLIENT_CERT_CHAIN_", 18)) { sk = SSL_get_peer_cert_chain(ssl); result = ssl_var_lookup_ssl_cert_chain(p, sk, var+17); } - else if (strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) { - ssl = ap_ctx_get(c->client->ctx, "ssl"); + else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) { if ((xs = SSL_get_peer_certificate(ssl)) != NULL) result = ssl_var_lookup_ssl_cert(p, xs, var+7); } - else if (strlen(var) > 7 && strcEQn(var, "SERVER_", 7)) { - ssl = ap_ctx_get(c->client->ctx, "ssl"); + else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "SERVER_", 7)) { if ((xs = SSL_get_certificate(ssl)) != NULL) result = ssl_var_lookup_ssl_cert(p, xs, var+7); } @@ -403,12 +405,15 @@ static char *ssl_var_lookup_ssl_cert_dn(pool *p, X509_NAME *xsname, char *var) for (i = 0; ssl_var_lookup_ssl_cert_dn_rec[i].name != NULL; i++) { if (strEQ(var, ssl_var_lookup_ssl_cert_dn_rec[i].name)) { - for (j = 0; j < sk_num(xsname->entries); j++) { - xsne = (X509_NAME_ENTRY *)sk_value(xsname->entries, j); + for (j = 0; j < sk_X509_NAME_ENTRY_num(xsname->entries); j++) { + xsne = sk_X509_NAME_ENTRY_value(xsname->entries, j); n = OBJ_obj2nid(xsne->object); if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid) { result = ap_palloc(p, xsne->value->length+1); ap_cpystrn(result, (char *)xsne->value->data, xsne->value->length+1); +#ifdef CHARSET_EBCDIC + ascii2ebcdic(result, result, xsne->value->length); +#endif /* CHARSET_EBCDIC */ result[xsne->value->length] = NUL; break; } @@ -439,7 +444,7 @@ static char *ssl_var_lookup_ssl_cert_valid(pool *p, ASN1_UTCTIME *tm) static char *ssl_var_lookup_ssl_cert_serial(pool *p, X509 *xs) { char *result; - BIO* bio; + BIO *bio; int n; if ((bio = BIO_new(BIO_s_mem())) == NULL) @@ -453,7 +458,7 @@ static char *ssl_var_lookup_ssl_cert_serial(pool *p, X509 *xs) return result; } -static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK *sk, char *var) +static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK_OF(X509) *sk, char *var) { char *result; X509 *xs; @@ -463,8 +468,8 @@ static char *ssl_var_lookup_ssl_cert_chain(pool *p, STACK *sk, char *var) if (strspn(var, "0123456789") == strlen(var)) { n = atoi(var); - if (sk_num(sk) >= n) { - xs = (X509 *)sk_value(sk, n); + if (sk_X509_num(sk) >= n) { + xs = sk_X509_value(sk, n); result = ssl_var_lookup_ssl_cert_PEM(p, xs); } } @@ -502,24 +507,24 @@ static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var) if (strEQ(var, "")) { ssl = ap_ctx_get(c->client->ctx, "ssl"); - result = SSL_get_cipher_name(ssl); + result = (char *)SSL_get_cipher_name(ssl); } else if (strcEQ(var, "_EXPORT")) { ssl = ap_ctx_get(c->client->ctx, "ssl"); - cipher = SSL_get_cipher_name(ssl); + cipher = (char *)SSL_get_cipher_name(ssl); ssl_var_lookup_ssl_cipher_bits(cipher, &usekeysize, &algkeysize); result = (usekeysize < 56 ? "true" : "false"); } else if (strcEQ(var, "_USEKEYSIZE")) { ssl = ap_ctx_get(c->client->ctx, "ssl"); - cipher = SSL_get_cipher_name(ssl); + cipher = (char *)SSL_get_cipher_name(ssl); ssl_var_lookup_ssl_cipher_bits(cipher, &usekeysize, &algkeysize); result = ap_psprintf(p, "%d", usekeysize); resdup = FALSE; } else if (strcEQ(var, "_ALGKEYSIZE")) { ssl = ap_ctx_get(c->client->ctx, "ssl"); - cipher = SSL_get_cipher_name(ssl); + cipher = (char *)SSL_get_cipher_name(ssl); ssl_var_lookup_ssl_cipher_bits(cipher, &usekeysize, &algkeysize); result = ap_psprintf(p, "%d", algkeysize); resdup = FALSE; @@ -532,7 +537,7 @@ static char *ssl_var_lookup_ssl_cipher(pool *p, conn_rec *c, char *var) /* * This structure is used instead of SSL_get_cipher_bits() because - * this SSLeay function has rounding problems, but we want the + * this OpenSSL function has rounding problems, but we want the * correct sizes. */ static const struct { @@ -540,6 +545,11 @@ static const struct { int nUseKeySize; int nAlgKeySize; } ssl_var_lookup_ssl_cipher_bits_rec[] = { + + { TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 /*EXP1024-RC4-MD5*/, 56, 128 }, + { TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 /*EXP1024-RC2-CBC-MD5*/,56, 128 }, + { TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA /*EXP1024-DES-CBC-SHA*/,56, 56 }, + { SSL3_TXT_RSA_IDEA_128_SHA /*IDEA-CBC-SHA*/, 128, 128 }, { SSL3_TXT_RSA_NULL_MD5 /*NULL-MD5*/, 0, 0 }, { SSL3_TXT_RSA_NULL_SHA /*NULL-SHA*/, 0, 0 }, @@ -571,12 +581,14 @@ static const struct { { SSL3_TXT_FZA_DMS_NULL_SHA /*FZA-NULL-SHA*/, 0, 0 }, { SSL3_TXT_FZA_DMS_FZA_SHA /*FZA-FZA-CBC-SHA*/, 0, 0 }, { SSL3_TXT_FZA_DMS_RC4_SHA /*FZA-RC4-SHA*/, 128, 128 }, + { SSL2_TXT_DES_64_CFB64_WITH_MD5_1 /*DES-CFB-M1*/, 56, 56 }, { SSL2_TXT_RC2_128_CBC_WITH_MD5 /*RC2-CBC-MD5*/, 128, 128 }, { SSL2_TXT_DES_64_CBC_WITH_MD5 /*DES-CBC-MD5*/, 56, 56 }, { SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 /*DES-CBC3-MD5*/, 168, 168 }, { SSL2_TXT_RC4_64_WITH_MD5 /*RC4-64-MD5*/, 64, 64 }, { SSL2_TXT_NULL /*NULL*/, 0, 0 }, + { NULL, 0, 0 } }; @@ -614,7 +626,7 @@ static char *ssl_var_lookup_ssl_version(pool *p, char *var) result = ap_psprintf(p, "mod_ssl/%s", MOD_SSL_VERSION); } else if (strEQ(var, "LIBRARY")) { - result = ap_pstrdup(p, SSLeay_version(SSLEAY_VERSION)); + result = ap_pstrdup(p, SSL_LIBRARY_TEXT); if ((cp = strchr(result, ' ')) != NULL) { *cp = '/'; if ((cp2 = strchr(cp, ' ')) != NULL) diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr.c index 0015ea09ad5..8601468dca8 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_expr.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_expr.c ** Expression Handling @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr.h b/usr.sbin/httpd/src/modules/ssl/ssl_expr.h index b6851971038..42c6cdde9fb 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_expr.h +++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr.h @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_expr.h ** Expression Handling (Header) @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c index 61e6f826ac5..8fd58a59768 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_eval.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_expr_eval.c ** Expression Evaluation @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c index cbc42253136..f6b45840879 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.c @@ -1,5 +1,3 @@ -#ifndef lint -#endif #include <stdlib.h> #define YYBYACC 1 #define YYMAJOR 1 @@ -9,19 +7,16 @@ #define ssl_expr_yyclearin (ssl_expr_yychar=(YYEMPTY)) #define ssl_expr_yyerrok (ssl_expr_yyerrflag=0) #define YYRECOVERING (ssl_expr_yyerrflag!=0) -#if defined(c_plusplus) || defined(__cplusplus) -#include <stdlib.h> -#else -extern char *getenv(); -extern void *realloc(); -#endif static int ssl_expr_yygrowstack(); #define YYPREFIX "ssl_expr_yy" +#line 72 "ssl_expr_parse.y" #include "mod_ssl.h" +#line 75 "ssl_expr_parse.y" typedef union { char *cpVal; ssl_expr *exVal; } YYSTYPE; +#line 29 "y.tab.c" #define T_TRUE 257 #define T_FALSE 258 #define T_DIGIT 259 @@ -218,6 +213,7 @@ short *ssl_expr_yyss; short *ssl_expr_yysslim; YYSTYPE *ssl_expr_yyvs; int ssl_expr_yystacksize; +#line 180 "ssl_expr_parse.y" int ssl_expr_yyerror(char *s) { @@ -225,6 +221,7 @@ int ssl_expr_yyerror(char *s) return 2; } +#line 232 "y.tab.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ static int ssl_expr_yygrowstack() { @@ -394,75 +391,99 @@ ssl_expr_yyreduce: switch (ssl_expr_yyn) { case 1: +#line 118 "ssl_expr_parse.y" { ssl_expr_info.expr = ssl_expr_yyvsp[0].exVal; } break; case 2: +#line 121 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_True, NULL, NULL); } break; case 3: +#line 122 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_False, NULL, NULL); } break; case 4: +#line 123 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_Not, ssl_expr_yyvsp[0].exVal, NULL); } break; case 5: +#line 124 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_Or, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 6: +#line 125 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_And, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 7: +#line 126 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_Comp, ssl_expr_yyvsp[0].exVal, NULL); } break; case 8: +#line 127 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_yyvsp[-1].exVal; } break; case 9: +#line 130 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_EQ, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 10: +#line 131 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_NE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 11: +#line 132 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_LT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 12: +#line 133 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_LE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 13: +#line 134 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_GT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 14: +#line 135 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_GE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 15: +#line 136 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_IN, ssl_expr_yyvsp[-4].exVal, ssl_expr_yyvsp[-1].exVal); } break; case 16: +#line 137 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_REG, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 17: +#line 138 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_NRE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); } break; case 18: +#line 141 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, NULL); } break; case 19: +#line 142 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, ssl_expr_yyvsp[-2].exVal); } break; case 20: +#line 145 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_Digit, ssl_expr_yyvsp[0].cpVal, NULL); } break; case 21: +#line 146 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_String, ssl_expr_yyvsp[0].cpVal, NULL); } break; case 22: +#line 147 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_make(op_Var, ssl_expr_yyvsp[-1].cpVal, NULL); } break; case 23: +#line 148 "ssl_expr_parse.y" { ssl_expr_yyval.exVal = ssl_expr_yyvsp[0].exVal; } break; case 24: +#line 151 "ssl_expr_parse.y" { regex_t *regex; if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal, @@ -475,6 +496,7 @@ case 24: } break; case 25: +#line 161 "ssl_expr_parse.y" { regex_t *regex; if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal, @@ -487,11 +509,13 @@ case 25: } break; case 26: +#line 173 "ssl_expr_parse.y" { ssl_expr *args = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[-1].cpVal, NULL); ssl_expr_yyval.exVal = ssl_expr_make(op_Func, "file", args); } break; +#line 526 "y.tab.c" } ssl_expr_yyssp -= ssl_expr_yym; ssl_expr_yystate = *ssl_expr_yyssp; diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y index cc4590ad824..f1819f46d8e 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y +++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_parse.y @@ -1,8 +1,8 @@ /* _ _ ** _ __ ___ ___ __| | ___ ___| | ** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL +** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/ ** |_____| ** ssl_expr_parse.y ** Expression LR(1) Parser @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.c b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.c new file mode 100644 index 00000000000..6d422fdfaa7 --- /dev/null +++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.c @@ -0,0 +1,2002 @@ +#define yy_create_buffer ssl_expr_yy_create_buffer +#define yy_delete_buffer ssl_expr_yy_delete_buffer +#define yy_scan_buffer ssl_expr_yy_scan_buffer +#define yy_scan_string ssl_expr_yy_scan_string +#define yy_scan_bytes ssl_expr_yy_scan_bytes +#define yy_flex_debug ssl_expr_yy_flex_debug +#define yy_init_buffer ssl_expr_yy_init_buffer +#define yy_flush_buffer ssl_expr_yy_flush_buffer +#define yy_load_buffer_state ssl_expr_yy_load_buffer_state +#define yy_switch_to_buffer ssl_expr_yy_switch_to_buffer +#define yyin ssl_expr_yyin +#define yyleng ssl_expr_yyleng +#define yylex ssl_expr_yylex +#define yyout ssl_expr_yyout +#define yyrestart ssl_expr_yyrestart +#define yytext ssl_expr_yytext + +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include <stdio.h> + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include <stdlib.h> +#include <unistd.h> + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include <io.h> +#include <stdlib.h> +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define yywrap() 1 +#define YY_SKIP_YYWRAP +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 46 +#define YY_END_OF_BUFFER 47 +static yyconst short int yy_accept[86] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 47, 45, + 1, 38, 2, 45, 43, 24, 45, 28, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, + 13, 4, 3, 14, 16, 18, 17, 1, 22, 32, + 34, 43, 26, 20, 31, 30, 44, 44, 19, 44, + 44, 29, 27, 39, 25, 23, 15, 15, 21, 44, + 35, 44, 36, 13, 12, 5, 6, 10, 11, 7, + 8, 9, 33, 44, 44, 37, 44, 5, 6, 44, + 40, 41, 5, 42, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 5, 1, 1, 1, 6, 1, 1, + 1, 1, 1, 1, 7, 1, 1, 8, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 1, 1, 10, + 11, 12, 1, 1, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 1, 14, 1, 1, 7, 1, 15, 16, 13, 17, + + 18, 19, 20, 13, 21, 13, 13, 22, 23, 24, + 25, 13, 26, 27, 28, 29, 30, 13, 13, 13, + 13, 13, 1, 31, 1, 32, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[33] = + { 0, + 1, 1, 2, 1, 3, 1, 4, 4, 4, 1, + 1, 1, 4, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 1, 1 + } ; + +static yyconst short int yy_base[93] = + { 0, + 0, 0, 30, 31, 0, 0, 82, 81, 101, 142, + 35, 28, 142, 94, 32, 88, 31, 87, 0, 69, + 66, 28, 28, 67, 29, 63, 30, 63, 62, 57, + 0, 142, 142, 88, 142, 142, 142, 48, 142, 142, + 142, 44, 142, 142, 142, 142, 0, 70, 0, 64, + 63, 0, 0, 0, 0, 0, 142, 0, 0, 55, + 0, 46, 142, 0, 142, 53, 62, 142, 142, 142, + 142, 142, 0, 44, 48, 0, 41, 70, 72, 38, + 0, 0, 74, 0, 142, 117, 121, 125, 50, 129, + 133, 137 + + } ; + +static yyconst short int yy_def[93] = + { 0, + 85, 1, 86, 86, 87, 87, 88, 88, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 89, 89, + 89, 89, 89, 89, 89, 90, 89, 89, 89, 85, + 91, 85, 85, 92, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 85, 89, 89, 89, + 89, 89, 85, 91, 85, 85, 85, 85, 85, 85, + 85, 85, 89, 89, 89, 89, 89, 85, 85, 89, + 89, 89, 85, 89, 0, 85, 85, 85, 85, 85, + 85, 85 + + } ; + +static yyconst short int yy_nxt[175] = + { 0, + 10, 11, 11, 12, 13, 14, 10, 15, 15, 16, + 17, 18, 19, 10, 20, 19, 19, 21, 22, 23, + 24, 25, 26, 27, 28, 19, 19, 19, 29, 19, + 30, 10, 32, 32, 33, 33, 38, 38, 39, 42, + 42, 44, 50, 34, 34, 52, 55, 59, 51, 38, + 38, 42, 42, 47, 60, 84, 53, 56, 82, 40, + 78, 79, 45, 57, 57, 81, 57, 57, 57, 79, + 79, 80, 57, 57, 57, 77, 57, 83, 79, 79, + 79, 79, 79, 76, 75, 74, 73, 63, 62, 61, + 54, 49, 48, 57, 57, 66, 67, 46, 43, 41, + + 85, 37, 37, 68, 85, 85, 69, 85, 85, 85, + 85, 70, 85, 85, 71, 85, 72, 31, 31, 31, + 31, 35, 35, 35, 35, 36, 36, 36, 36, 58, + 85, 58, 58, 64, 85, 85, 64, 65, 65, 65, + 65, 9, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85 + } ; + +static yyconst short int yy_chk[175] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 4, 3, 4, 11, 11, 12, 15, + 15, 17, 22, 3, 4, 23, 25, 27, 22, 38, + 38, 42, 42, 89, 27, 80, 23, 25, 77, 12, + 66, 66, 17, 26, 26, 75, 26, 26, 26, 67, + 67, 74, 26, 26, 26, 62, 26, 78, 78, 79, + 79, 83, 83, 60, 51, 50, 48, 30, 29, 28, + 24, 21, 20, 26, 26, 34, 34, 18, 16, 14, + + 9, 8, 7, 34, 0, 0, 34, 0, 0, 0, + 0, 34, 0, 0, 34, 0, 34, 86, 86, 86, + 86, 87, 87, 87, 87, 88, 88, 88, 88, 90, + 0, 90, 90, 91, 0, 0, 91, 92, 92, 92, + 92, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "ssl_expr_scan.l" +#define INITIAL 0 +/* _ _ +** _ __ ___ ___ __| | ___ ___| | +** | '_ ` _ \ / _ \ / _` | / __/ __| | +** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL +** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/ +** |_____| +** ssl_expr_scan.l +** Expression Scanner +*/ +/* ==================================================================== + * Copyright (c) 1998-1999 Ralf S. Engelschall. 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. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by + * Ralf S. Engelschall <rse@engelschall.com> for use in the + * mod_ssl project (http://www.modssl.org/)." + * + * 4. The names "mod_ssl" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * rse@engelschall.com. + * + * 5. Products derived from this software may not be called "mod_ssl" + * nor may "mod_ssl" appear in their names without prior + * written permission of Ralf S. Engelschall. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by + * Ralf S. Engelschall <rse@engelschall.com> for use in the + * mod_ssl project (http://www.modssl.org/)." + * + * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``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 RALF S. ENGELSCHALL OR + * HIS 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, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* ``Killing for peace is +like fucking for virginity.'' +-- Unknown */ +/* _________________________________________________________________ +** +** Expression Scanner +** _________________________________________________________________ +*/ +#line 73 "ssl_expr_scan.l" +#include "mod_ssl.h" + +#include "ssl_expr_parse.h" + +#define YY_NO_UNPUT 1 +int yyinput(char *buf, int max_size); + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + (result = yyinput(buf, max_size)) + +#define MAX_STR_LEN 2048 +/* %option stack */ +#define YY_NEVER_INTERACTIVE 1 +#define str 1 + +#define regex 2 +#define regex_flags 3 + +#line 537 "lex.ssl_expr_yy.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include <stdlib.h> +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 94 "ssl_expr_scan.l" + + + char caStr[MAX_STR_LEN]; + char *cpStr = NULL; + char caRegex[MAX_STR_LEN]; + char *cpRegex = NULL; + char cRegexDel = NUL; + + /* + * Whitespaces + */ +#line 700 "lex.ssl_expr_yy.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 86 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 85 ); + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 105 "ssl_expr_scan.l" +{ + /* NOP */ +} + YY_BREAK +/* + * C-style strings ("...") + */ +case 2: +YY_RULE_SETUP +#line 112 "ssl_expr_scan.l" +{ + cpStr = caStr; + BEGIN(str); +} + YY_BREAK +case 3: +YY_RULE_SETUP +#line 116 "ssl_expr_scan.l" +{ + BEGIN(INITIAL); + *cpStr = NUL; + yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caStr); + return T_STRING; +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 122 "ssl_expr_scan.l" +{ + yyerror("Unterminated string"); +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 125 "ssl_expr_scan.l" +{ + int result; + + (void)sscanf(yytext+1, "%o", &result); + if (result > 0xff) + yyerror("Escape sequence out of bound"); + else + *cpStr++ = result; +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 134 "ssl_expr_scan.l" +{ + yyerror("Bad escape sequence"); +} + YY_BREAK +case 7: +YY_RULE_SETUP +#line 137 "ssl_expr_scan.l" +{ *cpStr++ = '\n'; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 138 "ssl_expr_scan.l" +{ *cpStr++ = '\r'; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 139 "ssl_expr_scan.l" +{ *cpStr++ = '\t'; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 140 "ssl_expr_scan.l" +{ *cpStr++ = '\b'; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 141 "ssl_expr_scan.l" +{ *cpStr++ = '\f'; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 142 "ssl_expr_scan.l" +{ + *cpStr++ = yytext[1]; +} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 145 "ssl_expr_scan.l" +{ + char *cp = yytext; + while (*cp != NUL) + *cpStr++ = *cp++; +} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 150 "ssl_expr_scan.l" +{ + *cpStr++ = yytext[1]; +} + YY_BREAK +/* + * Regular Expression + */ +case 15: +YY_RULE_SETUP +#line 157 "ssl_expr_scan.l" +{ + cRegexDel = yytext[1]; + cpRegex = caRegex; + BEGIN(regex); +} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 162 "ssl_expr_scan.l" +{ + if (yytext[0] == cRegexDel) { + *cpRegex = NUL; + BEGIN(regex_flags); + } + else { + *cpRegex++ = yytext[0]; + } +} + YY_BREAK +case 17: +YY_RULE_SETUP +#line 171 "ssl_expr_scan.l" +{ + yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex); + BEGIN(INITIAL); + return T_REGEX_I; +} + YY_BREAK +case 18: +YY_RULE_SETUP +#line 176 "ssl_expr_scan.l" +{ + yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex); + yyless(0); + BEGIN(INITIAL); + return T_REGEX; +} + YY_BREAK +case YY_STATE_EOF(regex_flags): +#line 182 "ssl_expr_scan.l" +{ + yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, caRegex); + BEGIN(INITIAL); + return T_REGEX; +} + YY_BREAK +/* + * Operators + */ +case 19: +YY_RULE_SETUP +#line 191 "ssl_expr_scan.l" +{ return T_OP_EQ; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 192 "ssl_expr_scan.l" +{ return T_OP_EQ; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 193 "ssl_expr_scan.l" +{ return T_OP_NE; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 194 "ssl_expr_scan.l" +{ return T_OP_NE; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 195 "ssl_expr_scan.l" +{ return T_OP_LT; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 196 "ssl_expr_scan.l" +{ return T_OP_LT; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 197 "ssl_expr_scan.l" +{ return T_OP_LE; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 198 "ssl_expr_scan.l" +{ return T_OP_LE; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 199 "ssl_expr_scan.l" +{ return T_OP_GT; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 200 "ssl_expr_scan.l" +{ return T_OP_GT; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 201 "ssl_expr_scan.l" +{ return T_OP_GE; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 202 "ssl_expr_scan.l" +{ return T_OP_GE; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 203 "ssl_expr_scan.l" +{ return T_OP_REG; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 204 "ssl_expr_scan.l" +{ return T_OP_NRE; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 205 "ssl_expr_scan.l" +{ return T_OP_AND; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 206 "ssl_expr_scan.l" +{ return T_OP_AND; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 207 "ssl_expr_scan.l" +{ return T_OP_OR; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 208 "ssl_expr_scan.l" +{ return T_OP_OR; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 209 "ssl_expr_scan.l" +{ return T_OP_NOT; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 210 "ssl_expr_scan.l" +{ return T_OP_NOT; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 211 "ssl_expr_scan.l" +{ return T_OP_IN; } + YY_BREAK +/* + * Functions + */ +case 40: +YY_RULE_SETUP +#line 216 "ssl_expr_scan.l" +{ return T_FUNC_FILE; } + YY_BREAK +/* + * Specials + */ +case 41: +YY_RULE_SETUP +#line 221 "ssl_expr_scan.l" +{ return T_TRUE; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 222 "ssl_expr_scan.l" +{ return T_FALSE; } + YY_BREAK +/* + * Digits + */ +case 43: +YY_RULE_SETUP +#line 227 "ssl_expr_scan.l" +{ + yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, yytext); + return T_DIGIT; +} + YY_BREAK +/* + * Identifiers + */ +case 44: +YY_RULE_SETUP +#line 235 "ssl_expr_scan.l" +{ + yylval.cpVal = ap_pstrdup(ssl_expr_info.pool, yytext); + return T_ID; +} + YY_BREAK +/* + * Anything else is returned as is... + */ +case 45: +YY_RULE_SETUP +#line 243 "ssl_expr_scan.l" +{ + return yytext[0]; +} + YY_BREAK +case 46: +YY_RULE_SETUP +#line 247 "ssl_expr_scan.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 1100 "lex.ssl_expr_yy.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(str): +case YY_STATE_EOF(regex): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 86 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 86 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 85); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 247 "ssl_expr_scan.l" + + +int yyinput(char *buf, int max_size) +{ + int n; + + if ((n = MIN(max_size, ssl_expr_info.inputbuf + + ssl_expr_info.inputlen + - ssl_expr_info.inputptr)) <= 0) + return YY_NULL; + memcpy(buf, ssl_expr_info.inputptr, n); + ssl_expr_info.inputptr += n; + return n; +} + diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l index a6352724412..c111b41bdf7 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l +++ b/usr.sbin/httpd/src/modules/ssl/ssl_expr_scan.l @@ -1,8 +1,8 @@ /* _ _ ** _ __ ___ ___ __| | ___ ___| | ** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL +** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/ ** |_____| ** ssl_expr_scan.l ** Expression Scanner @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util.c b/usr.sbin/httpd/src/modules/ssl/ssl_util.c index dd49b134be0..3159600be1b 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_util.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_util.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_util.c ** Utility Functions @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -121,8 +121,8 @@ char *ssl_util_vhostid(pool *p, server_rec *s) char *id; SSLSrvConfigRec *sc; char *host; - int port; - + unsigned int port; + host = s->server_hostname; if (s->port != 0) port = s->port; @@ -133,7 +133,7 @@ char *ssl_util_vhostid(pool *p, server_rec *s) else port = DEFAULT_HTTP_PORT; } - id = ap_psprintf(p, "%s:%d", host, port); + id = ap_psprintf(p, "%s:%u", host, port); return id; } @@ -202,13 +202,48 @@ int ssl_util_ppopen_child(void *cmd, child_info *pinfo) { int child_pid = 1; + /* + * Prepare for exec + */ ap_cleanup_for_exec(); #ifdef SIGHUP signal(SIGHUP, SIG_IGN); #endif -#if defined(__EMX__) + + /* + * Exec() the child program + */ +#if defined(WIN32) + /* MS Windows */ + { + char pCommand[MAX_STRING_LEN]; + STARTUPINFO si; + PROCESS_INFORMATION pi; + + ap_snprintf(pCommand, sizeof(pCommand), "%s /C %s", SHELL_PATH, cmd); + + memset(&si, 0, sizeof(si)); + memset(&pi, 0, sizeof(pi)); + + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; + si.wShowWindow = SW_HIDE; + si.hStdInput = pinfo->hPipeInputRead; + si.hStdOutput = pinfo->hPipeOutputWrite; + si.hStdError = pinfo->hPipeErrorWrite; + + if (CreateProcess(NULL, pCommand, NULL, NULL, TRUE, 0, + environ, NULL, &si, &pi)) { + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + child_pid = pi.dwProcessId; + } + } +#elif defined(OS2) + /* IBM OS/2 */ execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); #else + /* Standard Unix */ execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); #endif return (child_pid); @@ -261,6 +296,46 @@ BOOL ssl_util_path_check(ssl_pathcheck_t pcm, char *path) return TRUE; } +ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey) +{ + ssl_algo_t t; + + t = SSL_ALGO_UNKNOWN; + if (pCert != NULL) + pKey = X509_get_pubkey(pCert); + if (pKey != NULL) { + switch (EVP_PKEY_type(pKey->type)) { + case EVP_PKEY_RSA: + t = SSL_ALGO_RSA; + break; + case EVP_PKEY_DSA: + t = SSL_ALGO_DSA; + break; + default: + break; + } + } + return t; +} + +char *ssl_util_algotypestr(ssl_algo_t t) +{ + char *cp; + + cp = "UNKNOWN"; + switch (t) { + case SSL_ALGO_RSA: + cp = "RSA"; + break; + case SSL_ALGO_DSA: + cp = "DSA"; + break; + default: + break; + } + return cp; +} + char *ssl_util_ptxtsub( pool *p, const char *cpLine, const char *cpMatch, char *cpSubst) { @@ -316,7 +391,7 @@ char *ssl_util_ptxtsub( /* _________________________________________________________________ ** -** Special Functions for Win32/SSLeay +** Special Functions for Win32/OpenSSL ** _________________________________________________________________ */ diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c index 029335f88ba..4340f88ffad 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.c @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_util_sdbm.c ** Built-in Simple DBM @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h index 076b8be5cdc..def1d3d94f7 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h +++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_sdbm.h @@ -1,8 +1,8 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_util_sdbm.c ** Built-in Simple DBM (Header) @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c index 2d8632ae355..18a83ac8d5f 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c +++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.c @@ -1,11 +1,11 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_util_ssl.c -** Additional Utility Functions for SSLeay +** Additional Utility Functions for OpenSSL */ /* ==================================================================== @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -64,7 +64,7 @@ /* _________________________________________________________________ ** -** Additional High-Level Functions for SSLeay +** Additional High-Level Functions for OpenSSL ** _________________________________________________________________ */ @@ -73,9 +73,9 @@ int SSL_get_app_data2_idx(void) static int app_data2_idx = -1; if (app_data2_idx < 0) { - app_data2_idx = SSL_get_ex_new_index(0, + app_data2_idx = SSL_get_ex_new_index(0, "Second Application Data for SSL", NULL, NULL, NULL); - app_data2_idx = SSL_get_ex_new_index(0, + app_data2_idx = SSL_get_ex_new_index(0, "Second Application Data for SSL", NULL, NULL, NULL); } return(app_data2_idx); @@ -92,3 +92,367 @@ void SSL_set_app_data2(SSL *ssl, void *arg) return; } +/* _________________________________________________________________ +** +** High-Level Certificate / Private Key Loading +** _________________________________________________________________ +*/ + +X509 *SSL_read_X509(FILE *fp, X509 **x509, int (*cb)()) +{ + X509 *rc; + BIO *bioS; + BIO *bioF; + + /* 1. try PEM (= DER+Base64+headers) */ +#if SSL_LIBRARY_VERSION < 0x00904000 + rc = PEM_read_X509(fp, x509, cb); +#else + rc = PEM_read_X509(fp, x509, cb, NULL); +#endif + if (rc == NULL) { + /* 2. try DER+Base64 */ + fseek(fp, 0L, SEEK_SET); + if ((bioS = BIO_new(BIO_s_fd())) == NULL) + return NULL; + BIO_set_fd(bioS, fileno(fp), BIO_NOCLOSE); + if ((bioF = BIO_new(BIO_f_base64())) == NULL) { + BIO_free(bioS); + return NULL; + } + bioS = BIO_push(bioF, bioS); + rc = d2i_X509_bio(bioS, NULL); + BIO_free_all(bioS); + if (rc == NULL) { + /* 3. try plain DER */ + fseek(fp, 0L, SEEK_SET); + if ((bioS = BIO_new(BIO_s_fd())) == NULL) + return NULL; + BIO_set_fd(bioS, fileno(fp), BIO_NOCLOSE); + rc = d2i_X509_bio(bioS, NULL); + BIO_free(bioS); + } + } + if (rc != NULL && x509 != NULL) { + if (*x509 != NULL) + X509_free(*x509); + *x509 = rc; + } + return rc; +} + +static EVP_PKEY *d2i_PrivateKey_bio(BIO *bio, EVP_PKEY *key) +{ + return ((EVP_PKEY *)ASN1_d2i_bio( + (char *(*)())EVP_PKEY_new, + (char *(*)())d2i_PrivateKey, + (bio), (unsigned char **)(key))); +} + +EVP_PKEY *SSL_read_PrivateKey(FILE *fp, EVP_PKEY **key, int (*cb)()) +{ + EVP_PKEY *rc; + BIO *bioS; + BIO *bioF; + + /* 1. try PEM (= DER+Base64+headers) */ +#if SSL_LIBRARY_VERSION < 0x00904000 + rc = PEM_read_PrivateKey(fp, key, cb); +#else + rc = PEM_read_PrivateKey(fp, key, cb, NULL); +#endif + if (rc == NULL) { + /* 2. try DER+Base64 */ + fseek(fp, 0L, SEEK_SET); + if ((bioS = BIO_new(BIO_s_fd())) == NULL) + return NULL; + BIO_set_fd(bioS, fileno(fp), BIO_NOCLOSE); + if ((bioF = BIO_new(BIO_f_base64())) == NULL) { + BIO_free(bioS); + return NULL; + } + bioS = BIO_push(bioF, bioS); + rc = d2i_PrivateKey_bio(bioS, NULL); + BIO_free_all(bioS); + if (rc == NULL) { + /* 3. try plain DER */ + fseek(fp, 0L, SEEK_SET); + if ((bioS = BIO_new(BIO_s_fd())) == NULL) + return NULL; + BIO_set_fd(bioS, fileno(fp), BIO_NOCLOSE); + rc = d2i_PrivateKey_bio(bioS, NULL); + BIO_free(bioS); + } + } + if (rc != NULL && key != NULL) { + if (*key != NULL) + EVP_PKEY_free(*key); + *key = rc; + } + return rc; +} + +/* _________________________________________________________________ +** +** Smart shutdown +** _________________________________________________________________ +*/ + +int SSL_smart_shutdown(SSL *ssl) +{ + int i; + int rc; + + /* + * Repeat the calls, because SSL_shutdown internally dispatches through a + * little state machine. Usually only one or two interation should be + * needed, so we restrict the total number of restrictions in order to + * avoid process hangs in case the client played bad with the socket + * connection and OpenSSL cannot recognize it. + */ + rc = 0; + for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) { + if ((rc = SSL_shutdown(ssl))) + break; + } + return rc; +} + +/* _________________________________________________________________ +** +** Certificate Revocation List (CRL) Storage +** _________________________________________________________________ +*/ + +X509_STORE *SSL_X509_STORE_create(char *cpFile, char *cpPath) +{ + X509_STORE *pStore; + X509_LOOKUP *pLookup; + + if (cpFile == NULL && cpPath == NULL) + return NULL; + if ((pStore = X509_STORE_new()) == NULL) + return NULL; + if (cpFile != NULL) { + if ((pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file())) == NULL) { + X509_STORE_free(pStore); + return NULL; + } + X509_LOOKUP_load_file(pLookup, cpFile, X509_FILETYPE_PEM); + } + if (cpPath != NULL) { + if ((pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir())) == NULL) { + X509_STORE_free(pStore); + return NULL; + } + X509_LOOKUP_add_dir(pLookup, cpPath, X509_FILETYPE_PEM); + } + return pStore; +} + +int SSL_X509_STORE_lookup(X509_STORE *pStore, int nType, + X509_NAME *pName, X509_OBJECT *pObj) +{ + X509_STORE_CTX pStoreCtx; + int rc; + + X509_STORE_CTX_init(&pStoreCtx, pStore, NULL, NULL); + rc = X509_STORE_get_by_subject(&pStoreCtx, nType, pName, pObj); + X509_STORE_CTX_cleanup(&pStoreCtx); + return rc; +} + +/* _________________________________________________________________ +** +** Cipher Suite Spec String Creation +** _________________________________________________________________ +*/ + +char *SSL_make_ciphersuite(pool *p, SSL *ssl) +{ + STACK_OF(SSL_CIPHER) *sk; + SSL_CIPHER *c; + int i; + int l; + char *cpCipherSuite; + char *cp; + + if (ssl == NULL) + return ""; + sk = SSL_get_ciphers(ssl); + if (sk == NULL) + return ""; + l = 0; + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + l += strlen(c->name+2+1); + } + cpCipherSuite = (char *)ap_palloc(p, l+1); + cp = cpCipherSuite; + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + l = strlen(c->name); + memcpy(cp, c->name, l); + cp += l; + *cp++ = '/'; + *cp++ = (c->valid == 1 ? '1' : '0'); + *cp++ = ':'; + } + *cp = NUL; + return cpCipherSuite; +} + +/* _________________________________________________________________ +** +** Certificate Checks +** _________________________________________________________________ +*/ + +/* check whether cert contains extended key usage with a SGC tag */ +BOOL SSL_X509_isSGC(X509 *cert) +{ + X509_EXTENSION *ext; + int ext_nid; + STACK *sk; + BOOL is_sgc; + int idx; + int i; + + is_sgc = FALSE; + idx = X509_get_ext_by_NID(cert, NID_ext_key_usage, -1); + if (idx >= 0) { + ext = X509_get_ext(cert, idx); + if ((sk = (STACK *)X509V3_EXT_d2i(ext)) != NULL) { + for (i = 0; i < sk_num(sk); i++) { + ext_nid = OBJ_obj2nid((ASN1_OBJECT *)sk_value(sk, i)); + if (ext_nid == NID_ms_sgc || ext_nid == NID_ns_sgc) { + is_sgc = TRUE; + break; + } + } + } + } + return is_sgc; +} + +/* retrieve basic constraints ingredients */ +BOOL SSL_X509_getBC(X509 *cert, int *ca, int *pathlen) +{ + X509_EXTENSION *ext; + BASIC_CONSTRAINTS *bc; + int idx; + BIGNUM *bn = NULL; + char *cp; + + if ((idx = X509_get_ext_by_NID(cert, NID_basic_constraints, -1)) < 0) + return FALSE; + ext = X509_get_ext(cert, idx); + if (ext == NULL) + return FALSE; + if ((bc = (BASIC_CONSTRAINTS *)X509V3_EXT_d2i(ext)) == NULL) + return FALSE; + *ca = bc->ca; + *pathlen = -1 /* unlimited */; + if (bc->pathlen != NULL) { + if ((bn = ASN1_INTEGER_to_BN(bc->pathlen, NULL)) == NULL) + return FALSE; + if ((cp = BN_bn2dec(bn)) == NULL) + return FALSE; + *pathlen = atoi(cp); + free(cp); + BN_free(bn); + } + BASIC_CONSTRAINTS_free(bc); + return TRUE; +} + +/* retrieve subject CommonName of certificate */ +BOOL SSL_X509_getCN(pool *p, X509 *xs, char **cppCN) +{ + X509_NAME *xsn; + X509_NAME_ENTRY *xsne; + int i, nid; + + xsn = X509_get_subject_name(xs); + for (i = 0; i < sk_X509_NAME_ENTRY_num(xsn->entries); i++) { + xsne = sk_X509_NAME_ENTRY_value(xsn->entries, i); + nid = OBJ_obj2nid(xsne->object); + if (nid == NID_commonName) { + *cppCN = ap_palloc(p, xsne->value->length+1); + ap_cpystrn(*cppCN, (char *)xsne->value->data, xsne->value->length+1); + (*cppCN)[xsne->value->length] = NUL; + return TRUE; + } + } + return FALSE; +} + +/* _________________________________________________________________ +** +** Extra Server Certificate Chain Support +** _________________________________________________________________ +*/ + +/* + * Read a file that optionally contains the server certificate in PEM + * format, possibly followed by a sequence of CA certificates that + * should be sent to the peer in the SSL Certificate message. + */ +int SSL_CTX_use_certificate_chain( + SSL_CTX *ctx, char *file, int skipfirst, int (*cb)()) +{ + BIO *bio; + X509 *x509; + unsigned long err; + int n; + + if ((bio = BIO_new(BIO_s_file_internal())) == NULL) + return -1; + if (BIO_read_filename(bio, file) <= 0) { + BIO_free(bio); + return -1; + } + /* optionally skip a leading server certificate */ + if (skipfirst) { +#if SSL_LIBRARY_VERSION < 0x00904000 + if ((x509 = PEM_read_bio_X509(bio, NULL, cb)) == NULL) { +#else + if ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) == NULL) { +#endif + BIO_free(bio); + return -1; + } + X509_free(x509); + } + /* free a perhaps already configured extra chain */ + if (ctx->extra_certs != NULL) { + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + } + /* create new extra chain by loading the certs */ + n = 0; +#if SSL_LIBRARY_VERSION < 0x00904000 + while ((x509 = PEM_read_bio_X509(bio, NULL, cb)) != NULL) { +#else + while ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) { +#endif + if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) { + X509_free(x509); + BIO_free(bio); + return -1; + } + n++; + } + /* Make sure that only the error is just an EOF */ + if ((err = ERR_peek_error()) > 0) { + if (!( ERR_GET_LIB(err) == ERR_LIB_PEM + && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { + BIO_free(bio); + return -1; + } + while (ERR_get_error() > 0) ; + } + BIO_free(bio); + return n; +} + diff --git a/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h index 01e0cbe7f86..2b5f3ce6d92 100644 --- a/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h +++ b/usr.sbin/httpd/src/modules/ssl/ssl_util_ssl.h @@ -1,11 +1,11 @@ /* _ _ -** _ __ ___ ___ __| | ___ ___| | -** | '_ ` _ \ / _ \ / _` | / __/ __| | -** | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to SSLeay -** |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.engelschall.com/sw/mod_ssl/ +** _ __ ___ ___ __| | ___ ___| | mod_ssl +** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL +** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org +** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org ** |_____| ** ssl_util_ssl.h -** Additional Utility Functions for SSLeay +** Additional Utility Functions for OpenSSL */ /* ==================================================================== @@ -27,7 +27,7 @@ * software must display the following acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * 4. The names "mod_ssl" must not be used to endorse or promote * products derived from this software without prior written @@ -42,7 +42,7 @@ * acknowledgment: * "This product includes software developed by * Ralf S. Engelschall <rse@engelschall.com> for use in the - * mod_ssl project (http://www.engelschall.com/sw/mod_ssl/)." + * mod_ssl project (http://www.modssl.org/)." * * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -68,14 +68,11 @@ #ifdef OPENSSL_VERSION_NUMBER #define SSL_LIBRARY_VERSION OPENSSL_VERSION_NUMBER #define SSL_LIBRARY_NAME "OpenSSL" -#else -#ifdef SSLEAY_VERSION_NUMBER -#define SSL_LIBRARY_VERSION SSLEAY_VERSION_NUMBER -#define SSL_LIBRARY_NAME "SSLeay" +#define SSL_LIBRARY_TEXT OPENSSL_VERSION_TEXT #else #define SSL_LIBRARY_VERSION 0x0000 #define SSL_LIBRARY_NAME "OtherSSL" -#endif +#define SSL_LIBRARY_TEXT "OtherSSL 0.0.0 00 XXX 0000" #endif /* @@ -89,8 +86,18 @@ /* * Additional Functions */ -int SSL_get_app_data2_idx(void); -void *SSL_get_app_data2(SSL *); -void SSL_set_app_data2(SSL *, void *); +int SSL_get_app_data2_idx(void); +void *SSL_get_app_data2(SSL *); +void SSL_set_app_data2(SSL *, void *); +X509 *SSL_read_X509(FILE *, X509 **, int (*)()); +EVP_PKEY *SSL_read_PrivateKey(FILE *, EVP_PKEY **, int (*)()); +int SSL_smart_shutdown(SSL *ssl); +X509_STORE *SSL_X509_STORE_create(char *, char *); +int SSL_X509_STORE_lookup(X509_STORE *, int, X509_NAME *, X509_OBJECT *); +char *SSL_make_ciphersuite(pool *, SSL *); +BOOL SSL_X509_isSGC(X509 *); +BOOL SSL_X509_getBC(X509 *, int *, int *); +BOOL SSL_X509_getCN(pool *, X509 *, char **); +int SSL_CTX_use_certificate_chain(SSL_CTX *, char *, int, int (*)()); #endif /* SSL_UTIL_SSL_H */ diff --git a/usr.sbin/httpd/src/modules/standard/mod_access.c b/usr.sbin/httpd/src/modules/standard/mod_access.c index f681e95501f..6179510451c 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_access.c +++ b/usr.sbin/httpd/src/modules/standard/mod_access.c @@ -202,7 +202,7 @@ static const char *allow_cmd(cmd_parms *cmd, void *dv, char *from, char *where) mask = htonl(mask); } a->x.ip.mask = mask; - + a->x.ip.net = (a->x.ip.net & mask); /* pjr - This fixes PR 4770 */ } else if (ap_isdigit(*where) && is_ip(where)) { /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */ diff --git a/usr.sbin/httpd/src/modules/standard/mod_alias.c b/usr.sbin/httpd/src/modules/standard/mod_alias.c index b7f5ba3d96c..f92d982d233 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_alias.c +++ b/usr.sbin/httpd/src/modules/standard/mod_alias.c @@ -300,7 +300,7 @@ static char *try_alias_list(request_rec *r, array_header *aliases, int doesc, in int l; if (p->regexp) { - if (!regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm, 0)) { + if (!ap_regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm, 0)) { if (p->real) { found = ap_pregsub(r->pool, p->real, r->uri, p->regexp->re_nsub + 1, regm); diff --git a/usr.sbin/httpd/src/modules/standard/mod_auth.c b/usr.sbin/httpd/src/modules/standard/mod_auth.c index 11df5645926..e07dc453733 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_auth.c +++ b/usr.sbin/httpd/src/modules/standard/mod_auth.c @@ -74,9 +74,6 @@ #include "http_core.h" #include "http_log.h" #include "http_protocol.h" -#if defined(HAVE_CRYPT_H) -#include <crypt.h> -#endif typedef struct auth_config_struct { char *auth_pwfile; @@ -203,6 +200,7 @@ static int authenticate_basic_user(request_rec *r) conn_rec *c = r->connection; const char *sent_pw; char *real_pw; + char *invalid_pw; int res; if ((res = ap_get_basic_auth_pw(r, &sent_pw))) @@ -219,10 +217,11 @@ static int authenticate_basic_user(request_rec *r) ap_note_basic_auth_failure(r); return AUTH_REQUIRED; } - /* anyone know where the prototype for crypt is? */ - if (strcmp(real_pw, (char *) crypt(sent_pw, real_pw))) { + invalid_pw = ap_validate_password(sent_pw, real_pw); + if (invalid_pw != NULL) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "user %s: password mismatch: %s", c->user, r->uri); + "user %s: authentication failure for \"%s\": %s", + c->user, r->uri, invalid_pw); ap_note_basic_auth_failure(r); return AUTH_REQUIRED; } diff --git a/usr.sbin/httpd/src/modules/standard/mod_auth_db.c b/usr.sbin/httpd/src/modules/standard/mod_auth_db.c index 5571f7b51c8..e09e8eb6c4b 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_auth_db.c +++ b/usr.sbin/httpd/src/modules/standard/mod_auth_db.c @@ -226,6 +226,7 @@ static int db_authenticate_basic_user(request_rec *r) conn_rec *c = r->connection; const char *sent_pw; char *real_pw, *colon_pw; + char *invalid_pw; int res; if ((res = ap_get_basic_auth_pw(r, &sent_pw))) @@ -244,12 +245,14 @@ static int db_authenticate_basic_user(request_rec *r) } /* Password is up to first : if exists */ colon_pw = strchr(real_pw, ':'); - if (colon_pw) + if (colon_pw) { *colon_pw = '\0'; - /* anyone know where the prototype for crypt is? */ - if (strcmp(real_pw, (char *) crypt(sent_pw, real_pw))) { + } + invalid_pw = ap_validate_password(sent_pw, real_pw); + if (invalid_pw != NULL) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "DB user %s: password mismatch: %s", c->user, r->uri); + "DB user %s: authentication failure for \"%s\": %s", + c->user, r->uri, invalid_pw); ap_note_basic_auth_failure(r); return AUTH_REQUIRED; } diff --git a/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c b/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c index a91838b4c2b..bb32361a6d9 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c +++ b/usr.sbin/httpd/src/modules/standard/mod_auth_dbm.c @@ -74,7 +74,12 @@ #include "http_core.h" #include "http_log.h" #include "http_protocol.h" +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) \ + && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 +#include <db1/ndbm.h> +#else #include <ndbm.h> +#endif /* * Module definition information - the part between the -START and -END @@ -208,6 +213,7 @@ static int dbm_authenticate_basic_user(request_rec *r) conn_rec *c = r->connection; const char *sent_pw; char *real_pw, *colon_pw; + char *invalid_pw; int res; if ((res = ap_get_basic_auth_pw(r, &sent_pw))) @@ -226,12 +232,14 @@ static int dbm_authenticate_basic_user(request_rec *r) } /* Password is up to first : if exists */ colon_pw = strchr(real_pw, ':'); - if (colon_pw) + if (colon_pw) { *colon_pw = '\0'; - /* anyone know where the prototype for crypt is? */ - if (strcmp(real_pw, (char *) crypt(sent_pw, real_pw))) { + } + invalid_pw = ap_validate_password(sent_pw, real_pw); + if (invalid_pw != NULL) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, - "user %s: password mismatch: %s", c->user, r->uri); + "DBM user %s: authentication failure for \"%s\": %s", + c->user, r->uri, invalid_pw); ap_note_basic_auth_failure(r); return AUTH_REQUIRED; } diff --git a/usr.sbin/httpd/src/modules/standard/mod_autoindex.c b/usr.sbin/httpd/src/modules/standard/mod_autoindex.c index 10436261aff..9c28dc40864 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_autoindex.c +++ b/usr.sbin/httpd/src/modules/standard/mod_autoindex.c @@ -72,6 +72,7 @@ #include "http_log.h" #include "http_main.h" #include "util_script.h" +#include "fnmatch.h" module MODULE_VAR_EXPORT autoindex_module; @@ -131,6 +132,13 @@ struct item { char *data; }; +typedef struct ai_desc_t { + char *pattern; + char *description; + int full_path; + int wildcards; +} ai_desc_t; + typedef struct autoindex_config_struct { char *default_icon; @@ -143,8 +151,12 @@ typedef struct autoindex_config_struct { int icon_height; char *default_order; - array_header *icon_list, *alt_list, *desc_list, *ign_list; - array_header *hdr_list, *rdme_list; + array_header *icon_list; + array_header *alt_list; + array_header *desc_list; + array_header *ign_list; + array_header *hdr_list; + array_header *rdme_list; } autoindex_config_rec; @@ -180,7 +192,7 @@ static ap_inline int is_parent(const char *name) */ static void emit_preamble(request_rec *r, char *title) { - ap_rvputs(r, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + ap_rvputs(r, DOCTYPE_HTML_3_2, "<HTML>\n <HEAD>\n <TITLE>Index of ", title, "</TITLE>\n </HEAD>\n <BODY>\n", NULL); } @@ -257,10 +269,48 @@ static const char *add_icon(cmd_parms *cmd, void *d, char *icon, char *to) return NULL; } +/* + * Add description text for a filename pattern. If the pattern has + * wildcards already (or we need to add them), add leading and + * trailing wildcards to it to ensure substring processing. If the + * pattern contains a '/' anywhere, force wildcard matching mode, + * add a slash to the prefix so that "bar/bletch" won't be matched + * by "foobar/bletch", and make a note that there's a delimiter; + * the matching routine simplifies to just the actual filename + * whenever it can. This allows definitions in parent directories + * to be made for files in subordinate ones using relative paths. + */ + +/* + * Absent a strcasestr() function, we have to force wildcards on + * systems for which "AAA" and "aaa" mean the same file. + */ +#ifdef CASE_BLIND_FILESYSTEM +#define WILDCARDS_REQUIRED 1 +#else +#define WILDCARDS_REQUIRED 0 +#endif + static const char *add_desc(cmd_parms *cmd, void *d, char *desc, char *to) { - push_item(((autoindex_config_rec *) d)->desc_list, cmd->info, to, - cmd->path, desc); + autoindex_config_rec *dcfg = (autoindex_config_rec *) d; + ai_desc_t *desc_entry; + char *prefix = ""; + + desc_entry = (ai_desc_t *) ap_push_array(dcfg->desc_list); + desc_entry->full_path = (strchr(to, '/') == NULL) ? 0 : 1; + desc_entry->wildcards = (WILDCARDS_REQUIRED + || desc_entry->full_path + || ap_is_fnmatch(to)); + if (desc_entry->wildcards) { + prefix = desc_entry->full_path ? "*/" : "*"; + desc_entry->pattern = ap_pstrcat(dcfg->desc_list->pool, + prefix, to, "*", NULL); + } + else { + desc_entry->pattern = ap_pstrdup(dcfg->desc_list->pool, to); + } + desc_entry->description = ap_pstrdup(dcfg->desc_list->pool, desc); return NULL; } @@ -272,9 +322,6 @@ static const char *add_ignore(cmd_parms *cmd, void *d, char *ext) static const char *add_header(cmd_parms *cmd, void *d, char *name) { - if (strchr(name, '/')) { - return "HeaderName cannot contain a /"; - } push_item(((autoindex_config_rec *) d)->hdr_list, 0, NULL, cmd->path, name); return NULL; @@ -282,9 +329,6 @@ static const char *add_header(cmd_parms *cmd, void *d, char *name) static const char *add_readme(cmd_parms *cmd, void *d, char *name) { - if (strchr(name, '/')) { - return "ReadmeName cannot contain a /"; - } push_item(((autoindex_config_rec *) d)->rdme_list, 0, NULL, cmd->path, name); return NULL; @@ -410,8 +454,8 @@ static const char *add_opts(cmd_parms *cmd, void *d, const char *optstr) else { int width = atoi(&w[10]); - if (width < 1) { - return "NameWidth value must be greater than 1"; + if (width < 5) { + return "NameWidth value must be greater than 5"; } d_cfg->name_width = width; d_cfg->name_adjust = K_NOADJUST; @@ -530,7 +574,7 @@ static void *create_autoindex_config(pool *p, char *dummy) new->name_adjust = K_UNSET; new->icon_list = ap_make_array(p, 4, sizeof(struct item)); new->alt_list = ap_make_array(p, 4, sizeof(struct item)); - new->desc_list = ap_make_array(p, 4, sizeof(struct item)); + new->desc_list = ap_make_array(p, 4, sizeof(ai_desc_t)); new->ign_list = ap_make_array(p, 4, sizeof(struct item)); new->hdr_list = ap_make_array(p, 4, sizeof(struct item)); new->rdme_list = ap_make_array(p, 4, sizeof(struct item)); @@ -688,7 +732,6 @@ static char *find_item(request_rec *r, array_header *list, int path_only) #define find_icon(d,p,t) find_item(p,d->icon_list,t) #define find_alt(d,p,t) find_item(p,d->alt_list,t) -#define find_desc(d,p) find_item(p,d->desc_list,0) #define find_header(d,p) find_item(p,d->hdr_list,0) #define find_readme(d,p) find_item(p,d->rdme_list,0) @@ -707,6 +750,63 @@ static char *find_default_icon(autoindex_config_rec *d, char *bogus_name) return find_item(&r, d->icon_list, 1); } +/* + * Look through the list of pattern/description pairs and return the first one + * if any) that matches the filename in the request. If multiple patterns + * match, only the first one is used; since the order in the array is the + * same as the order in which directives were processed, earlier matching + * directives will dominate. + */ + +#ifdef CASE_BLIND_FILESYSTEM +#define MATCH_FLAGS FNM_CASE_BLIND +#else +#define MATCH_FLAGS 0 +#endif + +static char *find_desc(autoindex_config_rec *dcfg, request_rec *r) +{ + int i; + ai_desc_t *list = (ai_desc_t *) dcfg->desc_list->elts; + const char *filename_full = r->filename; + const char *filename_only; + const char *filename; + + /* + * If the filename includes a path, extract just the name itself + * for the simple matches. + */ + if ((filename_only = strrchr(filename_full, '/')) == NULL) { + filename_only = filename_full; + } + else { + filename_only++; + } + for (i = 0; i < dcfg->desc_list->nelts; ++i) { + ai_desc_t *tuple = &list[i]; + int found; + + /* + * Only use the full-path filename if the pattern contains '/'s. + */ + filename = (tuple->full_path) ? filename_full : filename_only; + /* + * Make the comparison using the cheapest method; only do + * wildcard checking if we must. + */ + if (tuple->wildcards) { + found = (ap_fnmatch(tuple->pattern, filename, MATCH_FLAGS) == 0); + } + else { + found = (strstr(filename, tuple->pattern) != NULL); + } + if (found) { + return tuple->description; + } + } + return NULL; +} + static int ignore_entry(autoindex_config_rec *d, char *path) { array_header *list = d->ign_list; @@ -758,99 +858,217 @@ static int ignore_entry(autoindex_config_rec *d, char *path) */ /* - * Look for the specified file, and pump it into the response stream if we - * find it. + * Elements of the emitted document: + * Preamble + * Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req + * succeeds for the (content_type == text/html) header file. + * Header file + * Emitted if found (and able). + * H1 tag line + * Emitted if a header file is NOT emitted. + * Directory stuff + * Always emitted. + * HR + * Emitted if FANCY_INDEXING is set. + * Readme file + * Emitted if found (and able). + * ServerSig + * Emitted if ServerSignature is not Off AND a readme file + * is NOT emitted. + * Postamble + * Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req + * succeeds for the (content_type == text/html) readme file. */ -static int insert_readme(char *name, char *readme_fname, char *title, - int hrule, int whichend, request_rec *r) + + +/* + * emit a plain text file + */ +static void do_emit_plain(request_rec *r, FILE *f) { - char *fn; - FILE *f; - struct stat finfo; - int plaintext = 0; - request_rec *rr; - autoindex_config_rec *cfg; - int autoindex_opts; - - cfg = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config, - &autoindex_module); - autoindex_opts = cfg->opts; - /* XXX: this is a load of crap, it needs to do a full sub_req_lookup_uri */ - fn = ap_make_full_path(r->pool, name, readme_fname); - fn = ap_pstrcat(r->pool, fn, ".html", NULL); - if (stat(fn, &finfo) == -1) { - /* A brief fake multiviews search for README.html */ - fn[strlen(fn) - 5] = '\0'; - if (stat(fn, &finfo) == -1) { - return 0; + char buf[IOBUFSIZE + 1]; + int i, n, c, ch; + + ap_rputs("<PRE>\n", r); + while (!feof(f)) { + do { + n = fread(buf, sizeof(char), IOBUFSIZE, f); } - plaintext = 1; - if (hrule) { - ap_rputs("<HR>\n", r); + while (n == -1 && ferror(f) && errno == EINTR); + if (n == -1 || n == 0) { + break; + } + buf[n] = '\0'; + c = 0; + while (c < n) { + for (i = c; i < n; i++) { + if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') { + break; + } + } + ch = buf[i]; + buf[i] = '\0'; + ap_rputs(&buf[c], r); + if (ch == '<') { + ap_rputs("<", r); + } + else if (ch == '>') { + ap_rputs(">", r); + } + else if (ch == '&') { + ap_rputs("&", r); + } + c = i + 1; } } - else if (hrule) { - ap_rputs("<HR>\n", r); - } - /* XXX: when the above is rewritten properly, this necessary security - * check will be redundant. -djg */ - rr = ap_sub_req_lookup_file(fn, r); - if (rr->status != HTTP_OK) { - ap_destroy_sub_req(rr); - return 0; - } - ap_destroy_sub_req(rr); - if (!(f = ap_pfopen(r->pool, fn, "r"))) { - return 0; + ap_rputs("</PRE>\n", r); +} + +/* + * Handle the preamble through the H1 tag line, inclusive. Locate + * the file with a subrequests. Process text/html documents by actually + * running the subrequest; text/xxx documents get copied verbatim, + * and any other content type is ignored. This means that a non-text + * document (such as HEADER.gif) might get multiviewed as the result + * instead of a text document, meaning nothing will be displayed, but + * oh well. + */ +static void emit_head(request_rec *r, char *header_fname, int suppress_amble, + char *title) +{ + FILE *f; + request_rec *rr = NULL; + int emit_amble = 1; + int emit_H1 = 1; + + /* + * If there's a header file, send a subrequest to look for it. If it's + * found and a text file, handle it -- otherwise fall through and + * pretend there's nothing there. + */ + if ((header_fname != NULL) + && (rr = ap_sub_req_lookup_uri(header_fname, r)) + && (rr->status == HTTP_OK) + && (rr->filename != NULL) + && S_ISREG(rr->finfo.st_mode)) { + /* + * Check for the two specific cases we allow: text/html and + * text/anything-else. The former is allowed to be processed for + * SSIs. + */ + if (rr->content_type != NULL) { + if (!strcasecmp(ap_field_noparam(r->pool, rr->content_type), + "text/html")) { + /* Hope everything will work... */ + emit_amble = 0; + emit_H1 = 0; + + if (! suppress_amble) { + emit_preamble(r, title); + } + /* + * If there's a problem running the subrequest, display the + * preamble if we didn't do it before -- the header file + * didn't get displayed. + */ + if (ap_run_sub_req(rr) != OK) { + /* It didn't work */ + emit_amble = suppress_amble; + emit_H1 = 1; + } + } + else if (!strncasecmp("text/", rr->content_type, 5)) { + /* + * If we can open the file, prefix it with the preamble + * regardless; since we'll be sending a <PRE> block around + * the file's contents, any HTML header it had won't end up + * where it belongs. + */ + if ((f = ap_pfopen(r->pool, rr->filename, "r")) != 0) { + emit_preamble(r, title); + emit_amble = 0; + do_emit_plain(r, f); + ap_pfclose(r->pool, f); + emit_H1 = 0; + } + } + } } - if ((whichend == FRONT_MATTER) - && (!(autoindex_opts & SUPPRESS_PREAMBLE))) { + + if (emit_amble) { emit_preamble(r, title); } - if (!plaintext) { - ap_send_fd(f, r); + if (emit_H1) { + ap_rvputs(r, "<H1>Index of ", title, "</H1>\n", NULL); } - else { - char buf[IOBUFSIZE + 1]; - int i, n, c, ch; - ap_rputs("<PRE>\n", r); - while (!feof(f)) { - do { - n = fread(buf, sizeof(char), IOBUFSIZE, f); - } - while (n == -1 && ferror(f) && errno == EINTR); - if (n == -1 || n == 0) { - break; - } - buf[n] = '\0'; - c = 0; - while (c < n) { - for (i = c; i < n; i++) { - if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') { - break; - } - } - ch = buf[i]; - buf[i] = '\0'; - ap_rputs(&buf[c], r); - if (ch == '<') { - ap_rputs("<", r); - } - else if (ch == '>') { - ap_rputs(">", r); + if (rr != NULL) { + ap_destroy_sub_req(rr); + } +} + + +/* + * Handle the Readme file through the postamble, inclusive. Locate + * the file with a subrequests. Process text/html documents by actually + * running the subrequest; text/xxx documents get copied verbatim, + * and any other content type is ignored. This means that a non-text + * document (such as FOOTER.gif) might get multiviewed as the result + * instead of a text document, meaning nothing will be displayed, but + * oh well. + */ +static void emit_tail(request_rec *r, char *readme_fname, int suppress_amble) +{ + FILE *f; + request_rec *rr = NULL; + int suppress_post = 0; + int suppress_sig = 0; + + /* + * If there's a readme file, send a subrequest to look for it. If it's + * found and a text file, handle it -- otherwise fall through and + * pretend there's nothing there. + */ + if ((readme_fname != NULL) + && (rr = ap_sub_req_lookup_uri(readme_fname, r)) + && (rr->status == HTTP_OK) + && (rr->filename != NULL) + && S_ISREG(rr->finfo.st_mode)) { + /* + * Check for the two specific cases we allow: text/html and + * text/anything-else. The former is allowed to be processed for + * SSIs. + */ + if (rr->content_type != NULL) { + if (!strcasecmp(ap_field_noparam(r->pool, rr->content_type), + "text/html")) { + if (ap_run_sub_req(rr) == OK) { + /* worked... */ + suppress_sig = 1; + suppress_post = suppress_amble; } - else if (ch == '&') { - ap_rputs("&", r); + } + else if (!strncasecmp("text/", rr->content_type, 5)) { + /* + * If we can open the file, suppress the signature. + */ + if ((f = ap_pfopen(r->pool, rr->filename, "r")) != 0) { + do_emit_plain(r, f); + ap_pfclose(r->pool, f); + suppress_sig = 1; } - c = i + 1; } } } - ap_pfclose(r->pool, f); - if (plaintext) { - ap_rputs("</PRE>\n", r); + + if (!suppress_sig) { + ap_rputs(ap_psignature("", r), r); + } + if (!suppress_post) { + ap_rputs("</BODY></HTML>\n", r); + } + if (rr != NULL) { + ap_destroy_sub_req(rr); } - return 1; } @@ -863,8 +1081,9 @@ static char *find_title(request_rec *r) if (r->status != HTTP_OK) { return NULL; } - if (r->content_type - && (!strcmp(r->content_type, "text/html") + if ((r->content_type != NULL) + && (!strcasecmp(ap_field_noparam(r->pool, r->content_type), + "text/html") || !strcmp(r->content_type, INCLUDES_MAGIC_TYPE)) && !r->content_encoding) { if (!(thefile = ap_pfopen(r->pool, r->filename, "r"))) { @@ -1042,41 +1261,6 @@ static void emit_link(request_rec *r, char *anchor, char fname, char curkey, } } -/* - * Fit a string into a specified buffer width, marking any - * truncation. The size argument is the actual buffer size, including - * the \0 termination byte. The buffer will be prefilled with blanks. - * If the pad argument is false, any extra spaces at the end of the - * buffer are omitted. (Used when constructing anchors.) - */ -static ap_inline char *widthify(const char *s, char *buff, int size, int pad) -{ - int s_len; - - memset(buff, ' ', size); - buff[size - 1] = '\0'; - s_len = strlen(s); - if (s_len > (size - 1)) { - ap_cpystrn(buff, s, size); - if (size > 1) { - buff[size - 2] = '>'; - } - if (size > 2) { - buff[size - 3] = '.'; - } - if (size > 3) { - buff[size - 4] = '.'; - } - } - else { - ap_cpystrn(buff, s, s_len + 1); - if (pad) { - buff[s_len] = ' '; - } - } - return buff; -} - static void output_directories(struct ent **ar, int n, autoindex_config_rec *d, request_rec *r, int autoindex_opts, char keyid, char direction) @@ -1088,6 +1272,7 @@ static void output_directories(struct ent **ar, int n, pool *scratch = ap_make_sub_pool(r->pool); int name_width; char *name_scratch; + char *pad_scratch; if (name[0] == '\0') { name = "/"; @@ -1102,10 +1287,10 @@ static void output_directories(struct ent **ar, int n, } } } - ++name_width; name_scratch = ap_palloc(r->pool, name_width + 1); - memset(name_scratch, ' ', name_width); - name_scratch[name_width] = '\0'; + pad_scratch = ap_palloc(r->pool, name_width + 1); + memset(pad_scratch, ' ', name_width); + pad_scratch[name_width] = '\0'; if (autoindex_opts & FANCY_INDEXING) { ap_rputs("<PRE>", r); @@ -1123,14 +1308,8 @@ static void output_directories(struct ent **ar, int n, } ap_rputs("> ", r); } - emit_link(r, widthify("Name", name_scratch, - (name_width > 5) ? 5 : name_width, K_NOPAD), - K_NAME, keyid, direction, static_columns); - if (name_width > 5) { - memset(name_scratch, ' ', name_width); - name_scratch[name_width] = '\0'; - ap_rputs(&name_scratch[5], r); - } + emit_link(r, "Name", K_NAME, keyid, direction, static_columns); + ap_rputs(pad_scratch + 4, r); /* * Emit the guaranteed-at-least-one-space-between-columns byte. */ @@ -1156,7 +1335,6 @@ static void output_directories(struct ent **ar, int n, for (x = 0; x < n; x++) { char *anchor, *t, *t2; - char *pad; int nwidth; ap_clear_pool(scratch); @@ -1167,15 +1345,12 @@ static void output_directories(struct ent **ar, int n, if (t[0] == '\0') { t = "/"; } - /* 1234567890123456 */ t2 = "Parent Directory"; - pad = name_scratch + 16; anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0)); } else { t = ar[x]->name; - pad = name_scratch + strlen(t); - t2 = ap_escape_html(scratch, t); + t2 = t; anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0)); } @@ -1200,18 +1375,19 @@ static void output_directories(struct ent **ar, int n, ap_rputs("</A>", r); } - ap_rvputs(r, " <A HREF=\"", anchor, "\">", - widthify(t2, name_scratch, name_width, K_NOPAD), - "</A>", NULL); - /* - * We know that widthify() prefilled the buffer with spaces - * before doing its thing, so use them. - */ nwidth = strlen(t2); - if (nwidth < (name_width - 1)) { - name_scratch[nwidth] = ' '; - ap_rputs(&name_scratch[nwidth], r); + if (nwidth > name_width) { + memcpy(name_scratch, t2, name_width - 3); + name_scratch[name_width - 3] = '.'; + name_scratch[name_width - 2] = '.'; + name_scratch[name_width - 1] = '>'; + name_scratch[name_width] = 0; + t2 = name_scratch; + nwidth = name_width; } + ap_rvputs(r, " <A HREF=\"", anchor, "\">", + ap_escape_html(scratch, t2), "</A>", pad_scratch + nwidth, + NULL); /* * The blank before the storm.. er, before the next field. */ @@ -1241,7 +1417,7 @@ static void output_directories(struct ent **ar, int n, } else { ap_rvputs(r, "<LI><A HREF=\"", anchor, "\"> ", t2, - "</A>", pad, NULL); + "</A>", NULL); } ap_rputc('\n', r); } @@ -1326,7 +1502,6 @@ static int index_directory(request_rec *r, int num_ent = 0, x; struct ent *head, *p; struct ent **ar = NULL; - char *tmp; const char *qstring; int autoindex_opts = autoindex_conf->opts; char keyid; @@ -1356,12 +1531,8 @@ static int index_directory(request_rec *r, *title_endp-- = '\0'; } - if ((!(tmp = find_header(autoindex_conf, r))) - || (!(insert_readme(name, tmp, title_name, NO_HRULE, FRONT_MATTER, r))) - ) { - emit_preamble(r, title_name); - ap_rvputs(r, "<H1>Index of ", title_name, "</H1>\n", NULL); - } + emit_head(r, find_header(autoindex_conf, r), + autoindex_opts & SUPPRESS_PREAMBLE, title_name); /* * Figure out what sort of indexing (if any) we're supposed to use. @@ -1426,15 +1597,11 @@ static int index_directory(request_rec *r, direction); ap_pclosedir(r->pool, d); - if ((tmp = find_readme(autoindex_conf, r))) { - if (!insert_readme(name, tmp, "", - ((autoindex_opts & FANCY_INDEXING) ? HRULE - : NO_HRULE), - END_MATTER, r)) { - ap_rputs(ap_psignature("<HR>\n", r), r); - } + if (autoindex_opts & FANCY_INDEXING) { + ap_rputs("<HR>\n", r); } - ap_rputs("</BODY></HTML>\n", r); + emit_tail(r, find_readme(autoindex_conf, r), + autoindex_opts & SUPPRESS_PREAMBLE); ap_kill_timeout(r); return 0; diff --git a/usr.sbin/httpd/src/modules/standard/mod_cgi.c b/usr.sbin/httpd/src/modules/standard/mod_cgi.c index 9091d0d9be0..392fb5a1f13 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_cgi.c +++ b/usr.sbin/httpd/src/modules/standard/mod_cgi.c @@ -210,8 +210,19 @@ static int log_script(request_rec *r, cgi_server_conf * conf, int ret, /* Soak up script output */ while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_in) > 0) continue; +#ifdef WIN32 + /* Soak up stderr and redirect it to the error log. + * Script output to stderr is already directed to the error log + * on Unix, thanks to the magic of fork(). + */ + while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) { + ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r, + "%s", argsbuffer); + } +#else while (ap_bgets(argsbuffer, HUGE_STRING_LEN, script_err) > 0) continue; +#endif return ret; } @@ -275,6 +286,9 @@ static int log_script(request_rec *r, cgi_server_conf * conf, int ret, struct cgi_child_stuff { +#ifdef TPF + TPF_FORK_CHILD t; +#endif request_rec *r; int nph; int debug; @@ -325,10 +339,13 @@ static int cgi_child(void *child_stuff, child_info *pinfo) * NB only ISINDEX scripts get decoded arguments. */ +#ifdef TPF + return (0); +#else ap_cleanup_for_exec(); child_pid = ap_call_exec(r, pinfo, argv0, env, 0); -#ifdef WIN32 +#if defined(WIN32) || defined(OS2) return (child_pid); #else @@ -346,6 +363,7 @@ static int cgi_child(void *child_stuff, child_info *pinfo) /* NOT REACHED */ return (0); #endif +#endif /* TPF */ } static int cgi_handler(request_rec *r) @@ -419,6 +437,11 @@ static int cgi_handler(request_rec *r) cld.r = r; cld.nph = nph; cld.debug = conf->logname ? 1 : 0; +#ifdef TPF + cld.t.filename = r->filename; + cld.t.subprocess_env = r->subprocess_env; + cld.t.prog_type = FORK_FILE; +#endif /* TPF */ #ifdef CHARSET_EBCDIC /* XXX:@@@ Is the generated/included output ALWAYS in text/ebcdic format? */ @@ -440,16 +463,10 @@ static int cgi_handler(request_rec *r) } /* Transfer any put/post args, CERN style... - * Note that if a buggy script fails to read everything we throw - * at it, or a buggy client sends too much, we get a SIGPIPE, so - * we have to ignore SIGPIPE while doing this. CERN does the same - * (and in fact, they pretty nearly guarantee themselves a SIGPIPE - * on every invocation by chasing the real client data with a - * spurious newline). + * Note that we already ignore SIGPIPE in the core server. */ if (ap_should_client_block(r)) { - void (*handler) (int); int dbsize, len_read; if (conf->logname) { @@ -458,9 +475,6 @@ static int cgi_handler(request_rec *r) } ap_hard_timeout("copy script args", r); -#ifdef SIGPIPE - handler = signal(SIGPIPE, SIG_IGN); -#endif while ((len_read = ap_get_client_block(r, argsbuffer, HUGE_STRING_LEN)) > 0) { @@ -485,7 +499,6 @@ static int cgi_handler(request_rec *r) } ap_bflush(script_out); - signal(SIGPIPE, handler); ap_kill_timeout(r); } diff --git a/usr.sbin/httpd/src/modules/standard/mod_dir.c b/usr.sbin/httpd/src/modules/standard/mod_dir.c index 04fbd1458c3..a32b390a88b 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_dir.c +++ b/usr.sbin/httpd/src/modules/standard/mod_dir.c @@ -161,7 +161,7 @@ static int handle_dir(request_rec *r) char *name_ptr = *names_ptr; request_rec *rr = ap_sub_req_lookup_uri(name_ptr, r); - if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) { + if (rr->status == HTTP_OK && S_ISREG(rr->finfo.st_mode)) { char *new_uri = ap_escape_uri(r->pool, rr->uri); if (rr->args != NULL) @@ -179,13 +179,13 @@ static int handle_dir(request_rec *r) if (ap_is_HTTP_REDIRECT(rr->status) || (rr->status == HTTP_NOT_ACCEPTABLE && num_names == 1)) { + ap_pool_join(r->pool, rr->pool); error_notfound = rr->status; r->notes = ap_overlay_tables(r->pool, r->notes, rr->notes); r->headers_out = ap_overlay_tables(r->pool, r->headers_out, rr->headers_out); r->err_headers_out = ap_overlay_tables(r->pool, r->err_headers_out, rr->err_headers_out); - ap_destroy_sub_req(rr); return error_notfound; } diff --git a/usr.sbin/httpd/src/modules/standard/mod_env.c b/usr.sbin/httpd/src/modules/standard/mod_env.c index e2bf3603a01..351a48712b0 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_env.c +++ b/usr.sbin/httpd/src/modules/standard/mod_env.c @@ -105,26 +105,26 @@ typedef struct { table *vars; char *unsetenv; int vars_present; -} env_server_config_rec; +} env_dir_config_rec; module MODULE_VAR_EXPORT env_module; -static void *create_env_server_config(pool *p, server_rec *dummy) +static void *create_env_dir_config(pool *p, char *dummy) { - env_server_config_rec *new = - (env_server_config_rec *) ap_palloc(p, sizeof(env_server_config_rec)); + env_dir_config_rec *new = + (env_dir_config_rec *) ap_palloc(p, sizeof(env_dir_config_rec)); new->vars = ap_make_table(p, 50); new->unsetenv = ""; new->vars_present = 0; return (void *) new; } -static void *merge_env_server_configs(pool *p, void *basev, void *addv) +static void *merge_env_dir_configs(pool *p, void *basev, void *addv) { - env_server_config_rec *base = (env_server_config_rec *) basev; - env_server_config_rec *add = (env_server_config_rec *) addv; - env_server_config_rec *new = - (env_server_config_rec *) ap_palloc(p, sizeof(env_server_config_rec)); + env_dir_config_rec *base = (env_dir_config_rec *) basev; + env_dir_config_rec *add = (env_dir_config_rec *) addv; + env_dir_config_rec *new = + (env_dir_config_rec *) ap_palloc(p, sizeof(env_dir_config_rec)); table *new_table; table_entry *elts; @@ -166,11 +166,10 @@ static void *merge_env_server_configs(pool *p, void *basev, void *addv) return new; } -static const char *add_env_module_vars_passed(cmd_parms *cmd, char *struct_ptr, +static const char *add_env_module_vars_passed(cmd_parms *cmd, + env_dir_config_rec *sconf, const char *arg) { - env_server_config_rec *sconf = - ap_get_module_config(cmd->server->module_config, &env_module); table *vars = sconf->vars; char *env_var; char *name_ptr; @@ -186,11 +185,10 @@ static const char *add_env_module_vars_passed(cmd_parms *cmd, char *struct_ptr, return NULL; } -static const char *add_env_module_vars_set(cmd_parms *cmd, char *struct_ptr, +static const char *add_env_module_vars_set(cmd_parms *cmd, + env_dir_config_rec *sconf, const char *arg) { - env_server_config_rec *sconf = - ap_get_module_config(cmd->server->module_config, &env_module); table *vars = sconf->vars; char *name, *value; @@ -212,11 +210,10 @@ static const char *add_env_module_vars_set(cmd_parms *cmd, char *struct_ptr, return NULL; } -static const char *add_env_module_vars_unset(cmd_parms *cmd, char *struct_ptr, +static const char *add_env_module_vars_unset(cmd_parms *cmd, + env_dir_config_rec *sconf, char *arg) { - env_server_config_rec *sconf = - ap_get_module_config(cmd->server->module_config, &env_module); sconf->unsetenv = sconf->unsetenv ? ap_pstrcat(cmd->pool, sconf->unsetenv, " ", arg, NULL) : arg; @@ -226,19 +223,18 @@ static const char *add_env_module_vars_unset(cmd_parms *cmd, char *struct_ptr, static const command_rec env_module_cmds[] = { {"PassEnv", add_env_module_vars_passed, NULL, - RSRC_CONF, RAW_ARGS, "a list of environment variables to pass to CGI."}, + OR_FILEINFO, RAW_ARGS, "a list of environment variables to pass to CGI."}, {"SetEnv", add_env_module_vars_set, NULL, - RSRC_CONF, RAW_ARGS, "an environment variable name and a value to pass to CGI."}, + OR_FILEINFO, RAW_ARGS, "an environment variable name and a value to pass to CGI."}, {"UnsetEnv", add_env_module_vars_unset, NULL, - RSRC_CONF, RAW_ARGS, "a list of variables to remove from the CGI environment."}, + OR_FILEINFO, RAW_ARGS, "a list of variables to remove from the CGI environment."}, {NULL}, }; static int fixup_env_module(request_rec *r) { table *e = r->subprocess_env; - server_rec *s = r->server; - env_server_config_rec *sconf = ap_get_module_config(s->module_config, + env_dir_config_rec *sconf = ap_get_module_config(r->per_dir_config, &env_module); table *vars = sconf->vars; @@ -254,10 +250,10 @@ module MODULE_VAR_EXPORT env_module = { STANDARD_MODULE_STUFF, NULL, /* initializer */ - NULL, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - create_env_server_config, /* server config */ - merge_env_server_configs, /* merge server configs */ + create_env_dir_config, /* dir config creater */ + merge_env_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ env_module_cmds, /* command table */ NULL, /* handlers */ NULL, /* filename translation */ diff --git a/usr.sbin/httpd/src/modules/standard/mod_imap.c b/usr.sbin/httpd/src/modules/standard/mod_imap.c index dfde31464c4..c5152e71e40 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_imap.c +++ b/usr.sbin/httpd/src/modules/standard/mod_imap.c @@ -508,7 +508,7 @@ static void menu_header(request_rec *r, char *menu) ap_send_http_header(r); ap_hard_timeout("send menu", r); /* killed in menu_footer */ - ap_rvputs(r, "<html><head>\n<title>Menu for ", r->uri, + ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ", r->uri, "</title>\n</head><body>\n", NULL); if (!strcasecmp(menu, "formatted")) { diff --git a/usr.sbin/httpd/src/modules/standard/mod_include.c b/usr.sbin/httpd/src/modules/standard/mod_include.c index dd36668cda7..3ee96db83b5 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_include.c +++ b/usr.sbin/httpd/src/modules/standard/mod_include.c @@ -628,7 +628,7 @@ static int include_cgi(char *s, request_rec *r) */ static int is_only_below(const char *path) { -#if WIN32 +#ifdef HAVE_DRIVE_LETTERS if (path[1] == ':') return 0; #endif @@ -765,6 +765,9 @@ static int handle_include(FILE *in, request_rec *r, const char *error, int noexe } typedef struct { +#ifdef TPF + TPF_FORK_CHILD t; +#endif request_rec *r; char *s; } include_cmd_arg; @@ -818,11 +821,14 @@ static int include_cmd_child(void *arg, child_info *pinfo) #ifdef DEBUG_INCLUDE_CMD fprintf(dbg, "Attempting to exec '%s'\n", s); #endif +#ifdef TPF + return (0); +#else ap_cleanup_for_exec(); /* set shellcmd flag to pass arg to SHELL_PATH */ child_pid = ap_call_exec(r, pinfo, s, ap_create_environment(r->pool, env), 1); -#ifdef WIN32 +#if defined(WIN32) || defined(OS2) return (child_pid); #else /* Oh, drat. We're still here. The log file descriptors are closed, @@ -840,6 +846,7 @@ static int include_cmd_child(void *arg, child_info *pinfo) /* NOT REACHED */ return (child_pid); #endif /* WIN32 */ +#endif /* TPF */ } static int include_cmd(char *s, request_rec *r) @@ -849,6 +856,11 @@ static int include_cmd(char *s, request_rec *r) arg.r = r; arg.s = s; +#ifdef TPF + arg.t.filename = r->filename; + arg.t.subprocess_env = r->subprocess_env; + arg.t.prog_type = FORK_FILE; +#endif if (!ap_bspawn_child(r->pool, include_cmd_child, &arg, kill_after_timeout, NULL, &script_in, NULL)) { @@ -1033,35 +1045,41 @@ static int handle_config(FILE *in, request_rec *r, char *error, char *tf, static int find_file(request_rec *r, const char *directive, const char *tag, char *tag_val, struct stat *finfo, const char *error) { - char *to_send; - request_rec *rr; + char *to_send = tag_val; + request_rec *rr = NULL; int ret=0; + char *error_fmt = NULL; if (!strcmp(tag, "file")) { - ap_getparents(tag_val); /* get rid of any nasties */ - - rr = ap_sub_req_lookup_file(tag_val, r); - - if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) { - to_send = rr->filename; - if ((ret = stat(to_send, finfo)) == -1) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "unable to get information about \"%s\" " - "in parsed file %s", - to_send, r->filename); - ap_rputs(error, r); - } + /* be safe; only files in this directory or below allowed */ + if (!is_only_below(tag_val)) { + error_fmt = "unable to access file \"%s\" " + "in parsed file %s"; } else { + ap_getparents(tag_val); /* get rid of any nasties */ + rr = ap_sub_req_lookup_file(tag_val, r); + + if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) { + to_send = rr->filename; + if (stat(to_send, finfo)) { + error_fmt = "unable to get information about \"%s\" " + "in parsed file %s"; + } + } + else { + error_fmt = "unable to lookup information about \"%s\" " + "in parsed file %s"; + } + } + + if (error_fmt) { ret = -1; - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "unable to lookup information about \"%s\" " - "in parsed file %s", - tag_val, r->filename); + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, error_fmt, to_send, r->filename); ap_rputs(error, r); } - - ap_destroy_sub_req(rr); + + if (rr) ap_destroy_sub_req(rr); return ret; } @@ -1116,9 +1134,8 @@ static int handle_fsize(FILE *in, request_rec *r, const char *error, int sizefmt } else { int l, x; -#if defined(BSD) && BSD > 199305 - /* ap_snprintf can't handle %qd */ - sprintf(tag, "%qd", finfo.st_size); +#if defined(AP_OFF_T_IS_QUAD) + ap_snprintf(tag, sizeof(tag), "%qd", finfo.st_size); #else ap_snprintf(tag, sizeof(tag), "%ld", finfo.st_size); #endif @@ -1169,7 +1186,7 @@ static int re_check(request_rec *r, char *string, char *rexp) "unable to compile pattern \"%s\"", rexp); return -1; } - regex_error = regexec(compiled, string, 0, (regmatch_t *) NULL, 0); + regex_error = ap_regexec(compiled, string, 0, (regmatch_t *) NULL, 0); ap_pregfree(r->pool, compiled); return (!regex_error); } diff --git a/usr.sbin/httpd/src/modules/standard/mod_info.c b/usr.sbin/httpd/src/modules/standard/mod_info.c index ce0edefc9e2..27995855780 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_info.c +++ b/usr.sbin/httpd/src/modules/standard/mod_info.c @@ -378,7 +378,8 @@ static int display_info(request_rec *r) } ap_hard_timeout("send server info", r); - ap_rputs("<html><head><title>Server Information</title></head>\n", r); + ap_rputs(DOCTYPE_HTML_3_2 + "<html><head><title>Server Information</title></head>\n", r); ap_rputs("<body><h1 align=center>Apache Server Information</h1>\n", r); if (!r->args || strcasecmp(r->args, "list")) { cfname = ap_server_root_relative(r->pool, ap_server_confname); diff --git a/usr.sbin/httpd/src/modules/standard/mod_log_config.c b/usr.sbin/httpd/src/modules/standard/mod_log_config.c index 21ed1973f99..def4069b961 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_log_config.c +++ b/usr.sbin/httpd/src/modules/standard/mod_log_config.c @@ -106,8 +106,8 @@ * CustomLog logs/referer "%{referer}i -> %U" * CustomLog logs/agent "%{user-agent}i" * - * Except: no RefererIgnore functionality - * logs '-' if no Referer or User-Agent instead of nothing + * RefererIgnore functionality can be obtained with conditional + * logging (SetEnvIf and CustomLog ... env=!VAR). * * But using this method allows much easier modification of the * log format, e.g. to log hosts along with UA: @@ -122,6 +122,7 @@ * %...f: filename * %...h: remote host * %...a: remote IP-address + * %...A: local IP-address * %...{Foobar}i: The contents of Foobar: header line(s) in the request * sent to the client. * %...l: remote logname (from identd, if supplied) @@ -138,7 +139,8 @@ * %...T: the time taken to serve the request, in seconds. * %...u: remote user (from auth; may be bogus if return status (%s) is 401) * %...U: the URL path requested. - * %...v: the name of the server (i.e. which virtual host?) + * %...v: the configured name of the server (i.e. which virtual host?) + * %...V: the server name according to the UseCanonicalName setting * * The '...' can be nothing at all (e.g. "%h %u %r %s %b"), or it can * indicate conditions for inclusion of the item (which will cause it @@ -235,6 +237,7 @@ typedef struct { char *format_string; array_header *format; int log_fd; + char *condition_var; #ifdef BUFFERED_LOGS int outcnt; char outbuf[LOG_BUFSIZE]; @@ -290,6 +293,11 @@ static const char *log_remote_address(request_rec *r, char *a) return r->connection->remote_ip; } +static const char *log_local_address(request_rec *r, char *a) +{ + return r->connection->local_ip; +} + static const char *log_remote_logname(request_rec *r, char *a) { return ap_get_remote_logname(r); @@ -385,16 +393,14 @@ static const char *log_request_time(request_rec *r, char *a) } else { /* CLF format */ char sign = (timz < 0 ? '-' : '+'); - size_t l; if (timz < 0) { timz = -timz; } - - strftime(tstr, MAX_STRING_LEN, "[%d/%b/%Y:%H:%M:%S ", t); - l = strlen(tstr); - ap_snprintf(tstr + l, sizeof(tstr) - l, - "%c%.2d%.2d]", sign, timz / 60, timz % 60); + ap_snprintf(tstr, sizeof(tstr), "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]", + t->tm_mday, ap_month_snames[t->tm_mon], t->tm_year+1900, + t->tm_hour, t->tm_min, t->tm_sec, + sign, timz / 60, timz % 60); } return ap_pstrdup(r->pool, tstr); @@ -419,6 +425,14 @@ static const char *log_server_port(request_rec *r, char *a) r->server->port ? r->server->port : ap_default_port(r)); } +/* This respects the setting of UseCanonicalName so that + * the dynamic mass virtual hosting trick works better. + */ +static const char *log_server_name(request_rec *r, char *a) +{ + return ap_get_server_name(r); +} + static const char *log_child_pid(request_rec *r, char *a) { return ap_psprintf(r->pool, "%ld", (long) getpid()); @@ -441,6 +455,9 @@ static struct log_item_list { { 'a', log_remote_address, 0 }, + { + 'A', log_local_address, 0 + }, { 'l', log_remote_logname, 0 }, @@ -481,6 +498,9 @@ static struct log_item_list { 'e', log_env_var, 0 }, { + 'V', log_server_name, 0 + }, + { 'v', log_virtual_host, 0 }, { @@ -527,30 +547,61 @@ static struct log_item_list *find_log_func(char k) return NULL; } -static char *log_format_substring(pool *p, const char *start, - const char *end) -{ - char *res = ap_palloc(p, end - start + 1); - - strncpy(res, start, end - start); - res[end - start] = '\0'; - return res; -} - static char *parse_log_misc_string(pool *p, log_format_item *it, const char **sa) { - const char *s = *sa; + const char *s; + char *d; it->func = constant_item; it->conditions = NULL; + s = *sa; while (*s && *s != '%') { - ++s; + s++; } - it->arg = log_format_substring(p, *sa, s); - *sa = s; + /* + * This might allocate a few chars extra if there's a backslash + * escape in the format string. + */ + it->arg = ap_palloc(p, s - *sa + 1); + + d = it->arg; + s = *sa; + while (*s && *s != '%') { + if (*s != '\\') { + *d++ = *s++; + } + else { + s++; + switch (*s) { + case '\\': + *d++ = '\\'; + s++; + break; + case 'n': + *d++ = '\n'; + s++; + break; + case 't': + *d++ = '\t'; + s++; + break; + default: + /* copy verbatim */ + *d++ = '\\'; + /* + * Allow the loop to deal with this *s in the normal + * fashion so that it handles end of string etc. + * properly. + */ + break; + } + } + } + *d = '\0'; + *sa = s; return NULL; } @@ -729,11 +780,30 @@ static int config_log_transaction(request_rec *r, config_log_state *cls, int i; int len = 0; array_header *format; + char *envar; if (cls->fname == NULL) { return DECLINED; } + /* + * See if we've got any conditional envariable-controlled logging decisions + * to make. + */ + if (cls->condition_var != NULL) { + envar = cls->condition_var; + if (*envar != '!') { + if (ap_table_get(r->subprocess_env, envar) == NULL) { + return DECLINED; + } + } + else { + if (ap_table_get(r->subprocess_env, &envar[1]) != NULL) { + return DECLINED; + } + } + } + format = cls->format ? cls->format : default_format; strs = ap_palloc(r->pool, sizeof(char *) * (format->nelts)); @@ -792,10 +862,13 @@ static int config_log_transaction(request_rec *r, config_log_state *cls, static int multi_log_transaction(request_rec *r) { multi_log_state *mls = ap_get_module_config(r->server->module_config, - &config_log_module); + &config_log_module); config_log_state *clsarray; int i; + /* + * Log this transaction.. + */ if (mls->config_logs->nelts) { clsarray = (config_log_state *) mls->config_logs->elts; for (i = 0; i < mls->config_logs->nelts; ++i) { @@ -823,8 +896,9 @@ static int multi_log_transaction(request_rec *r) static void *make_config_log_state(pool *p, server_rec *s) { - multi_log_state *mls = (multi_log_state *) ap_palloc(p, sizeof(multi_log_state)); + multi_log_state *mls; + mls = (multi_log_state *) ap_palloc(p, sizeof(multi_log_state)); mls->config_logs = ap_make_array(p, 1, sizeof(config_log_state)); mls->default_format_string = NULL; mls->default_format = NULL; @@ -864,7 +938,7 @@ static const char *log_format(cmd_parms *cmd, void *dummy, char *fmt, { const char *err_string = NULL; multi_log_state *mls = ap_get_module_config(cmd->server->module_config, - &config_log_module); + &config_log_module); /* * If we were given two arguments, the second is a name to be given to the @@ -884,18 +958,31 @@ static const char *log_format(cmd_parms *cmd, void *dummy, char *fmt, return err_string; } + static const char *add_custom_log(cmd_parms *cmd, void *dummy, char *fn, - char *fmt) + char *fmt, char *envclause) { const char *err_string = NULL; multi_log_state *mls = ap_get_module_config(cmd->server->module_config, - &config_log_module); + &config_log_module); config_log_state *cls; cls = (config_log_state *) ap_push_array(mls->config_logs); + cls->condition_var = NULL; + if (envclause != NULL) { + if (strncasecmp(envclause, "env=", 4) != 0) { + return "error in condition clause"; + } + if ((envclause[4] == '\0') + || ((envclause[4] == '!') && (envclause[5] == '\0'))) { + return "missing environment variable name"; + } + cls->condition_var = ap_pstrdup(cmd->pool, &envclause[4]); + } + cls->fname = fn; cls->format_string = fmt; - if (!fmt) { + if (fmt == NULL) { cls->format = NULL; } else { @@ -908,18 +995,19 @@ static const char *add_custom_log(cmd_parms *cmd, void *dummy, char *fn, static const char *set_transfer_log(cmd_parms *cmd, void *dummy, char *fn) { - return add_custom_log(cmd, dummy, fn, NULL); + return add_custom_log(cmd, dummy, fn, NULL, NULL); } static const char *set_cookie_log(cmd_parms *cmd, void *dummy, char *fn) { - return add_custom_log(cmd, dummy, fn, "%{Cookie}n \"%r\" %t"); + return add_custom_log(cmd, dummy, fn, "%{Cookie}n \"%r\" %t", NULL); } static const command_rec config_log_cmds[] = { - {"CustomLog", add_custom_log, NULL, RSRC_CONF, TAKE2, - "a file name and a custom log format string or format name"}, + {"CustomLog", add_custom_log, NULL, RSRC_CONF, TAKE23, + "a file name, a custom log format string or format name, " + "and an optional \"env=\" clause (see docs)"}, {"TransferLog", set_transfer_log, NULL, RSRC_CONF, TAKE1, "the filename of the access log"}, {"LogFormat", log_format, NULL, RSRC_CONF, TAKE12, diff --git a/usr.sbin/httpd/src/modules/standard/mod_mime.c b/usr.sbin/httpd/src/modules/standard/mod_mime.c index 80ec7ee3c82..f27356bfdd3 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_mime.c +++ b/usr.sbin/httpd/src/modules/standard/mod_mime.c @@ -233,13 +233,8 @@ static const command_rec mime_cmds[] = * get private versions through AddType... */ -/* MIME_HASHSIZE used to be 27 (26 chars and one "non-alpha" slot), but - * with character sets like EBCDIC, this is insufficient because the - * range 'a'...'z' is not contigous. Defining it as ('z'-'a'+2) is - * equivalent to 27 in ASCII, and makes it work in EBCDIC. - */ -#define MIME_HASHSIZE ('z'-'a'+2) -#define hash(i) (ap_isalpha(i) ? (ap_tolower(i)) - 'a' : (MIME_HASHSIZE-1)) +#define MIME_HASHSIZE (32) +#define hash(i) (ap_tolower(i) % MIME_HASHSIZE) static table *hash_buckets[MIME_HASHSIZE]; diff --git a/usr.sbin/httpd/src/modules/standard/mod_mime_magic.c b/usr.sbin/httpd/src/modules/standard/mod_mime_magic.c index e57eea537f8..7f4d6ba6e30 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_mime_magic.c +++ b/usr.sbin/httpd/src/modules/standard/mod_mime_magic.c @@ -242,7 +242,7 @@ union record { static int ascmagic(request_rec *, unsigned char *, int); static int is_tar(unsigned char *, int); static int softmagic(request_rec *, unsigned char *, int); -static void tryit(request_rec *, unsigned char *, int); +static void tryit(request_rec *, unsigned char *, int, int); static int zmagic(request_rec *, unsigned char *, int); static int getvalue(server_rec *, struct magic *, char **); @@ -256,7 +256,7 @@ static int mget(request_rec *, union VALUETYPE *, unsigned char *, static int mcheck(request_rec *, union VALUETYPE *, struct magic *); static void mprint(request_rec *, union VALUETYPE *, struct magic *); -static int uncompress(request_rec *, int, const unsigned char *, +static int uncompress(request_rec *, int, unsigned char **, int); static long from_oct(int, char *); static int fsmagic(request_rec *r, const char *fn); @@ -887,7 +887,7 @@ static int magic_process(request_rec *r) magic_rsl_puts(r, MIME_TEXT_UNKNOWN); else { buf[nbytes++] = '\0'; /* null-terminate it */ - tryit(r, buf, nbytes); + tryit(r, buf, nbytes, 1); } (void) ap_pclosef(r->pool, fd); @@ -897,13 +897,15 @@ static int magic_process(request_rec *r) } -static void tryit(request_rec *r, unsigned char *buf, int nb) +static void tryit(request_rec *r, unsigned char *buf, int nb, int checkzmagic) { /* * Try compression stuff */ - if (zmagic(r, buf, nb) == 1) - return; + if (checkzmagic == 1) { + if (zmagic(r, buf, nb) == 1) + return; + } /* * try tests in /etc/magic (or surrogate magic file) @@ -2082,9 +2084,13 @@ static struct { char *encoding; /* MUST be lowercase */ } compr[] = { + /* we use gzip here rather than uncompress because we have to pass + * it a full filename -- and uncompress only considers filenames + * ending with .Z + */ { "\037\235", 2, { - "uncompress", "-c", NULL + "gzip", "-dcq", NULL }, 0, "x-compress" }, { @@ -2121,8 +2127,8 @@ static int zmagic(request_rec *r, unsigned char *buf, int nbytes) if (i == ncompr) return 0; - if ((newsize = uncompress(r, i, buf, &newbuf, nbytes)) > 0) { - tryit(r, newbuf, newsize); + if ((newsize = uncompress(r, i, &newbuf, nbytes)) > 0) { + tryit(r, newbuf, newsize, 0); /* set encoding type in the request record */ r->content_encoding = compr[i].encoding; @@ -2139,6 +2145,13 @@ struct uncompress_parms { static int uncompress_child(void *data, child_info *pinfo) { struct uncompress_parms *parm = data; + char *new_argv[4]; + + new_argv[0] = compr[parm->method].argv[0]; + new_argv[1] = compr[parm->method].argv[1]; + new_argv[2] = parm->r->filename; + new_argv[3] = NULL; + #if defined(WIN32) int child_pid; #endif @@ -2149,10 +2162,10 @@ static int uncompress_child(void *data, child_info *pinfo) #if defined(WIN32) child_pid = spawnvp(compr[parm->method].argv[0], - compr[parm->method].argv); + new_argv); return (child_pid); #else - execvp(compr[parm->method].argv[0], compr[parm->method].argv); + execvp(compr[parm->method].argv[0], new_argv); ap_log_rerror(APLOG_MARK, APLOG_ERR, parm->r, MODNAME ": could not execute `%s'.", compr[parm->method].argv[0]); @@ -2161,11 +2174,11 @@ static int uncompress_child(void *data, child_info *pinfo) } -static int uncompress(request_rec *r, int method, const unsigned char *old, +static int uncompress(request_rec *r, int method, unsigned char **newch, int n) { struct uncompress_parms parm; - BUFF *bin, *bout; + BUFF *bout; pool *sub_pool; parm.r = r; @@ -2178,19 +2191,12 @@ static int uncompress(request_rec *r, int method, const unsigned char *old, sub_pool = ap_make_sub_pool(r->pool); if (!ap_bspawn_child(sub_pool, uncompress_child, &parm, kill_always, - &bin, &bout, NULL)) { + NULL, &bout, NULL)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, MODNAME ": couldn't spawn uncompress process: %s", r->uri); return -1; } - if (ap_bwrite(bin, old, n) != n) { - ap_destroy_pool(sub_pool); - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - MODNAME ": write failed."); - return -1; - } - ap_bclose(bin); *newch = (unsigned char *) ap_palloc(r->pool, n); if ((n = ap_bread(bout, *newch, n)) <= 0) { ap_destroy_pool(sub_pool); diff --git a/usr.sbin/httpd/src/modules/standard/mod_negotiation.c b/usr.sbin/httpd/src/modules/standard/mod_negotiation.c index b2fcf93ef74..5f7411260c2 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_negotiation.c +++ b/usr.sbin/httpd/src/modules/standard/mod_negotiation.c @@ -140,7 +140,6 @@ static const command_rec negotiation_cmds[] = typedef struct accept_rec { char *name; /* MUST be lowercase */ float quality; - float max_bytes; float level; char *charset; /* for content-type only */ } accept_rec; @@ -315,7 +314,6 @@ static const char *get_entry(pool *p, accept_rec *result, const char *accept_line) { result->quality = 1.0f; - result->max_bytes = 0.0f; result->level = 0.0f; result->charset = ""; @@ -392,10 +390,6 @@ static const char *get_entry(pool *p, accept_rec *result, && (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0'))) { result->quality = atof(cp); } - else if (parm[0] == 'm' && parm[1] == 'x' && - parm[2] == 'b' && parm[3] == '\0') { - result->max_bytes = atof(cp); - } else if (parm[0] == 'l' && !strcmp(&parm[1], "evel")) { result->level = atof(cp); } @@ -511,81 +505,81 @@ static negotiation_state *parse_accept_headers(request_rec *r) static void parse_negotiate_header(request_rec *r, negotiation_state *neg) { const char *negotiate = ap_table_get(r->headers_in, "Negotiate"); + char *tok; - if (negotiate) { - /* Negotiate: header tells us UA does transparent negotiation */ + /* First, default to no TCN, no Alternates, and the original Apache + * negotiation algorithm with fiddles for broken browser configs. + * + * To save network bandwidth, we do not configure to send an + * Alternates header to the user agent by default. User + * agents that want an Alternates header for agent-driven + * negotiation will have to request it by sending an + * appropriate Negotiate header. + */ + neg->ua_supports_trans = 0; + neg->send_alternates = 0; + neg->may_choose = 1; + neg->use_rvsa = 0; + neg->dont_fiddle_headers = 0; + + if (!negotiate) + return; - /* sending Alternates on non-transparent resources is allowed, - * and may even be useful, but we don't for now, also - * because it could clash with an Alternates header set by - * a sub- or super- request on a transparent resource. + if (strcmp(negotiate, "trans") == 0) { + /* Lynx 2.7 and 2.8 send 'negotiate: trans' even though they + * do not support transparent content negotiation, so for Lynx we + * ignore the negotiate header when its contents are exactly "trans". + * If future versions of Lynx ever need to say 'negotiate: trans', + * they can send the equivalent 'negotiate: trans, trans' instead + * to avoid triggering the workaround below. */ + const char *ua = ap_table_get(r->headers_in, "User-Agent"); - while (*negotiate) { - char *tok = ap_get_token(neg->pool, &negotiate, 1); - char *cp; + if (ua && (strncmp(ua, "Lynx", 4) == 0)) + return; + } - for (cp = tok; (*cp && !ap_isspace(*cp) && *cp != '='); ++cp) { - *cp = ap_tolower(*cp); - } - *cp = 0; - - if (strcmp(tok, "trans") == 0 || - strcmp(tok, "vlist") == 0 || - strcmp(tok, "guess-small") == 0 || - ap_isdigit(tok[0]) || - strcmp(tok, "*") == 0) { - - /* The user agent supports transparent negotiation */ - neg->ua_supports_trans = 1; - - /* Send-alternates could be configurable, but note - * that it must be 1 if we have 'vlist' in the - * negotiate header. - */ - neg->send_alternates = 1; + neg->may_choose = 0; /* An empty Negotiate would require 300 response */ - if (strcmp(tok, "1.0") == 0) { - /* we may use the RVSA/1.0 algorithm, configure for it */ - neg->may_choose = 1; - neg->use_rvsa = 1; - neg->dont_fiddle_headers = 1; - } - else if (strcmp(tok, "*") == 0) { - /* we may use any variant selection algorithm, configure - * to use the Apache algorithm - */ - neg->may_choose = 1; - - /* We disable header fiddles on the assumption that a - * client sending Negotiate knows how to send correct - * headers which don't need fiddling. - */ - neg->dont_fiddle_headers = 1; - } - } + while ((tok = ap_get_list_item(neg->pool, &negotiate)) != NULL) { - if (*negotiate) - negotiate++; /* skip over , */ - } - } + if (strcmp(tok, "trans") == 0 || + strcmp(tok, "vlist") == 0 || + strcmp(tok, "guess-small") == 0 || + ap_isdigit(tok[0]) || + strcmp(tok, "*") == 0) { - if (!neg->ua_supports_trans) { - /* User agent does not support transparent negotiation, - * configure to do server-driven negotiation with the Apache - * algorithm. - */ - neg->may_choose = 1; + /* The user agent supports transparent negotiation */ + neg->ua_supports_trans = 1; - /* To save network bandwidth, we do not configure to send an - * Alternates header to the user agent in this case. User - * agents which want an Alternates header for agent-driven - * negotiation will have to request it by sending an - * appropriate Negotiate header. - */ + /* Send-alternates could be configurable, but note + * that it must be 1 if we have 'vlist' in the + * negotiate header. + */ + neg->send_alternates = 1; + + if (strcmp(tok, "1.0") == 0) { + /* we may use the RVSA/1.0 algorithm, configure for it */ + neg->may_choose = 1; + neg->use_rvsa = 1; + neg->dont_fiddle_headers = 1; + } + else if (tok[0] == '*') { + /* we may use any variant selection algorithm, configure + * to use the Apache algorithm + */ + neg->may_choose = 1; + + /* We disable header fiddles on the assumption that a + * client sending Negotiate knows how to send correct + * headers which don't need fiddling. + */ + neg->dont_fiddle_headers = 1; + } + } } -#if NEG_DEBUG +#ifdef NEG_DEBUG fprintf(stderr, "dont_fiddle_headers=%d use_rvsa=%d ua_supports_trans=%d " "send_alternates=%d, may_choose=%d\n", neg->dont_fiddle_headers, neg->use_rvsa, @@ -613,7 +607,6 @@ static void maybe_add_default_accepts(negotiation_state *neg, new_accept->name = "*/*"; new_accept->quality = 1.0f; new_accept->level = 0.0f; - new_accept->max_bytes = 0.0f; } new_accept = (accept_rec *) ap_push_array(neg->accepts); @@ -626,7 +619,6 @@ static void maybe_add_default_accepts(negotiation_state *neg, new_accept->quality = prefer_scripts ? 2.0f : 0.001f; } new_accept->level = 0.0f; - new_accept->max_bytes = 0.0f; } /***************************************************************** @@ -837,9 +829,6 @@ static int read_type_map(negotiation_state *neg, request_rec *rr) has_content = 1; } else if (!strncmp(buffer, "description:", 12)) { - /* XXX: The possibility to set a description is - * currently not documented. - */ char *desc = ap_pstrdup(neg->pool, body); char *cp; @@ -1523,13 +1512,6 @@ static void set_accept_quality(negotiation_state *neg, var_rec *variant) } } - /* Check maxbytes -- not in HTTP/1.1 or TCN */ - - if (type->max_bytes > 0 - && (find_content_length(neg, variant) > type->max_bytes)) { - continue; - } - /* If we are allowed to mess with the q-values * and have no explicit q= parameters in the accept header, * make wildcards very low, so we have a low chance @@ -1556,7 +1538,7 @@ static void set_accept_quality(negotiation_state *neg, var_rec *variant) } /* For a given variant, find the 'q' value of the charset given - * on the Accept-Charset line. If not charsets are listed, + * on the Accept-Charset line. If no charsets are listed, * assume value of '1'. */ static void set_charset_quality(negotiation_state *neg, var_rec *variant) @@ -1763,20 +1745,21 @@ static int is_variant_better_rvsa(negotiation_state *neg, var_rec *variant, variant->charset_quality * variant->lang_quality; - /* Make sure that variants with a very low nonzero q value - * do not get rounded down to 0 + /* RFC 2296 calls for the result to be rounded to 5 decimal places, + * but we don't do that because it serves no useful purpose other + * than to ensure that a remote algorithm operates on the same + * precision as ours. That is silly, since what we obviously want + * is for the algorithm to operate on the best available precision + * regardless of who runs it. Since the above calculation may + * result in significant variance at 1e-12, rounding would be bogus. */ - if (q <= 0.0f) - q = 0.0f; - else if (q < 0.00001f) - q = 0.00001f; #ifdef NEG_DEBUG fprintf(stderr, "Variant: file=%s type=%s lang=%s sourceq=%1.3f " "mimeq=%1.3f langq=%1.3f charq=%1.3f encq=%1.3f " "q=%1.5f definite=%d\n", (variant->file_name ? variant->file_name : ""), - (variant->mime_name ? variant->mime_name : ""), + (variant->mime_type ? variant->mime_type : ""), (variant->content_languages ? ap_array_pstrcat(neg->pool, variant->content_languages, ',') : ""), @@ -1784,11 +1767,12 @@ static int is_variant_better_rvsa(negotiation_state *neg, var_rec *variant, variant->mime_type_quality, variant->lang_quality, variant->charset_quality, - variant->encoding_qual q, + variant->encoding_quality, + q, variant->definite); #endif - if (q == 0.0f) { + if (q <= 0.0f) { return 0; } if (q > bestq) { @@ -1803,19 +1787,6 @@ static int is_variant_better_rvsa(negotiation_state *neg, var_rec *variant, *p_bestq = q; return 1; } - /* If the best variant's charset is ISO-8859-1 and this variant has - * the same charset quality, then we prefer this variant - */ - if (variant->charset_quality == best->charset_quality && - (variant->content_charset != NULL && - *variant->content_charset != '\0' && - strcmp(variant->content_charset, "iso-8859-1") != 0) && - (best->content_charset == NULL || - *best->content_charset == '\0' || - strcmp(best->content_charset, "iso-8859-1") == 0)) { - *p_bestq = q; - return 1; - } } return 0; } @@ -1833,7 +1804,7 @@ static int is_variant_better(negotiation_state *neg, var_rec *variant, /* For non-transparent negotiation, server can choose how * to handle the negotiation. We'll use the following in * order: content-type, language, content-type level, charset, - * content length. + * content encoding, content length. * * For each check, we have three possible outcomes: * This variant is worse than current best: return 0 @@ -1853,6 +1824,22 @@ static int is_variant_better(negotiation_state *neg, var_rec *variant, * acceptable by type, charset, encoding or language. */ +#ifdef NEG_DEBUG + fprintf(stderr, "Variant: file=%s type=%s lang=%s sourceq=%1.3f " + "mimeq=%1.3f langq=%1.3f langidx=%d charq=%1.3f encq=%1.3f \n", + (variant->file_name ? variant->file_name : ""), + (variant->mime_type ? variant->mime_type : ""), + (variant->content_languages + ? ap_array_pstrcat(neg->pool, variant->content_languages, ',') + : ""), + variant->source_quality, + variant->mime_type_quality, + variant->lang_quality, + variant->lang_index, + variant->charset_quality, + variant->encoding_quality); +#endif + if (variant->encoding_quality == 0.0f || variant->lang_quality == 0.0f || variant->source_quality == 0.0f || @@ -1879,17 +1866,13 @@ static int is_variant_better(negotiation_state *neg, var_rec *variant, return 1; } - /* if language qualities were equal, try the LanguagePriority - * stuff - */ - /* XXX: TODO: there is a slight discrepancy between how this - * behaves and how it described in the documentation - */ - if (best->lang_index != -1 && variant->lang_index > best->lang_index) { + /* if language qualities were equal, try the LanguagePriority stuff */ + if (best->lang_index != -1 && + (variant->lang_index == -1 || variant->lang_index > best->lang_index)) { return 0; } if (variant->lang_index != -1 && - (variant->lang_index < best->lang_index || best->lang_index == -1)) { + (best->lang_index == -1 || variant->lang_index < best->lang_index)) { *p_bestq = q; return 1; } @@ -1913,9 +1896,6 @@ static int is_variant_better(negotiation_state *neg, var_rec *variant, /* If the best variant's charset is ISO-8859-1 and this variant has * the same charset quality, then we prefer this variant */ - /* XXX: TODO: this specific tie-breaker is not described in the - * documentation - */ if (variant->charset_quality > best->charset_quality || ((variant->content_charset != NULL && @@ -2211,14 +2191,6 @@ static void set_neg_headers(request_rec *r, negotiation_state *neg, ap_array_pstrcat(r->pool, arr, '\0')); } - /* Theoretically the negotiation result _always_ has a dependence on - * the contents of the Accept header because we do 'mxb=' - * processing in set_accept_quality(). However, variations in mxb - * only affect the relative quality of several acceptable variants, - * so there is no reason to worry about an unacceptable variant - * being mistakenly prioritized. We therefore ignore mxb in deciding - * whether or not to include Accept in the Vary field value. - */ if (neg->is_transparent || vary_by_type || vary_by_language || vary_by_language || vary_by_charset || vary_by_encoding) { @@ -2437,7 +2409,6 @@ static int do_negotiation(request_rec *r, negotiation_state *neg, int alg_result; /* result of variant selection algorithm */ int res; int j; - int unencoded_variants = 0; /* Decide if resource is transparently negotiable */ @@ -2465,20 +2436,7 @@ static int do_negotiation(request_rec *r, negotiation_state *neg, */ if (strchr(variant->file_name, '/')) neg->is_transparent = 0; - - if (!variant->content_encoding) - unencoded_variants++; } - - /* If there are less than 2 unencoded variants, we always - * switch to server-driven negotiation, regardless of whether - * we are contacted by a client capable of transparent - * negotiation. We do this because our current TCN - * implementation does not deal well with the case of having 0 - * or 1 unencoded variants. - */ - if (unencoded_variants < 2) - neg->is_transparent = 0; } if (neg->is_transparent) { diff --git a/usr.sbin/httpd/src/modules/standard/mod_rewrite.c b/usr.sbin/httpd/src/modules/standard/mod_rewrite.c index 9898103006f..fa16d2d1916 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_rewrite.c +++ b/usr.sbin/httpd/src/modules/standard/mod_rewrite.c @@ -91,6 +91,10 @@ #include "mod_rewrite.h" +#ifndef NO_WRITEV +#include <sys/types.h> +#include <sys/uio.h> +#endif /* ** +-------------------------------------------------------+ @@ -158,9 +162,9 @@ static const command_rec command_table[] = { { "RewriteBase", cmd_rewritebase, NULL, OR_FILEINFO, TAKE1, "the base URL of the per-directory context" }, { "RewriteCond", cmd_rewritecond, NULL, OR_FILEINFO, RAW_ARGS, - "a input string and a to be applied regexp-pattern" }, + "an input string and a to be applied regexp-pattern" }, { "RewriteRule", cmd_rewriterule, NULL, OR_FILEINFO, RAW_ARGS, - "a URL-applied regexp-pattern and a substitution URL" }, + "an URL-applied regexp-pattern and a substitution URL" }, { "RewriteMap", cmd_rewritemap, NULL, RSRC_CONF, TAKE2, "a mapname and a filename" }, { "RewriteLock", cmd_rewritelock, NULL, RSRC_CONF, TAKE1, @@ -208,10 +212,8 @@ static cache *cachep; /* whether proxy module is available or not */ static int proxy_available; - /* the txt mapfile parsing stuff */ -static regex_t *lookup_map_txtfile_regexp = NULL; -static regmatch_t lookup_map_txtfile_regmatch[MAX_NMATCH]; - +static char *lockname; +static int lockfd = -1; /* ** +-------------------------------------------------------+ @@ -238,8 +240,6 @@ static void *config_server_create(pool *p, server_rec *s) a->rewritelogfile = NULL; a->rewritelogfp = -1; a->rewriteloglevel = 0; - a->rewritelockfile = NULL; - a->rewritelockfp = -1; a->rewritemaps = ap_make_array(p, 2, sizeof(rewritemap_entry)); a->rewriteconds = ap_make_array(p, 2, sizeof(rewritecond_entry)); a->rewriterules = ap_make_array(p, 2, sizeof(rewriterule_entry)); @@ -274,12 +274,6 @@ static void *config_server_merge(pool *p, void *basev, void *overridesv) a->rewritelogfp = overrides->rewritelogfp != -1 ? overrides->rewritelogfp : base->rewritelogfp; - a->rewritelockfile = overrides->rewritelockfile != NULL - ? overrides->rewritelockfile - : base->rewritelockfile; - a->rewritelockfp = overrides->rewritelockfp != -1 - ? overrides->rewritelockfp - : base->rewritelockfp; a->rewritemaps = ap_append_arrays(p, overrides->rewritemaps, base->rewritemaps); a->rewriteconds = ap_append_arrays(p, overrides->rewriteconds, @@ -295,8 +289,6 @@ static void *config_server_merge(pool *p, void *basev, void *overridesv) a->rewriteloglevel = overrides->rewriteloglevel; a->rewritelogfile = overrides->rewritelogfile; a->rewritelogfp = overrides->rewritelogfp; - a->rewritelockfile = overrides->rewritelockfile; - a->rewritelockfp = overrides->rewritelockfp; a->rewritemaps = overrides->rewritemaps; a->rewriteconds = overrides->rewriteconds; a->rewriterules = overrides->rewriterules; @@ -532,12 +524,12 @@ static const char *cmd_rewritemap(cmd_parms *cmd, void *dconf, char *a1, static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, char *a1) { - rewrite_server_conf *sconf; + const char *error; - sconf = (rewrite_server_conf *) - ap_get_module_config(cmd->server->module_config, &rewrite_module); + if ((error = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL) + return error; - sconf->rewritelockfile = a1; + lockname = a1; return NULL; } @@ -952,10 +944,6 @@ static void init_module(server_rec *s, pool *p) /* check if proxy module is available */ proxy_available = (ap_find_linked_module("mod_proxy.c") != NULL); - /* precompile a static pattern - for the txt mapfile parsing */ - lookup_map_txtfile_regexp = ap_pregcomp(p, MAPFILE_PATTERN, REG_EXTENDED); - /* create the rewriting lockfile in the parent */ rewritelock_create(s, p); ap_register_cleanup(p, (void *)s, rewritelock_remove, ap_null_cleanup); @@ -1804,7 +1792,7 @@ static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p, rewritelog(r, 3, "[per-dir %s] applying pattern '%s' to uri '%s'", perdir, p->pattern, uri); } - rc = (regexec(regexp, uri, regexp->re_nsub+1, regmatch, 0) == 0); + rc = (ap_regexec(regexp, uri, regexp->re_nsub+1, regmatch, 0) == 0); if (! (( rc && !(p->flags & RULEFLAG_NOTMATCH)) || (!rc && (p->flags & RULEFLAG_NOTMATCH)) ) ) { return 0; @@ -2180,7 +2168,7 @@ static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p, } } } - else if (strcmp(p->pattern, "-s ") == 0) { + else if (strcmp(p->pattern, "-s") == 0) { if (stat(input, &sb) == 0) { if (S_ISREG(sb.st_mode) && sb.st_size > 0) { rc = 1; @@ -2273,8 +2261,8 @@ static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p, } else { /* it is really a regexp pattern, so apply it */ - rc = (regexec(p->regexp, input, - p->regexp->re_nsub+1, regmatch,0) == 0); + rc = (ap_regexec(p->regexp, input, + p->regexp->re_nsub+1, regmatch,0) == 0); /* if it isn't a negated pattern and really matched we update the passed-through regex subst info structure */ @@ -2729,13 +2717,15 @@ static char *lookup_map(request_rec *r, char *name, char *key) else { rewritelog(r, 5, "map lookup FAILED: map=%s[txt] " "key=%s", s->name, key); + set_cache_string(cachep, s->name, CACHEMODE_TS, + st.st_mtime, key, ""); return NULL; } } else { rewritelog(r, 5, "cache lookup OK: map=%s[txt] key=%s " "-> val=%s", s->name, key, value); - return value; + return value[0] != '\0' ? value : NULL; } } else if (s->type == MAPTYPE_DBM) { @@ -2764,13 +2754,15 @@ static char *lookup_map(request_rec *r, char *name, char *key) else { rewritelog(r, 5, "map lookup FAILED: map=%s[dbm] " "key=%s", s->name, key); + set_cache_string(cachep, s->name, CACHEMODE_TS, + st.st_mtime, key, ""); return NULL; } } else { rewritelog(r, 5, "cache lookup OK: map=%s[dbm] key=%s " "-> val=%s", s->name, key, value); - return value; + return value[0] != '\0' ? value : NULL; } #else return NULL; @@ -2823,6 +2815,8 @@ static char *lookup_map(request_rec *r, char *name, char *key) else { rewritelog(r, 5, "map lookup FAILED: map=%s[txt] " "key=%s", s->name, key); + set_cache_string(cachep, s->name, CACHEMODE_TS, + st.st_mtime, key, ""); return NULL; } } @@ -2830,8 +2824,13 @@ static char *lookup_map(request_rec *r, char *name, char *key) rewritelog(r, 5, "cache lookup OK: map=%s[txt] key=%s " "-> val=%s", s->name, key, value); } - value = select_random_value_part(r, value); - rewritelog(r, 5, "randomly choosen the subvalue `%s'", value); + if (value[0] != '\0') { + value = select_random_value_part(r, value); + rewritelog(r, 5, "randomly choosen the subvalue `%s'", value); + } + else { + value = NULL; + } return value; } } @@ -2839,44 +2838,45 @@ static char *lookup_map(request_rec *r, char *name, char *key) return NULL; } - static char *lookup_map_txtfile(request_rec *r, char *file, char *key) { FILE *fp = NULL; char line[1024]; - char output[1024]; - char result[1024]; char *value = NULL; char *cpT; + size_t skip; char *curkey; char *curval; if ((fp = ap_pfopen(r->pool, file, "r")) == NULL) { - return NULL; + return NULL; } - ap_cpystrn(output, MAPFILE_OUTPUT, sizeof(output)); while (fgets(line, sizeof(line), fp) != NULL) { - if (line[strlen(line)-1] == '\n') { - line[strlen(line)-1] = '\0'; - } - if (regexec(lookup_map_txtfile_regexp, line, - lookup_map_txtfile_regexp->re_nsub+1, - lookup_map_txtfile_regmatch, 0) == 0) { - ap_cpystrn(result, ap_pregsub(r->pool, output, line, - lookup_map_txtfile_regexp->re_nsub+1, - lookup_map_txtfile_regmatch), - sizeof(result)); /* substitute in output */ - cpT = strchr(result, ','); - *cpT = '\0'; - curkey = result; - curval = cpT+1; - - if (strcmp(curkey, key) == 0) { - value = ap_pstrdup(r->pool, curval); - break; - } - } + if (line[0] == '#') + continue; /* ignore comments */ + cpT = line; + curkey = cpT; + skip = strcspn(cpT," \t\r\n"); + if (skip == 0) + continue; /* ignore lines that start with a space, tab, CR, or LF */ + cpT += skip; + *cpT = '\0'; + if (strcmp(curkey, key) != 0) + continue; /* key does not match... */ + + /* found a matching key; now extract and return the value */ + ++cpT; + skip = strspn(cpT, " \t\r\n"); + cpT += skip; + curval = cpT; + skip = strcspn(cpT, " \t\r\n"); + if (skip == 0) + continue; /* no value... */ + cpT += skip; + *cpT = '\0'; + value = ap_pstrdup(r->pool, curval); + break; } ap_pfclose(r->pool, fp); return value; @@ -2913,6 +2913,9 @@ static char *lookup_map_program(request_rec *r, int fpin, int fpout, char *key) char buf[LONG_STRING_LEN]; char c; int i; +#ifndef NO_WRITEV + struct iovec iov[2]; +#endif /* when `RewriteEngine off' was used in the per-server * context then the rewritemap-programs were not spawned. @@ -2927,8 +2930,16 @@ static char *lookup_map_program(request_rec *r, int fpin, int fpout, char *key) rewritelock_alloc(r); /* write out the request key */ +#ifdef NO_WRITEV write(fpin, key, strlen(key)); write(fpin, "\n", 1); +#else + iov[0].iov_base = key; + iov[0].iov_len = strlen(key); + iov[1].iov_base = "\n"; + iov[1].iov_len = 1; + writev(fpin, iov, 2); +#endif /* read in the response value */ i = 0; @@ -3247,28 +3258,26 @@ static void rewritelock_create(server_rec *s, pool *p) conf = ap_get_module_config(s->module_config, &rewrite_module); /* only operate if a lockfile is used */ - if (conf->rewritelockfile == NULL - || *(conf->rewritelockfile) == '\0') { + if (lockname == NULL || *(lockname) == '\0') { return; } /* fixup the path, especially for rewritelock_remove() */ - conf->rewritelockfile = ap_server_root_relative(p, conf->rewritelockfile); + lockname = ap_server_root_relative(p, lockname); /* create the lockfile */ - unlink(conf->rewritelockfile); - if ((conf->rewritelockfp = ap_popenf(p, conf->rewritelockfile, - O_WRONLY|O_CREAT, + unlink(lockname); + if ((lockfd = ap_popenf(p, lockname, O_WRONLY|O_CREAT, REWRITELOCK_MODE)) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_rewrite: Parent could not create RewriteLock " - "file %s", conf->rewritelockfile); + "file %s", lockname); exit(1); } #if !defined(OS2) && !defined(WIN32) /* make sure the childs have access to this file */ if (geteuid() == 0 /* is superuser */) - chown(conf->rewritelockfile, ap_user_id, -1 /* no gid change */); + chown(lockname, ap_user_id, -1 /* no gid change */); #endif return; @@ -3281,18 +3290,16 @@ static void rewritelock_open(server_rec *s, pool *p) conf = ap_get_module_config(s->module_config, &rewrite_module); /* only operate if a lockfile is used */ - if (conf->rewritelockfile == NULL - || *(conf->rewritelockfile) == '\0') { + if (lockname == NULL || *(lockname) == '\0') { return; } /* open the lockfile (once per child) to get a unique fd */ - if ((conf->rewritelockfp = ap_popenf(p, conf->rewritelockfile, - O_WRONLY, + if ((lockfd = ap_popenf(p, lockname, O_WRONLY, REWRITELOCK_MODE)) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_rewrite: Child could not open RewriteLock " - "file %s", conf->rewritelockfile); + "file %s", lockname); exit(1); } return; @@ -3300,43 +3307,29 @@ static void rewritelock_open(server_rec *s, pool *p) static void rewritelock_remove(void *data) { - server_rec *s; - rewrite_server_conf *conf; - - /* the data is really the server_rec */ - s = (server_rec *)data; - conf = ap_get_module_config(s->module_config, &rewrite_module); - /* only operate if a lockfile is used */ - if (conf->rewritelockfile == NULL - || *(conf->rewritelockfile) == '\0') { + if (lockname == NULL || *(lockname) == '\0') { return; } /* remove the lockfile */ - unlink(conf->rewritelockfile); + unlink(lockname); + lockname = NULL; + lockfd = -1; } static void rewritelock_alloc(request_rec *r) { - rewrite_server_conf *conf; - - conf = ap_get_module_config(r->server->module_config, &rewrite_module); - - if (conf->rewritelockfp != -1) { - fd_lock(r, conf->rewritelockfp); + if (lockfd != -1) { + fd_lock(r, lockfd); } return; } static void rewritelock_free(request_rec *r) { - rewrite_server_conf *conf; - - conf = ap_get_module_config(r->server->module_config, &rewrite_module); - - if (conf->rewritelockfp != -1) { - fd_unlock(r, conf->rewritelockfp); + if (lockfd != -1) { + fd_unlock(r, lockfd); } return; } @@ -3607,6 +3600,9 @@ static char *lookup_variable(request_rec *r, char *var) else if (strcasecmp(var, "SERVER_NAME") == 0) { result = ap_get_server_name(r); } + else if (strcasecmp(var, "SERVER_ADDR") == 0) { /* non-standard */ + result = r->connection->local_ip; + } else if (strcasecmp(var, "SERVER_PORT") == 0) { ap_snprintf(resultbuf, sizeof(resultbuf), "%u", ap_get_server_port(r)); result = resultbuf; @@ -3843,12 +3839,57 @@ static char *get_cache_string(cache *c, char *res, int mode, return ap_pstrdup(c->pool, ce->value); } +static int cache_tlb_hash(char *key) +{ + unsigned long n; + char *p; + + n = 0; + for (p=key; *p != '\0'; ++p) { + n = n * 53711 + 134561 + (unsigned)(*p & 0xff); + } + + return n % CACHE_TLB_ROWS; +} + +static cacheentry *cache_tlb_lookup(cachetlbentry *tlb, cacheentry *elt, + char *key) +{ + int ix = cache_tlb_hash(key); + int i; + int j; + + for (i=0; i < CACHE_TLB_COLS; ++i) { + j = tlb[ix].t[i]; + if (j < 0) + return NULL; + if (strcmp(elt[j].key, key) == 0) + return &elt[j]; + } + return NULL; +} + +static void cache_tlb_replace(cachetlbentry *tlb, cacheentry *elt, + cacheentry *e) +{ + int ix = cache_tlb_hash(e->key); + int i; + + tlb = &tlb[ix]; + + for (i=1; i < CACHE_TLB_COLS; ++i) + tlb->t[i] = tlb->t[i-1]; + + tlb->t[0] = e - elt; +} + static void store_cache_string(cache *c, char *res, cacheentry *ce) { int i; int j; cachelist *l; cacheentry *e; + cachetlbentry *t; int found_list; found_list = 0; @@ -3857,11 +3898,22 @@ static void store_cache_string(cache *c, char *res, cacheentry *ce) l = &(((cachelist *)c->lists->elts)[i]); if (strcmp(l->resource, res) == 0) { found_list = 1; + + e = cache_tlb_lookup((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, ce->key); + if (e != NULL) { + e->time = ce->time; + e->value = ap_pstrdup(c->pool, ce->value); + return; + } + for (j = 0; j < l->entries->nelts; j++) { e = &(((cacheentry *)l->entries->elts)[j]); if (strcmp(e->key, ce->key) == 0) { e->time = ce->time; e->value = ap_pstrdup(c->pool, ce->value); + cache_tlb_replace((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, e); return; } } @@ -3873,6 +3925,13 @@ static void store_cache_string(cache *c, char *res, cacheentry *ce) l = ap_push_array(c->lists); l->resource = ap_pstrdup(c->pool, res); l->entries = ap_make_array(c->pool, 2, sizeof(cacheentry)); + l->tlb = ap_make_array(c->pool, CACHE_TLB_ROWS, + sizeof(cachetlbentry)); + for (i=0; i<CACHE_TLB_ROWS; ++i) { + t = &((cachetlbentry *)l->tlb->elts)[i]; + for (j=0; j<CACHE_TLB_COLS; ++j) + t->t[j] = -1; + } } /* create the new entry */ @@ -3883,6 +3942,8 @@ static void store_cache_string(cache *c, char *res, cacheentry *ce) e->time = ce->time; e->key = ap_pstrdup(c->pool, ce->key); e->value = ap_pstrdup(c->pool, ce->value); + cache_tlb_replace((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, e); return; } } @@ -3901,6 +3962,12 @@ static cacheentry *retrieve_cache_string(cache *c, char *res, char *key) for (i = 0; i < c->lists->nelts; i++) { l = &(((cachelist *)c->lists->elts)[i]); if (strcmp(l->resource, res) == 0) { + + e = cache_tlb_lookup((cachetlbentry *)l->tlb->elts, + (cacheentry *)l->entries->elts, key); + if (e != NULL) + return e; + for (j = 0; j < l->entries->nelts; j++) { e = &(((cacheentry *)l->entries->elts)[j]); if (strcmp(e->key, key) == 0) { diff --git a/usr.sbin/httpd/src/modules/standard/mod_rewrite.h b/usr.sbin/httpd/src/modules/standard/mod_rewrite.h index 323f0af2974..22ff3375589 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_rewrite.h +++ b/usr.sbin/httpd/src/modules/standard/mod_rewrite.h @@ -105,6 +105,7 @@ #include <sys/stat.h> /* Include from the Apache server ... */ +#define CORE_PRIVATE #include "httpd.h" #include "http_config.h" #include "http_conf_globals.h" @@ -126,8 +127,15 @@ * so we also need to know the file extension */ #ifndef NO_DBM_REWRITEMAP +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) \ + && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 +#include <db1/ndbm.h> +#else #include <ndbm.h> -#if (__FreeBSD__) +#endif +#if defined(DBM_SUFFIX) +#define NDBM_FILE_SUFFIX DBM_SUFFIX +#elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM)) #define NDBM_FILE_SUFFIX ".db" #else #define NDBM_FILE_SUFFIX ".pag" @@ -149,7 +157,7 @@ #endif #if !defined(USE_FCNTL) && !defined(USE_FLOCK) #define USE_FLOCK 1 -#if !defined(MPE) && !defined(WIN32) +#if !defined(MPE) && !defined(WIN32) && !defined(__TANDEM) #include <sys/file.h> #endif #ifndef LOCK_UN @@ -219,6 +227,9 @@ #define CACHEMODE_TS 1<<0 #define CACHEMODE_TTL 1<<1 +#define CACHE_TLB_ROWS 1024 +#define CACHE_TLB_COLS 4 + #ifndef FALSE #define FALSE 0 #define TRUE !FALSE @@ -241,10 +252,6 @@ #define MAX_NMATCH 10 -#define MAPFILE_PATTERN "^([^ \t]+)[ \t]+([^ \t]+).*$" -#define MAPFILE_OUTPUT "$1,$2" - - /* ** ** our private data structures we handle with @@ -295,8 +302,6 @@ typedef struct { char *rewritelogfile; /* the RewriteLog filename */ int rewritelogfp; /* the RewriteLog open filepointer */ int rewriteloglevel; /* the RewriteLog level of verbosity */ - char *rewritelockfile; /* the RewriteLock filename */ - int rewritelockfp; /* the RewriteLock open filepointer */ array_header *rewritemaps; /* the RewriteMap entries */ array_header *rewriteconds; /* the RewriteCond entries (temporary) */ array_header *rewriterules; /* the RewriteRule entries */ @@ -317,17 +322,23 @@ typedef struct { } rewrite_perdir_conf; - /* the cache structures */ - + /* the cache structures, + * a 4-way hash table with LRU functionality + */ typedef struct cacheentry { time_t time; char *key; char *value; } cacheentry; +typedef struct tlbentry { + int t[CACHE_TLB_COLS]; +} cachetlbentry; + typedef struct cachelist { char *resource; array_header *entries; + array_header *tlb; } cachelist; typedef struct cache { @@ -335,9 +346,10 @@ typedef struct cache { array_header *lists; } cache; - /* the regex structure for the - substitution of backreferences */ + /* the regex structure for the + * substitution of backreferences + */ typedef struct backrefinfo { char *source; int nsub; diff --git a/usr.sbin/httpd/src/modules/standard/mod_setenvif.c b/usr.sbin/httpd/src/modules/standard/mod_setenvif.c index 24841852946..27eef0aec94 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_setenvif.c +++ b/usr.sbin/httpd/src/modules/standard/mod_setenvif.c @@ -125,7 +125,8 @@ enum special { SPECIAL_REMOTE_HOST, SPECIAL_REMOTE_USER, SPECIAL_REQUEST_URI, - SPECIAL_REQUEST_METHOD + SPECIAL_REQUEST_METHOD, + SPECIAL_REQUEST_PROTOCOL }; typedef struct { char *name; /* header name */ @@ -241,6 +242,9 @@ static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig, else if (!strcasecmp(fname, "request_method")) { new->special_type = SPECIAL_REQUEST_METHOD; } + else if (!strcasecmp(fname, "request_protocol")) { + new->special_type = SPECIAL_REQUEST_PROTOCOL; + } else { new->special_type = SPECIAL_NOT; } @@ -355,8 +359,14 @@ static int match_headers(request_rec *r) case SPECIAL_REQUEST_METHOD: val = r->method; break; + case SPECIAL_REQUEST_PROTOCOL: + val = r->protocol; + break; case SPECIAL_NOT: val = ap_table_get(r->headers_in, b->name); + if (val == NULL) { + val = ap_table_get(r->subprocess_env, b->name); + } break; } } @@ -371,7 +381,7 @@ static int match_headers(request_rec *r) val = ""; } - if (!regexec(b->preg, val, 0, NULL, 0)) { + if (!ap_regexec(b->preg, val, 0, NULL, 0)) { array_header *arr = ap_table_elts(b->features); elts = (table_entry *) arr->elts; diff --git a/usr.sbin/httpd/src/modules/standard/mod_so.c b/usr.sbin/httpd/src/modules/standard/mod_so.c index ecc81f8f181..c3c89c975f4 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_so.c +++ b/usr.sbin/httpd/src/modules/standard/mod_so.c @@ -251,7 +251,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, "' in file ", szModuleFile, ": ", ap_os_dso_error(), NULL); } modi->modp = modp; - modp->dynamic_load_handle = modhandle; + modp->dynamic_load_handle = (void *)modhandle; /* * Make sure the found module structure is really a module structure @@ -296,7 +296,7 @@ static const char *load_module(cmd_parms *cmd, void *dummy, static const char *load_file(cmd_parms *cmd, void *dummy, char *filename) { - void *handle; + ap_os_dso_handle_t handle; char *file; file = ap_server_root_relative(cmd->pool, filename); @@ -312,7 +312,7 @@ static const char *load_file(cmd_parms *cmd, void *dummy, char *filename) ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL, "loaded file %s", filename); - ap_register_cleanup(cmd->pool, handle, unload_file, ap_null_cleanup); + ap_register_cleanup(cmd->pool, (void *)handle, unload_file, ap_null_cleanup); return NULL; } @@ -356,6 +356,7 @@ module MODULE_VAR_EXPORT so_module = { NULL, /* check auth */ NULL, /* check access */ NULL, /* type_checker */ + NULL, /* fixer_upper */ NULL, /* logger */ NULL, /* header parser */ NULL, /* child_init */ diff --git a/usr.sbin/httpd/src/modules/standard/mod_speling.c b/usr.sbin/httpd/src/modules/standard/mod_speling.c index a9f94d7fc16..067fd77c719 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_speling.c +++ b/usr.sbin/httpd/src/modules/standard/mod_speling.c @@ -428,9 +428,12 @@ static int check_speling(request_rec *r) * returned. */ else { - char *t; pool *p; table *notes; + pool *sub_pool; + array_header *t; + array_header *v; + if (r->main == NULL) { p = r->pool; @@ -441,16 +444,22 @@ static int check_speling(request_rec *r) notes = r->main->notes; } + sub_pool = ap_make_sub_pool(p); + t = ap_make_array(sub_pool, candidates->nelts * 8 + 8, + sizeof(char *)); + v = ap_make_array(sub_pool, candidates->nelts * 5, + sizeof(char *)); + /* Generate the response text. */ - /* - * Since the text is expanded by repeated calls of - * t = pstrcat(p, t, ".."), we can avoid a little waste - * of memory by adding the header AFTER building the list. - * XXX: FIXME: find a way to build a string concatenation - * without repeatedly requesting new memory - * XXX: FIXME: Limit the list to a maximum number of entries - */ - t = ""; + + *(const char **)ap_push_array(t) = + "The document name you requested (<code>"; + *(const char **)ap_push_array(t) = r->uri; + *(const char **)ap_push_array(t) = + "</code>) could not be found on this server.\n" + "However, we found documents with names similar " + "to the one you requested.<p>" + "Available documents:\n<ul>\n"; for (i = 0; i < candidates->nelts; ++i) { char *vuri; @@ -458,16 +467,24 @@ static int check_speling(request_rec *r) reason = sp_reason_str[(int) (variant[i].quality)]; /* The format isn't very neat... */ - vuri = ap_pstrcat(p, url, variant[i].name, r->path_info, + vuri = ap_pstrcat(sub_pool, url, variant[i].name, r->path_info, (r->parsed_uri.query != NULL) ? "?" : "", (r->parsed_uri.query != NULL) ? r->parsed_uri.query : "", NULL); - ap_table_mergen(r->subprocess_env, "VARIANTS", - ap_pstrcat(p, "\"", vuri, "\";\"", - reason, "\"", NULL)); - t = ap_pstrcat(p, t, "<li><a href=\"", vuri, - "\">", vuri, "</a> (", reason, ")\n", NULL); + *(const char **)ap_push_array(v) = "\""; + *(const char **)ap_push_array(v) = vuri; + *(const char **)ap_push_array(v) = "\";\""; + *(const char **)ap_push_array(v) = reason; + *(const char **)ap_push_array(v) = "\""; + + *(const char **)ap_push_array(t) = "<li><a href=\""; + *(const char **)ap_push_array(t) = vuri; + *(const char **)ap_push_array(t) = "\">"; + *(const char **)ap_push_array(t) = vuri; + *(const char **)ap_push_array(t) = "</a> ("; + *(const char **)ap_push_array(t) = reason; + *(const char **)ap_push_array(t) = ")\n"; /* * when we have printed the "close matches" and there are @@ -479,30 +496,31 @@ static int check_speling(request_rec *r) if (i > 0 && i < candidates->nelts - 1 && variant[i].quality != SP_VERYDIFFERENT && variant[i + 1].quality == SP_VERYDIFFERENT) { - t = ap_pstrcat(p, t, + *(const char **)ap_push_array(t) = "</ul>\nFurthermore, the following related " - "documents were found:\n<ul>\n", NULL); + "documents were found:\n<ul>\n"; } } - t = ap_pstrcat(p, "The document name you requested (<code>", - r->uri, - "</code>) could not be found on this server.\n" - "However, we found documents with names similar " - "to the one you requested.<p>" - "Available documents:\n<ul>\n", t, "</ul>\n", NULL); + *(const char **)ap_push_array(t) = "</ul>\n"; /* If we know there was a referring page, add a note: */ if (ref != NULL) { - t = ap_pstrcat(p, t, + *(const char **)ap_push_array(t) = "Please consider informing the owner of the " - "<a href=\"", ref, - "\">referring page</a> " - "about the broken link.\n", - NULL); + "<a href=\""; + *(const char **)ap_push_array(t) = ref; + *(const char **)ap_push_array(t) = "\">referring page</a> " + "about the broken link.\n"; } + /* Pass our table to http_protocol.c (see mod_negotiation): */ - ap_table_setn(notes, "variant-list", t); + ap_table_setn(notes, "variant-list", ap_array_pstrcat(p, t, 0)); + + ap_table_mergen(r->subprocess_env, "VARIANTS", + ap_array_pstrcat(p, v, ',')); + + ap_destroy_pool(sub_pool); ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, r, ref ? "Spelling fix: %s: %d candidates from %s" diff --git a/usr.sbin/httpd/src/modules/standard/mod_status.c b/usr.sbin/httpd/src/modules/standard/mod_status.c index bba554526c0..ad09467f4ab 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_status.c +++ b/usr.sbin/httpd/src/modules/standard/mod_status.c @@ -341,7 +341,9 @@ static int status_handler(request_rec *r) ap_hard_timeout("send status info", r); if (!short_report) { - ap_rputs("<HTML><HEAD>\n<TITLE>Apache Status</TITLE>\n</HEAD><BODY>\n", r); + ap_rputs(DOCTYPE_HTML_3_2 + "<HTML><HEAD>\n<TITLE>Apache Status</TITLE>\n</HEAD><BODY>\n", + r); ap_rputs("<H1>Apache Server Status for ", r); ap_rvputs(r, ap_get_server_name(r), "</H1>\n\n", NULL); ap_rvputs(r, "Server Version: ", @@ -353,6 +355,7 @@ static int status_handler(request_rec *r) ap_rvputs(r, "Restart Time: ", ap_ht_time(r->pool, ap_restart_time, DEFAULT_TIME_FORMAT, 0), "<br>\n", NULL); + ap_rprintf(r, "Parent Server Generation: %d <br>\n", (int) ap_my_generation); ap_rputs("Server uptime: ", r); show_time(r, up_time); ap_rputs("<br>\n", r); @@ -477,12 +480,33 @@ static int status_handler(request_rec *r) if (no_table_report) ap_rputs("<p><hr><h2>Server Details</h2>\n\n", r); else +#ifndef NO_PRETTYPRINT + ap_rputs("<p>\n\n<table bgcolor=\"#ffffff\" border=\"0\">" + "<tr bgcolor=000000>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Srv</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>PID</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Acc</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>M</b></font></td>" +#ifndef NO_TIMES + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>CPU</b></font></td>" +#endif + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>SS</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Req</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Conn</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Child</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Slot</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Host</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>VHost</b></font></td>" + "<td><font face=\"Arial,Helvetica\" color=\"#ffffff\"><b>Request</b></td>" + "</tr>\n", r); +#else /* NO_PRETTYPRINT */ #ifdef NO_TIMES /* Allow for OS/2 not having CPU stats */ ap_rputs("<p>\n\n<table border=0><tr><th>Srv<th>PID<th>Acc<th>M\n<th>SS<th>Req<th>Conn<th>Child<th>Slot<th>Client<th>VHost<th>Request</tr>\n\n", r); #else ap_rputs("<p>\n\n<table border=0><tr><th>Srv<th>PID<th>Acc<th>M<th>CPU\n<th>SS<th>Req<th>Conn<th>Child<th>Slot<th>Client<th>VHost<th>Request</tr>\n\n", r); #endif +#endif /* NO_PRETTYPRINT */ } for (i = 0; i < HARD_SERVER_LIMIT; ++i) { @@ -527,11 +551,16 @@ static int status_handler(request_rec *r) if (!short_report) { if (no_table_report) { if (score_record.status == SERVER_DEAD) - ap_rprintf(r, "<b>Server %d</b> (-): %d|%lu|%lu [", - i, (int) conn_lres, my_lres, lres); + ap_rprintf(r, + "<b>Server %d-%d</b> (-): %d|%lu|%lu [", + i, (int) ps_record.generation, (int) conn_lres, + my_lres, lres); else - ap_rprintf(r, "<b>Server %d</b> (%d): %d|%lu|%lu [", - i, (int) ps_record.pid, (int) conn_lres, my_lres, lres); + ap_rprintf(r, + "<b>Server %d-%d</b> (%d): %d|%lu|%lu [", + i, (int) ps_record.generation, + (int) ps_record.pid, + (int) conn_lres, my_lres, lres); switch (score_record.status) { case SERVER_READY: @@ -588,17 +617,28 @@ static int status_handler(request_rec *r) ap_rputs("|", r); format_byte_out(r, bytes); ap_rputs(")\n", r); - ap_rprintf(r, " <i>%s {%s}</i><br>\n\n", - score_record.client, - ap_escape_html(r->pool, score_record.request)); + ap_rprintf(r, " <i>%s {%s}</i> <b>[%s]</b><br>\n\n", + score_record.client, + ap_escape_html(r->pool, score_record.request), + vhost ? vhost->server_hostname : "(unavailable)"); } else { /* !no_table_report */ +#ifndef NO_PRETTYPRINT + ap_rprintf(r,"<tr bgcolor=\"#ffffff\">"); +#else + ap_rprintf(r,"<tr>"); +#endif if (score_record.status == SERVER_DEAD) - ap_rprintf(r, "<tr><td><b>%d</b><td>-<td>%d/%lu/%lu", - i, (int) conn_lres, my_lres, lres); + ap_rprintf(r, + "<td><b>%d-%d</b><td>-<td>%d/%lu/%lu", + i, (int) ps_record.generation, + (int) conn_lres, my_lres, lres); else - ap_rprintf(r, "<tr><td><b>%d</b><td>%d<td>%d/%lu/%lu", - i, (int) ps_record.pid, (int) conn_lres, my_lres, lres); + ap_rprintf(r, + "<td><b>%d-%d</b><td>%d<td>%d/%lu/%lu", + i, (int) ps_record.generation, + (int) ps_record.pid, (int) conn_lres, + my_lres, lres); switch (score_record.status) { case SERVER_READY: @@ -655,11 +695,22 @@ static int status_handler(request_rec *r) ap_rprintf(r, "<td>?<td nowrap>?<td nowrap>..reading.. </tr>\n\n"); else +#ifndef NO_PRETTYPRINT + ap_rprintf(r, + "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>" + "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>" + "<td nowrap><font face=\"Arial,Helvetica\" size=\"-1\">%s</font>" + "</tr>\n\n", + score_record.client, + vhost ? vhost->server_hostname : "(unavailable)", + ap_escape_html(r->pool, score_record.request)); +#else ap_rprintf(r, "<td>%s<td nowrap>%s<td nowrap>%s</tr>\n\n", score_record.client, vhost ? vhost->server_hostname : "(unavailable)", ap_escape_html(r->pool, score_record.request)); +#endif } /* no_table_report */ } /* !short_report */ } /* if (<active child>) */ @@ -670,7 +721,7 @@ static int status_handler(request_rec *r) ap_rputs("</table>\n \ <hr> \ <table>\n \ -<tr><th>Srv<td>Server number\n \ +<tr><th>Srv<td>Child Server number - generation\n \ <tr><th>PID<td>OS process ID\n \ <tr><th>Acc<td>Number of accesses this connection / this child / this slot\n \ <tr><th>M<td>Mode of operation\n \ @@ -684,7 +735,7 @@ static int status_handler(request_rec *r) ap_rputs("</table>\n \ <hr> \ <table>\n \ -<tr><th>Srv<td>Server number\n \ +<tr><th>Srv<td>Child Server number - generation\n \ <tr><th>PID<td>OS process ID\n \ <tr><th>Acc<td>Number of accesses this connection / this child / this slot\n \ <tr><th>M<td>Mode of operation\n \ @@ -698,6 +749,12 @@ static int status_handler(request_rec *r) #endif } +#ifdef EAPI + ap_hook_use("ap::mod_status::display", + AP_HOOK_SIG4(void,ptr,int,int), AP_HOOK_ALL, + r, no_table_report, short_report); +#endif + } else { ap_rputs("<hr>To obtain a full report with current status information ", r); diff --git a/usr.sbin/httpd/src/modules/standard/mod_unique_id.c b/usr.sbin/httpd/src/modules/standard/mod_unique_id.c index 6e103942bd3..63474ed1feb 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_unique_id.c +++ b/usr.sbin/httpd/src/modules/standard/mod_unique_id.c @@ -104,7 +104,7 @@ typedef struct { * saving cpu cycles. The counter is never reset, and is used to permit up to * 64k requests in a single second by a single child. * - * The 112-bits of unique_id_rec are uuencoded using the alphabet + * The 112-bits of unique_id_rec are encoded using the alphabet * [A-Za-z0-9@-], resulting in 19 bytes of printable characters. That is then * stuffed into the environment variable UNIQUE_ID so that it is available to * other modules. The alphabet choice differs from normal base64 encoding @@ -181,7 +181,7 @@ static void unique_id_global_init(server_rec *s, pool *p) unique_id_rec_size[2] + unique_id_rec_size[3]; /* - * Calculate the size of the structure when uuencoded. + * Calculate the size of the structure when encoded. */ unique_id_rec_size_uu = (unique_id_rec_total_size*8+5)/6; @@ -296,7 +296,7 @@ static void unique_id_child_init(server_rec *s, pool *p) cur_unique_id.counter = htons(cur_unique_id.counter); } -/* NOTE: This is *NOT* the same encoding used by uuencode ... the last two +/* NOTE: This is *NOT* the same encoding used by base64encode ... the last two * characters should be + and /. But those two characters have very special * meanings in URLs, and we want to make it easy to use identifiers in * URLs. So we replace them with @ and -. diff --git a/usr.sbin/httpd/src/modules/standard/mod_userdir.c b/usr.sbin/httpd/src/modules/standard/mod_userdir.c index 9aea9ce9dd2..5c0e26d2753 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_userdir.c +++ b/usr.sbin/httpd/src/modules/standard/mod_userdir.c @@ -262,7 +262,7 @@ static int translate_userdir(request_rec *r) if (userdir[0] == '\0' || ap_os_is_path_absolute(userdir)) { if (x) { -#ifdef WIN32 +#ifdef HAVE_DRIVE_LETTERS /* * Crummy hack. Need to figure out whether we have been * redirected to a URL or to a file on some drive. Since I diff --git a/usr.sbin/httpd/src/modules/standard/mod_usertrack.c b/usr.sbin/httpd/src/modules/standard/mod_usertrack.c index fbf800b4dab..1b50e159967 100644 --- a/usr.sbin/httpd/src/modules/standard/mod_usertrack.c +++ b/usr.sbin/httpd/src/modules/standard/mod_usertrack.c @@ -111,7 +111,12 @@ module MODULE_VAR_EXPORT usertrack_module; typedef struct { int always; time_t expires; -} cookie_log_state; +} cookie_log_state; + +typedef struct { + int enabled; + char *cookie_name; +} cookie_dir_rec; /* Define this to allow post-2000 cookies. Cookies use two-digit dates, * so it might be dicey. (Netscape does it correctly, but others may not) @@ -121,12 +126,12 @@ typedef struct { /* Make Cookie: Now we have to generate something that is going to be * pretty unique. We can base it on the pid, time, hostip */ -#define COOKIE_NAME "Apache=" +#define COOKIE_NAME "Apache" static void make_cookie(request_rec *r) { cookie_log_state *cls = ap_get_module_config(r->server->module_config, - &usertrack_module); + &usertrack_module); #if defined(NO_GETTIMEOFDAY) && !defined(NO_TIMES) clock_t mpe_times; struct tms mpe_tms; @@ -138,7 +143,10 @@ static void make_cookie(request_rec *r) char cookiebuf[1024]; char *new_cookie; const char *rname = ap_get_remote_host(r->connection, r->per_dir_config, - REMOTE_NAME); + REMOTE_NAME); + cookie_dir_rec *dcfg; + + dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module); #if defined(NO_GETTIMEOFDAY) && !defined(NO_TIMES) /* We lack gettimeofday(), so we must use time() to obtain the epoch @@ -147,7 +155,8 @@ static void make_cookie(request_rec *r) mpe_times = times(&mpe_tms); - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, (int) getpid(), + ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, + (int) getpid(), (long) r->request_time, (long) mpe_tms.tms_utime); #elif defined(WIN32) /* @@ -156,13 +165,15 @@ static void make_cookie(request_rec *r) * was started. It should be relatively unique. */ - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, (int) getpid(), + ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, + (int) getpid(), (long) r->request_time, (long) GetTickCount()); #else gettimeofday(&tv, &tz); - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%d", rname, (int) getpid(), + ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%d", rname, + (int) getpid(), (long) tv.tv_sec, (int) tv.tv_usec / 1000); #endif @@ -184,14 +195,16 @@ static void make_cookie(request_rec *r) /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */ new_cookie = ap_psprintf(r->pool, - "%s%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", - COOKIE_NAME, cookiebuf, ap_day_snames[tms->tm_wday], + "%s=%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", + dcfg->cookie_name, cookiebuf, ap_day_snames[tms->tm_wday], tms->tm_mday, ap_month_snames[tms->tm_mon], tms->tm_year % 100, tms->tm_hour, tms->tm_min, tms->tm_sec); } - else - new_cookie = ap_psprintf(r->pool, "%s%s; path=/", COOKIE_NAME, cookiebuf); + else { + new_cookie = ap_psprintf(r->pool, "%s=%s; path=/", + dcfg->cookie_name, cookiebuf); + } ap_table_setn(r->headers_out, "Set-Cookie", new_cookie); ap_table_setn(r->notes, "cookie", ap_pstrdup(r->pool, cookiebuf)); /* log first time */ @@ -200,19 +213,20 @@ static void make_cookie(request_rec *r) static int spot_cookie(request_rec *r) { - int *enable = (int *) ap_get_module_config(r->per_dir_config, - &usertrack_module); + cookie_dir_rec *dcfg = ap_get_module_config(r->per_dir_config, + &usertrack_module); const char *cookie; char *value; - if (!*enable) + if (!dcfg->enabled) { return DECLINED; + } if ((cookie = ap_table_get(r->headers_in, "Cookie"))) - if ((value = strstr(cookie, COOKIE_NAME))) { + if ((value = strstr(cookie, dcfg->cookie_name))) { char *cookiebuf, *cookieend; - value += strlen(COOKIE_NAME); + value += strlen(dcfg->cookie_name) + 1; /* Skip over the '=' */ cookiebuf = ap_pstrdup(r->pool, value); cookieend = strchr(cookiebuf, ';'); if (cookieend) @@ -221,7 +235,7 @@ static int spot_cookie(request_rec *r) /* Set the cookie in a note, for logging */ ap_table_setn(r->notes, "cookie", cookiebuf); - return DECLINED; /* Theres already a cookie, no new one */ + return DECLINED; /* There's already a cookie, no new one */ } make_cookie(r); return OK; /* We set our cookie */ @@ -239,12 +253,19 @@ static void *make_cookie_log_state(pool *p, server_rec *s) static void *make_cookie_dir(pool *p, char *d) { - return (void *) ap_pcalloc(p, sizeof(int)); + cookie_dir_rec *dcfg; + + dcfg = (cookie_dir_rec *) ap_pcalloc(p, sizeof(cookie_dir_rec)); + dcfg->cookie_name = COOKIE_NAME; + dcfg->enabled = 0; + return dcfg; } -static const char *set_cookie_enable(cmd_parms *cmd, int *c, int arg) +static const char *set_cookie_enable(cmd_parms *cmd, void *mconfig, int arg) { - *c = arg; + cookie_dir_rec *dcfg = mconfig; + + dcfg->enabled = arg; return NULL; } @@ -315,11 +336,21 @@ static const char *set_cookie_exp(cmd_parms *parms, void *dummy, const char *arg return NULL; } +static const char *set_cookie_name(cmd_parms *cmd, void *mconfig, char *name) +{ + cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig; + + dcfg->cookie_name = ap_pstrdup(cmd->pool, name); + return NULL; +} + static const command_rec cookie_log_cmds[] = { {"CookieExpires", set_cookie_exp, NULL, RSRC_CONF, TAKE1, - "an expiry date code"}, + "an expiry date code"}, {"CookieTracking", set_cookie_enable, NULL, OR_FILEINFO, FLAG, - "whether or not to enable cookies"}, + "whether or not to enable cookies"}, + {"CookieName", set_cookie_name, NULL, OR_FILEINFO, TAKE1, + "name of the tracking cookie"}, {NULL} }; diff --git a/usr.sbin/httpd/src/os/bs2000/Makefile.tmpl b/usr.sbin/httpd/src/os/bs2000/Makefile.tmpl index 962b6d624f0..e56c1b618ca 100644 --- a/usr.sbin/httpd/src/os/bs2000/Makefile.tmpl +++ b/usr.sbin/httpd/src/os/bs2000/Makefile.tmpl @@ -36,7 +36,49 @@ depend: && rm Makefile.new $(OBJS): Makefile -os.o: os.c os-inline.c -ebcdic.o: ebcdic.c + # DO NOT REMOVE -os.o: os.c +bs2login.o: bs2login.c +bs2login.o: $(INCDIR)/httpd.h +bs2login.o: $(INCDIR)/ap_config.h +bs2login.o: $(INCDIR)/ap_mmn.h +bs2login.o: $(INCDIR)/ap_config_auto.h +bs2login.o: os.h +bs2login.o: $(INCDIR)/ap_ctype.h +bs2login.o: $(INCDIR)/hsregex.h +bs2login.o: $(INCDIR)/alloc.h +bs2login.o: $(INCDIR)/buff.h +bs2login.o: $(INCDIR)/ap.h +bs2login.o: ebcdic.h +bs2login.o: $(INCDIR)/util_uri.h +bs2login.o: $(INCDIR)/http_config.h +bs2login.o: $(INCDIR)/http_log.h +ebcdic.o: ebcdic.c +ebcdic.o: $(INCDIR)/ap_config.h +ebcdic.o: $(INCDIR)/ap_mmn.h +ebcdic.o: $(INCDIR)/ap_config_auto.h +ebcdic.o: os.h +ebcdic.o: $(INCDIR)/ap_ctype.h +ebcdic.o: $(INCDIR)/hsregex.h +ebcdic.o: ebcdic.h +os-inline.o: os-inline.c +os-inline.o: $(INCDIR)/ap_config.h +os-inline.o: $(INCDIR)/ap_mmn.h +os-inline.o: $(INCDIR)/ap_config_auto.h +os-inline.o: os.h +os-inline.o: $(INCDIR)/ap_ctype.h +os-inline.o: $(INCDIR)/hsregex.h +os.o: os.c +os.o: $(INCDIR)/httpd.h +os.o: $(INCDIR)/ap_config.h +os.o: $(INCDIR)/ap_mmn.h +os.o: $(INCDIR)/ap_config_auto.h +os.o: os.h +os.o: $(INCDIR)/ap_ctype.h +os.o: $(INCDIR)/hsregex.h +os.o: $(INCDIR)/alloc.h +os.o: $(INCDIR)/buff.h +os.o: $(INCDIR)/ap.h +os.o: ebcdic.h +os.o: $(INCDIR)/util_uri.h +os.o: $(INCDIR)/http_core.h diff --git a/usr.sbin/httpd/src/os/bs2000/bs2login.c b/usr.sbin/httpd/src/os/bs2000/bs2login.c index f76c536221e..32eb1aecb00 100644 --- a/usr.sbin/httpd/src/os/bs2000/bs2login.c +++ b/usr.sbin/httpd/src/os/bs2000/bs2login.c @@ -66,6 +66,17 @@ #define USER_LEN 8 static const char *bs2000_account = NULL; +typedef enum +{ + bs2_unknown, /* not initialized yet. */ + bs2_noFORK, /* no fork() because -X flag was specified */ + bs2_FORK, /* only fork() because uid != 0 */ + bs2_FORK_RINI, /* prior to A17, regular fork() and _rini() was used. */ + bs2_RFORK_RINI, /* for A17, use of _rfork() and _rini() was required */ + bs2_UFORK /* As of A18, the new ufork() is used. */ +} bs2_ForkType; + +static bs2_ForkType forktype = bs2_unknown; static void ap_pad(char *dest, size_t size, char ch) @@ -86,6 +97,75 @@ static void ap_str_toupper(char *str) } } +/* Determine the method for forking off a child in such a way as to + * set both the POSIX and BS2000 user id's to the unprivileged user. + */ +static bs2_ForkType os_forktype(void) +{ + struct utsname os_version; + + /* have we checked the OS version before? If yes return the previous + * result - the OS release isn't going to change suddenly! + */ + if (forktype != bs2_unknown) { + return forktype; + } + + /* If the user is unprivileged, use the normal fork() only. */ + if (getuid() != 0) { + return forktype = bs2_FORK; + } + + if (uname(&os_version) < 0) + { + ap_log_error(APLOG_MARK, APLOG_ALERT, NULL, + "uname() failed - aborting."); + exit(APEXIT_CHILDFATAL); + } + + /* + * Old BS2000/OSD versions (before XPG4 SPEC1170) don't work with Apache. + * Anyway, simply return a fork(). + */ + if (strcmp(os_version.release, "01.0A") == 0 || + strcmp(os_version.release, "02.0A") == 0 || + strcmp(os_version.release, "02.1A") == 0) + { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL, + "Error: unsupported OS version. " + "You may encounter problems."); + forktype = bs2_FORK; + } + + /* The following versions are special: + * OS versions before A17 needs regular fork() and _rini(). + * A17 requires _rfork() and _rini(), + * and later versions need ufork(). + */ + else if (strcmp(os_version.release, "01.1A") == 0 || + strcmp(os_version.release, "03.0A") == 0 || + strcmp(os_version.release, "03.1A") == 0 || + strcmp(os_version.release, "04.0A") == 0) + { + if (strcmp (os_version.version, "A18") >= 0) + forktype = bs2_UFORK; + + else if (strcmp (os_version.version, "A17") < 0) + forktype = bs2_FORK_RINI; + + else + forktype = bs2_RFORK_RINI; + } + + /* All later OS versions will hopefully use ufork() only ;-) */ + else + forktype = bs2_UFORK; + + return forktype; +} + + + /* This routine is called by http_core for the BS2000Account directive */ /* It stores the account name for later use */ const char *os_set_account(pool *p, const char *account) @@ -113,6 +193,7 @@ int os_init_job_environment(server_rec *server, const char *user_name, int one_p _rini_struct inittask; char username[USER_LEN+1]; int save_errno; + bs2_ForkType type = os_forktype(); /* We can be sure that no change to uid==0 is possible because of * the checks in http_core.c:set_user() @@ -121,6 +202,20 @@ int os_init_job_environment(server_rec *server, const char *user_name, int one_p /* The _rini() function works only after a prior _rfork(). * In the case of one_process, it would fail. */ + if (one_process) { + + type = forktype = bs2_noFORK; + + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, server, + "The debug mode of Apache should only " + "be started by an unprivileged user!"); + return 0; + } + + /* If no _rini() is required, then return quickly. */ + if (type != bs2_RFORK_RINI && type != bs2_FORK_RINI) + return 0; + /* An Account is required for _rini() */ if (bs2000_account == NULL) { @@ -130,16 +225,6 @@ int os_init_job_environment(server_rec *server, const char *user_name, int one_p exit(APEXIT_CHILDFATAL); } - /* The one_process test is placed _behind_ the BS2000Account test - * because we never want the user to forget configuring an account. - */ - if (one_process) { - ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, server, - "The debug mode of Apache should only " - "be started by an unprivileged user!"); - return 0; - } - ap_cpystrn(username, user_name, sizeof username); /* Make user name all upper case */ @@ -153,34 +238,13 @@ int os_init_job_environment(server_rec *server, const char *user_name, int one_p inittask.processor_name = " "; /* Switch to the new logon user (setuid() and setgid() are done later) */ - /* Only the super use can switch identities. */ + /* Only the super user can switch identities. */ if (_rini(&inittask) != 0) { - save_errno = errno; ap_log_error(APLOG_MARK, APLOG_ALERT, server, "_rini: BS2000 auth failed for user \"%s\" acct \"%s\"", inittask.username, inittask.account); - if (save_errno == EAGAIN) { - /* This funny error code does NOT mean that the operation should - * be retried. Instead it means that authentication failed - * because of possibly incompatible `JOBCLASS'es between - * the calling (SYSROOT) and the target non-privileged user id. - * Help the administrator by logging a hint. - */ - char *curr_user, curr_uid[L_cuserid]; - - if ((curr_user = cuserid(curr_uid)) == NULL) { - /* This *SHOULD* not occur. But if it does, deal with it. */ - ap_snprintf(curr_uid, sizeof curr_uid, "#%u", getuid()); - curr_user = curr_uid; - } - - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, server, - "_rini: Hint: Possible reason: JOBCLASS of user %s " - "not compatible with that of user %s ?", - curr_user, inittask.username); - } exit(APEXIT_CHILDFATAL); } @@ -188,51 +252,42 @@ int os_init_job_environment(server_rec *server, const char *user_name, int one_p } /* BS2000 requires a "special" version of fork() before a setuid()/_rini() call */ -/* Additionally, there's an OS release dependency here :-((( */ -/* I'm sorry, but there was no other way to make it work. -Martin */ -pid_t os_fork(void) +pid_t os_fork(const char *user) { - struct utsname os_version; - - /* - * When we run as a normal user (and bypass setuid() and _rini()), - * we use the regular fork(). - */ - if (getuid() != 0) { - return fork(); - } - - if (uname(&os_version) >= 0) - { - /* - * Old versions (before XPG4 SPEC1170) don't work with Apache - * and they require a fork(), not a _rfork() - */ - if (strcmp(os_version.release, "01.0A") == 0 || - strcmp(os_version.release, "02.0A") == 0 || - strcmp(os_version.release, "02.1A") == 0) - { - return fork(); + pid_t pid; + char username[USER_LEN+1]; + + switch (os_forktype()) { + case bs2_FORK: + case bs2_FORK_RINI: + pid = fork(); + break; + + case bs2_RFORK_RINI: + pid = _rfork(); + break; + + case bs2_UFORK: + ap_cpystrn(username, user, sizeof username); + + /* Make user name all upper case - for some versions of ufork() */ + ap_str_toupper(username); + + pid = ufork(username); + if (pid == -1 && errno == EPERM) { + ap_log_error(APLOG_MARK, APLOG_EMERG, + NULL, "ufork: Possible mis-configuration " + "for user %s - Aborting.", user); + exit(1); } + break; - /* The following versions are special: - * OS versions before A17 work with regular fork() only, - * later versions with _rfork() only. - */ - if (strcmp(os_version.release, "01.1A") == 0 || - strcmp(os_version.release, "03.0A") == 0 || - strcmp(os_version.release, "03.1A") == 0 || - strcmp(os_version.release, "04.0A") == 0) - { - return (strcmp (os_version.version, "A17") < 0) - ? fork() : _rfork(); - } + default: + pid = 0; + break; } - /* All later OS versions will require _rfork() - * to prepare for authorization with _rini() - */ - return _rfork(); + return pid; } #else /* _OSD_POSIX */ diff --git a/usr.sbin/httpd/src/os/bs2000/os.h b/usr.sbin/httpd/src/os/bs2000/os.h index 93be8ee3d20..1ede0813f2e 100644 --- a/usr.sbin/httpd/src/os/bs2000/os.h +++ b/usr.sbin/httpd/src/os/bs2000/os.h @@ -9,8 +9,6 @@ * and prototypes of OS specific functions defined in os.c or os-inline.c */ -#include "ap_config.h" - #if !defined(INLINE) && defined(USE_GNU_INLINE) /* Compiler supports inline, so include the inlineable functions as * part of the header @@ -32,11 +30,22 @@ extern int ap_os_is_path_absolute(const char *file); /* Other ap_os_ routines not used by this platform */ #define ap_os_is_filename_valid(f) (1) +#define ap_os_kill(pid, sig) kill(pid, sig) + +#if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) +typedef struct { + char *username; + char *account; + char *processor_name; +} _rini_struct; + +extern int _rini(_rini_struct *); +#endif /* !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) */ /* Sorry if this is ugly, but the include order doesn't allow me * to use request_rec here... */ struct request_rec; extern int ap_checkconv(struct request_rec *r); -extern pid_t os_fork(void); +extern pid_t os_fork(const char *user); #endif /*! APACHE_OS_H*/ diff --git a/usr.sbin/httpd/src/os/os2/Makefile.tmpl b/usr.sbin/httpd/src/os/os2/Makefile.tmpl index 2d182cef79c..98e96aaf844 100644 --- a/usr.sbin/httpd/src/os/os2/Makefile.tmpl +++ b/usr.sbin/httpd/src/os/os2/Makefile.tmpl @@ -8,13 +8,7 @@ COPY= os.h os-inline.c LIB= libos.a -all: $(LIB) copy - -copy: - for i in $(COPY); do \ - rm -f $(INCDIR)/$$i ;\ - cp `pwd`/$$i $(INCDIR)/$$i ;\ - done +all: $(LIB) $(LIB): $(OBJS) rm -f $@ @@ -33,6 +27,12 @@ distclean: clean $(OBJS): Makefile +$(INCDIR)/os.h: os.h + cp $< $@ + +$(INCDIR)/os-inline.c: os-inline.c + cp $< $@ + # We really don't expect end users to use this rule. It works only with # gcc, and rebuilds Makefile.tmpl. You have to re-run Configure after # using it. @@ -46,4 +46,12 @@ depend: && rm Makefile.new # DO NOT REMOVE -os.o: os.c os-inline.c +os-inline.o: os-inline.c $(INCDIR)/ap_config.h \ + $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ + $(INCDIR)/os.h $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h +os.o: os.c os.h os-inline.c +util_os2.o: util_os2.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ + $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ + $(INCDIR)/os.h $(INCDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ + $(INCDIR)/hsregex.h $(INCDIR)/alloc.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h $(INCDIR)/http_log.h diff --git a/usr.sbin/httpd/src/os/os2/os.c b/usr.sbin/httpd/src/os/os2/os.c index 2b5de32e46e..4a45c1fd26e 100644 --- a/usr.sbin/httpd/src/os/os2/os.c +++ b/usr.sbin/httpd/src/os/os2/os.c @@ -4,3 +4,55 @@ */ #include "os.h" +#define INCL_DOS +#include <os2.h> +#include <stdio.h> + +static int rc=0; + +void ap_os_dso_init(void) +{ +} + + + +ap_os_dso_handle_t ap_os_dso_load(const char *module_name) +{ + char errorstr[200]; + HMODULE handle; + + rc = DosLoadModule(errorstr, sizeof(errorstr), module_name, &handle); + + if (rc == 0) + return handle; + + return 0; +} + + + +void ap_os_dso_unload(ap_os_dso_handle_t handle) +{ + DosFreeModule(handle); +} + + + +void *ap_os_dso_sym(ap_os_dso_handle_t handle, const char *funcname) +{ + PFN func; + + rc = DosQueryProcAddr( handle, 0, funcname, &func ); + + if (rc == 0) + return func; + + return NULL; +} + + + +const char *ap_os_dso_error(void) +{ + return ap_os_error_message(rc); +} diff --git a/usr.sbin/httpd/src/os/os2/os.h b/usr.sbin/httpd/src/os/os2/os.h index 0aa5a6f1fe2..d717f1f8ca4 100644 --- a/usr.sbin/httpd/src/os/os2/os.h +++ b/usr.sbin/httpd/src/os/os2/os.h @@ -3,6 +3,7 @@ #define PLATFORM "OS/2" #define HAVE_CANONICAL_FILENAME +#define HAVE_DRIVE_LETTERS /* * This file in included in all Apache source code. It contains definitions @@ -31,7 +32,21 @@ extern int ap_os_is_path_absolute(const char *file); /* FIXME: the following should be implemented on this platform */ #define ap_os_is_filename_valid(f) (1) +/* Use a specialized kill() function */ +int ap_os_kill(int pid, int sig); + +/* Maps an OS error code to an error message */ +char *ap_os_error_message(int err); + /* OS/2 doesn't have symlinks so S_ISLNK is always false */ #define S_ISLNK(m) 0 +/* Dynamic loading functions */ +#define ap_os_dso_handle_t unsigned long +void ap_os_dso_init(void); +ap_os_dso_handle_t ap_os_dso_load(const char *); +void ap_os_dso_unload(ap_os_dso_handle_t); +void * ap_os_dso_sym(ap_os_dso_handle_t, const char *); +const char *ap_os_dso_error(void); + #endif /* ! APACHE_OS_H */ diff --git a/usr.sbin/httpd/src/os/os2/util_os2.c b/usr.sbin/httpd/src/os/os2/util_os2.c index 91fe4d444b5..820ea618008 100644 --- a/usr.sbin/httpd/src/os/os2/util_os2.c +++ b/usr.sbin/httpd/src/os/os2/util_os2.c @@ -1,4 +1,5 @@ -#define INCL_DOSFILEMGR +#define INCL_DOS +#define INCL_DOSERRORS #include <os2.h> #include "httpd.h" #include "http_log.h" @@ -19,7 +20,16 @@ API_EXPORT(char *)ap_os_canonical_filename(pool *pPool, const char *szFile) buf[--len] = 0; rc = DosQueryPathInfo(buf, FIL_QUERYFULLNAME, buf2, HUGE_STRING_LEN); - ap_assert(rc == 0); + + if (rc) { + if ( rc != ERROR_INVALID_NAME ) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, NULL, "OS/2 error %d for file %s", rc, szFile); + return ap_pstrdup(pPool, ""); + } else { + return ap_pstrdup(pPool, szFile); + } + } + strlwr(buf2); /* Switch backslashes to forward */ @@ -29,3 +39,58 @@ API_EXPORT(char *)ap_os_canonical_filename(pool *pPool, const char *szFile) return ap_pstrdup(pPool, buf2); } + + + +int ap_os_kill(pid_t pid, int sig) +{ +/* SIGTERM's don't work too well in OS/2 (only affects other EMX programs). + CGIs may not be, esp. REXX scripts, so use a native call instead */ + + int rc; + + if ( sig == SIGTERM ) { + rc = DosSendSignalException( pid, XCPT_SIGNAL_BREAK ); + + if ( rc ) { + errno = ESRCH; + rc = -1; + } + } else { + rc = kill(pid, sig); + } + + return rc; +} + + + +char *ap_os_error_message(int err) +{ + static char result[200]; + char message[HUGE_STRING_LEN]; + ULONG len; + char *pos; + int c; + + if (DosGetMessage(NULL, 0, message, HUGE_STRING_LEN, err, "OSO001.MSG", &len) == 0) { + len--; + message[len] = 0; + pos = result; + + if (len >= sizeof(result)) + len = sizeof(result-1); + + for (c=0; c<len; c++) { + while (isspace(message[c]) && isspace(message[c+1])) /* skip multiple whitespace */ + c++; + *(pos++) = isspace(message[c]) ? ' ' : message[c]; + } + + *pos = 0; + } else { + sprintf(result, "OS/2 error %d", err); + } + + return result; +} diff --git a/usr.sbin/httpd/src/os/tpf/Makefile.tmpl b/usr.sbin/httpd/src/os/tpf/Makefile.tmpl index ad54c1b84a4..14aa0899b1f 100644 --- a/usr.sbin/httpd/src/os/tpf/Makefile.tmpl +++ b/usr.sbin/httpd/src/os/tpf/Makefile.tmpl @@ -3,7 +3,7 @@ LIBS=$(EXTRA_LIBS) $(LIBS1) INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES) LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS) -OBJS= os.o os-inline.o ebcdic.o +OBJS= os.o os-inline.o ebcdic.o cgetop.o LIB= libos.a @@ -35,7 +35,8 @@ depend: && rm Makefile.new $(OBJS): Makefile -os.o: os.c os-inline.c +os.o: os.c os-inline.c $(INCDIR)/ap_config.h ebcdic.o: ebcdic.c +cgetop.o: cgetop.c # DO NOT REMOVE os.o: os.c diff --git a/usr.sbin/httpd/src/os/tpf/os.c b/usr.sbin/httpd/src/os/tpf/os.c index aea4d961f4e..e4682324cd1 100644 --- a/usr.sbin/httpd/src/os/tpf/os.c +++ b/usr.sbin/httpd/src/os/tpf/os.c @@ -63,6 +63,11 @@ #include "httpd.h" #include "http_core.h" #include "os.h" +#include "scoreboard.h" +#include "http_log.h" +#include "http_conf_globals.h" + +static FILE *sock_fp; /* Check the Content-Type to decide if conversion is needed */ int ap_checkconv(struct request_rec *r) @@ -87,14 +92,22 @@ int ap_checkconv(struct request_rec *r) if (type && (strncasecmp(type, "text/", 5) == 0 || strncasecmp(type, "message/", 8) == 0)) { if (strncasecmp(type, ASCIITEXT_MAGIC_TYPE_PREFIX, - sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0) + sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0){ r->content_type = ap_pstrcat(r->pool, "text/", - type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1, - NULL); + type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1, NULL); + if (r->method_number == M_PUT) + ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, 0); + } + else /* translate EBCDIC to ASCII */ convert_to_ascii = 1; } + else{ + if (r->method_number == M_PUT) + ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, 0); + /* don't translate non-text files to EBCDIC */ + } /* Enable conversion if it's a text document */ ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert_to_ascii); @@ -103,51 +116,65 @@ int ap_checkconv(struct request_rec *r) int tpf_select(int maxfds, fd_set *reads, fd_set *writes, fd_set *excepts, struct timeval *tv) { - int sockets[24]; +/* We're going to force our way through select. We're only interested reads and TPF allows + 2billion+ socket descriptors for we don't want an fd_set that big. Just assume that maxfds-1 + contains the socket descriptor we're interested in. If it's 0, leave it alone. */ + + int sockets[1]; int no_reads = 0; int no_writes = 0; int no_excepts = 0; int timeout = 0; - int counter = 0; - int i; - fd_set *temp; + int rv; if(maxfds) { - if(reads) - temp = reads; - else if(writes) - temp = writes; - else if(excepts) - temp = excepts; + if(tv) + timeout = tv->tv_sec * 1000 + tv->tv_usec; + sockets[0] = maxfds-1; + no_reads++; + } else - temp = NULL; + sockets[0] = 0; - for(i=0; i<maxfds; i++) { - if(FD_ISSET(i,temp)) { - sockets[counter] = i; - counter++; - } - } + ap_check_signals(); + rv = select(sockets, no_reads, no_writes, no_excepts, timeout); + ap_check_signals(); - if(tv) - timeout = tv->tv_sec * 1000 + tv->tv_usec; + return rv; + +} - if(reads) - no_reads = counter; - else if(writes) - no_writes = counter; - else if(excepts) - no_excepts = counter; +int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen) +{ + int socks[1]; + int rv; + + ap_check_signals(); + socks[0] = sockfd; + rv = select(socks, 1, 0, 0, 1000); + errno = sock_errno(); + if(rv>0) { + ap_check_signals(); + rv = accept(sockfd, peer, paddrlen); + errno = sock_errno(); } - return select(sockets, no_reads, no_writes, no_excepts, timeout); + return rv; } -/* pipe is not yet available on TPF */ +/* the getpass function is not usable on TPF */ +char *getpass(const char* prompt) +{ + errno = EIO; + return((char *)NULL); +} + +#ifndef __PIPE_ int pipe(int fildes[2]) { errno = ENOSYS; return(-1); } +#endif /* fork and exec functions are not defined on TPF due to the implementation of tpf_fork() */ @@ -175,3 +202,213 @@ int execve(const char *path, char *const argv[], char *const envp[]) errno = ENOSYS; return(-1); } + +int execvp(const char *file, char *const argv[]) +{ + errno = ENOSYS; + return(-1); +} + + + +int ap_tpf_spawn_child(pool *p, int (*func) (void *, child_info *), + void *data, enum kill_conditions kill_how, + int *pipe_in, int *pipe_out, int *pipe_err, + int out_fds[], int in_fds[], int err_fds[]) + +{ + + int i, temp_out, temp_in, temp_err, save_errno, pid, result=0; + int fd_flags_out, fd_flags_in, fd_flags_err; + struct tpf_fork_input fork_input; + TPF_FORK_CHILD *cld = (TPF_FORK_CHILD *) data; + array_header *env_arr = ap_table_elts ((array_header *) cld->subprocess_env); + table_entry *elts = (table_entry *) env_arr->elts; + + + + if (func) { + if (result=func(data, NULL)) { + return 0; /* error from child function */ + } + } + + if (pipe_out) { + fd_flags_out = fcntl(out_fds[0], F_GETFD); + fcntl(out_fds[0], F_SETFD, FD_CLOEXEC); + temp_out = dup(STDOUT_FILENO); + fcntl(temp_out, F_SETFD, FD_CLOEXEC); + dup2(out_fds[1], STDOUT_FILENO); + } + + + if (pipe_in) { + fd_flags_in = fcntl(in_fds[1], F_GETFD); + fcntl(in_fds[1], F_SETFD, FD_CLOEXEC); + temp_in = dup(STDIN_FILENO); + fcntl(temp_in, F_SETFD, FD_CLOEXEC); + dup2(in_fds[0], STDIN_FILENO); + } + + if (pipe_err) { + fd_flags_err = fcntl(err_fds[0], F_GETFD); + fcntl(err_fds[0], F_SETFD, FD_CLOEXEC); + temp_err = dup(STDERR_FILENO); + fcntl(temp_err, F_SETFD, FD_CLOEXEC); + dup2(err_fds[1], STDERR_FILENO); + } + + if (cld->subprocess_env) { + for (i = 0; i < env_arr->nelts; ++i) { + if (!elts[i].key) + continue; + setenv (elts[i].key, elts[i].val, 1); + } + } + + fork_input.program = (const char*) cld->filename; + fork_input.prog_type = cld->prog_type; + fork_input.istream = TPF_FORK_IS_BALANCE; + fork_input.ebw_data_length = 0; + fork_input.ebw_data = NULL; + fork_input.parm_data = NULL; + + + if ((pid = tpf_fork(&fork_input)) < 0) { + save_errno = errno; + if (pipe_out) { + close(out_fds[0]); + } + if (pipe_in) { + close(in_fds[1]); + } + if (pipe_err) { + close(err_fds[0]); + } + errno = save_errno; + pid = 0; + } + + if (cld->subprocess_env) { + for (i = 0; i < env_arr->nelts; ++i) { + if (!elts[i].key) + continue; + unsetenv (elts[i].key); + } + } + + if (pipe_out) { + close(out_fds[1]); + dup2(temp_out, STDOUT_FILENO); + close(temp_out); + fcntl(out_fds[0], F_SETFD, fd_flags_out); + } + + if (pipe_in) { + close(in_fds[0]); + dup2(temp_in, STDIN_FILENO); + close(temp_in); + fcntl(in_fds[1], F_SETFD, fd_flags_in); + } + + + if (pipe_err) { + close(err_fds[1]); + dup2(temp_err, STDERR_FILENO); + close(temp_err); + fcntl(err_fds[0], F_SETFD, fd_flags_err); + } + + + if (pid) { + + ap_note_subprocess(p, pid, kill_how); + + if (pipe_out) { + *pipe_out = out_fds[0]; + } + if (pipe_in) { + *pipe_in = in_fds[1]; + } + if (pipe_err) { + *pipe_err = err_fds[0]; + } + } + + return pid; + +} + +pid_t os_fork(server_rec *s, int slot) +{ + struct tpf_fork_input fork_input; + APACHE_TPF_INPUT input_parms; + int count; + listen_rec *lr; + + fflush(stdin); + if (dup2(fileno(sock_fp), STDIN_FILENO) == -1) + ap_log_error(APLOG_MARK, APLOG_CRIT, s, + "unable to replace stdin with sock device driver"); + fflush(stdout); + if (dup2(fileno(sock_fp), STDOUT_FILENO) == -1) + ap_log_error(APLOG_MARK, APLOG_CRIT, s, + "unable to replace stdout with sock device driver"); + input_parms.generation = ap_my_generation; +#ifdef SCOREBOARD_FILE + input_parms.scoreboard_fd = scoreboard_fd; +#else /* must be USE_TPF_SCOREBOARD or USE_SHMGET_SCOREBOARD */ + input_parms.scoreboard_heap = ap_scoreboard_image; +#endif + + lr = ap_listeners; + count = 0; + do { + input_parms.listeners[count] = lr->fd; + lr = lr->next; + count++; + } while(lr != ap_listeners); + + input_parms.slot = slot; + input_parms.restart_time = ap_restart_time; + fork_input.ebw_data = &input_parms; + fork_input.program = ap_server_argv0; + fork_input.prog_type = TPF_FORK_NAME; + fork_input.istream = TPF_FORK_IS_BALANCE; + fork_input.ebw_data_length = sizeof(input_parms); + fork_input.parm_data = "-x"; + return tpf_fork(&fork_input); +} + +int os_check_server(char *server) { + #ifndef USE_TPF_DAEMON + int rv; + int *current_acn; + if((rv = inetd_getServerStatus(server)) == INETD_SERVER_STATUS_INACTIVE) + return 1; + else { + current_acn = (int *)cinfc_fast(CINFC_CMMACNUM); + if(ecbp2()->ce2acn != *current_acn) + return 1; + } + #endif + return 0; +} + +void os_note_additional_cleanups(pool *p, int sd) { + char sockfilename[50]; + /* write the socket to file so that TPF socket device driver will close socket in case + we happen to abend. */ + sprintf(sockfilename, "/dev/tpf.socket.file/%.8X", sd); + sock_fp = fopen(sockfilename, "r+"); + ap_note_cleanups_for_file(p, sock_fp); /* arrange to close on exec or restart */ + fcntl(sd,F_SETFD,FD_CLOEXEC); +} + +void os_tpf_child(APACHE_TPF_INPUT *input_parms) { + tpf_child = 1; + ap_my_generation = input_parms->generation; + ap_restart_time = input_parms->restart_time; +} + + diff --git a/usr.sbin/httpd/src/os/tpf/os.h b/usr.sbin/httpd/src/os/tpf/os.h index 9a94bcc96c2..ff653229029 100644 --- a/usr.sbin/httpd/src/os/tpf/os.h +++ b/usr.sbin/httpd/src/os/tpf/os.h @@ -20,9 +20,6 @@ * part of the header */ #define INLINE extern ap_inline - -INLINE int ap_os_is_path_absolute(const char *file); - #include "os-inline.c" #endif @@ -30,82 +27,82 @@ INLINE int ap_os_is_path_absolute(const char *file); /* Compiler does not support inline, so prototype the inlineable functions * as normal */ -extern int ap_os_is_path_absolute(const char *file); +extern int ap_os_is_path_absolute(const char *f); #endif /* Other ap_os_ routines not used by this platform */ #define ap_os_is_filename_valid(f) (1) +#define ap_os_kill(pid, sig) kill(pid, sig) /* Sorry if this is ugly, but the include order doesn't allow me * to use request_rec here... */ struct request_rec; extern int ap_checkconv(struct request_rec *r); -#ifdef FD_SETSIZE -#undef FD_SETSIZE -#endif +#include <strings.h> +#ifndef __strings_h #define FD_SETSIZE 2048 -#ifdef __FD_MASK -#undef __FD_MASK -#endif - -typedef long __FD_MASK; - -#ifdef __NBBY -#undef __NBBY -#endif - -#define __NBBY 8 /* number of bits in a byte */ - -#ifdef __NFDBITS -#undef __NFDBITS -#endif +typedef long fd_mask; -#define __NFDBITS (sizeof(__FD_MASK) * __NBBY) +#define NBBY 8 /* number of bits in a byte */ +#define NFDBITS (sizeof(fd_mask) * NBBY) +#define howmany(x, y) (((x)+((y)-1))/(y)) -#ifndef __howmany -#define __howmany(x, y) (((x)+((y)-1))/(y)) -#endif - typedef struct fd_set { - __FD_MASK fds_bits [__howmany(FD_SETSIZE, __NFDBITS)]; + fd_mask fds_bits [howmany(FD_SETSIZE, NFDBITS)]; } fd_set; -#define FD_SET(n, p)((p)->fds_bits[(n)/__NFDBITS] |= (1 <<((n) % __NFDBITS))) - -#define FD_CLR(n, p)((p)->fds_bits[(n)/__NFDBITS] &= ~(1 << ((n) % __NFDBITS))) - -#define FD_ISSET(n, p)((p)->fds_bits[(n)/__NFDBITS] & (1 <<((n) % __NFDBITS))) - +#define FD_CLR(n, p)((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p)((p)->fds_bits[(n)/NFDBITS] & (1 <<((n) % NFDBITS))) #define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p))) +#endif +#ifdef FD_SET +#undef FD_SET +#define FD_SET(n, p) (0) +#endif -#define SIGPIPE 13 -#define SIGQUIT 24 -#define SO_KEEPALIVE 0x0008 +#define RESOURCE_KEY ((void*) 0xC1C2C1C3) /* TPF doesn't have, or need, tzset (it is used in mod_expires.c) */ #define tzset() -#include <stdarg.h> -#undef va_list -#undef va_start -#undef va_arg -#undef va_end - -typedef char *va_list; - -#define __va_promote(type) (((sizeof(type) + sizeof(int) - 1) \ - / sizeof(int)) * sizeof(int)) - -#define va_start(ap, last) (ap = ((char *)&(last) + __va_promote(last))) - -#define va_arg(ap, type) ((type *)(ap += sizeof(type) < sizeof(int) ? \ - (abort(), 0) : sizeof(type)))[-1] - -#define va_end(ap) - +#include <i$netd.h> +struct apache_input { + INETD_SERVER_INPUT inetd_server; + void *scoreboard_heap; /* scoreboard system heap address */ + int scoreboard_fd; /* scoreboard file descriptor */ + int slot; /* child number */ + int generation; /* server generation number */ + int listeners[10]; + time_t restart_time; +}; + +typedef struct apache_input APACHE_TPF_INPUT; + +typedef struct tpf_fork_child { + char *filename; + enum { FORK_NAME = 1, FORK_FILE = 2 } prog_type; + void *subprocess_env; +}TPF_FORK_CHILD; + +int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen); +extern int tpf_child; + +struct server_rec; +pid_t os_fork(struct server_rec *s, int slot); +int os_check_server(char *server); +char *getpass(const char *prompt); +extern char *ap_server_argv0; +extern int scoreboard_fd; +#include <signal.h> +#ifndef SIGPIPE +#define SIGPIPE 14 +#endif +#ifdef NSIG +#undef NSIG +#endif #endif /*! APACHE_OS_H*/ diff --git a/usr.sbin/httpd/src/os/unix/os.c b/usr.sbin/httpd/src/os/unix/os.c index 776b3c7e19d..18a0395da62 100644 --- a/usr.sbin/httpd/src/os/unix/os.c +++ b/usr.sbin/httpd/src/os/unix/os.c @@ -26,8 +26,15 @@ void ap_is_not_here(void) {} * dynamic shared object (DSO) mechanism */ -#ifdef RHAPSODY +#ifdef HAVE_DYLD /* NeXT/Apple dynamic linker */ #include <mach-o/dyld.h> + +/* + * NSUnlinkModule() is a noop in old versions of dyld. + * Let's install an error handler to deal with "multiply defined + * symbol" runtime errors. + */ +#ifdef DYLD_CANT_UNLOAD #include "httpd.h" #include "http_log.h" @@ -49,7 +56,6 @@ NSModule multiple_symbol_handler (NSSymbol s, NSModule old, NSModule new) * every time we reload a module. Workaround here is to just * rebind to the new symbol, and forget about the old one. * This is crummy, because it's basically a memory leak. - * (See Radar 2262020 against dyld). */ #ifdef DEBUG @@ -73,11 +79,12 @@ void linkEdit_symbol_handler (NSLinkEditErrors c, int errorNumber, abort(); } -#endif /*RHAPSODY*/ +#endif /* DYLD_CANT_UNLOAD */ +#endif /* HAVE_DYLD */ void ap_os_dso_init(void) { -#if defined(RHAPSODY) +#if defined(HAVE_DYLD) && defined(DYLD_CANT_UNLOAD) NSLinkEditErrorHandlers handlers; handlers.undefined = undefined_symbol_handler; @@ -95,14 +102,14 @@ void *ap_os_dso_load(const char *path) handle = shl_load(path, BIND_IMMEDIATE|BIND_VERBOSE|BIND_NOSTART, 0L); return (void *)handle; -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) NSObjectFileImage image; if (NSCreateObjectFileImageFromFile(path, &image) != NSObjectFileImageSuccess) return NULL; return NSLinkModule(image, path, TRUE); -#elif defined(OSF1) ||\ +#elif defined(OSF1) || defined(SEQUENT) ||\ (defined(__FreeBSD_version) && (__FreeBSD_version >= 220000)) return dlopen((char *)path, RTLD_NOW | RTLD_GLOBAL); @@ -116,7 +123,7 @@ void ap_os_dso_unload(void *handle) #if defined(HPUX) || defined(HPUX10) shl_unload((shl_t)handle); -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) NSUnLinkModule(handle,FALSE); #else @@ -138,7 +145,7 @@ void *ap_os_dso_sym(void *handle, const char *symname) status = shl_findsym((shl_t *)&handle, symname, TYPE_DATA, &symaddr); return (status == -1 ? NULL : symaddr); -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) NSSymbol symbol; char *symname2 = (char*)malloc(sizeof(char)*(strlen(symname)+2)); sprintf(symname2, "_%s", symname); @@ -154,6 +161,9 @@ void *ap_os_dso_sym(void *handle, const char *symname) free(symbol); return retval; +#elif defined(SEQUENT) + return dlsym(handle, (char *)symname); + #else return dlsym(handle, symname); #endif @@ -163,7 +173,7 @@ const char *ap_os_dso_error(void) { #if defined(HPUX) || defined(HPUX10) return strerror(errno); -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) return NULL; #else return dlerror(); diff --git a/usr.sbin/httpd/src/os/unix/os.h b/usr.sbin/httpd/src/os/unix/os.h index 496cfa9f9e8..6689dfae5c6 100644 --- a/usr.sbin/httpd/src/os/unix/os.h +++ b/usr.sbin/httpd/src/os/unix/os.h @@ -60,7 +60,9 @@ #include "ap_config.h" +#ifndef PLATFORM #define PLATFORM "Unix" +#endif /* * This file in included in all Apache source code. It contains definitions @@ -89,6 +91,7 @@ extern int ap_os_is_path_absolute(const char *file); /* Other ap_os_ routines not used by this platform */ #define ap_os_is_filename_valid(f) (1) +#define ap_os_kill(pid, sig) kill(pid, sig) /* * Abstraction layer for loading diff --git a/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.dsp b/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.dsp index 91de834bc45..4a0ffd1bf68 100644 --- a/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.dsp +++ b/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.dsp @@ -45,7 +45,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -55,7 +55,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 ..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /machine:I386 !ELSEIF "$(CFG)" == "ApacheModuleRewrite - Win32 Debug" @@ -71,7 +71,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -81,7 +81,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 ..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 !ENDIF diff --git a/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.mak b/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.mak index cd9de2327c6..6d2e5659088 100644 --- a/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.mak +++ b/usr.sbin/httpd/src/os/win32/ApacheModuleRewrite.mak @@ -64,7 +64,7 @@ CLEAN : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MD /W3 /GX /O2 /I "..\..\include" /D "NDEBUG" /D "WIN32" /D\ - "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE"\ + "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /D "WIN32_LEAN_AND_MEAN"\ /Fp"$(INTDIR)\ApacheModuleRewrite.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\"\ /FD /c CPP_OBJS=.\ApacheModuleRewriteR/ @@ -76,7 +76,7 @@ BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=..\..\CoreR\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ - winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo\ /subsystem:windows /dll /incremental:no\ /pdb:"$(OUTDIR)\ApacheModuleRewrite.pdb" /machine:I386\ /out:"$(OUTDIR)\ApacheModuleRewrite.dll"\ @@ -123,9 +123,9 @@ CLEAN : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "_DEBUG" /D\ - "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE"\ - /Fp"$(INTDIR)\ApacheModuleRewrite.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\"\ - /FD /c + "WIN32" /D "_WINDOWS" /D "NO_DBM_REWRITEMAP" /D "SHARED_MODULE" /D\ + "WIN32_LEAN_AND_MEAN" /Fp"$(INTDIR)\ApacheModuleRewrite.pch" /YX\ + /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\ApacheModuleRewriteD/ CPP_SBRS=. MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 @@ -135,7 +135,7 @@ BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=..\..\CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ - winspool.lib comdlg32.lib advapi32.lib shell32.lib wsock32.lib /nologo\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo\ /subsystem:windows /dll /incremental:yes\ /pdb:"$(OUTDIR)\ApacheModuleRewrite.pdb" /debug /machine:I386\ /out:"$(OUTDIR)\ApacheModuleRewrite.dll"\ @@ -191,18 +191,21 @@ SOURCE=..\..\modules\standard\mod_rewrite.c DEP_CPP_MOD_R=\ "..\..\include\alloc.h"\ "..\..\include\ap.h"\ + "..\..\include\ap_config.h"\ + "..\..\include\ap_ctype.h"\ "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ - "..\..\include\conf.h"\ "..\..\include\hsregex.h"\ + "..\..\include\http_conf_globals.h"\ "..\..\include\http_config.h"\ "..\..\include\http_core.h"\ "..\..\include\http_log.h"\ "..\..\include\http_request.h"\ + "..\..\include\http_vhost.h"\ "..\..\include\httpd.h"\ + "..\..\include\util_uri.h"\ "..\..\modules\standard\mod_rewrite.h"\ ".\os.h"\ - ".\passwd.h"\ ".\readdir.h"\ @@ -215,10 +218,12 @@ DEP_CPP_MOD_R=\ DEP_CPP_MOD_R=\ "..\..\include\alloc.h"\ "..\..\include\ap.h"\ + "..\..\include\ap_config.h"\ + "..\..\include\ap_ctype.h"\ "..\..\include\ap_mmn.h"\ "..\..\include\buff.h"\ - "..\..\include\conf.h"\ "..\..\include\hsregex.h"\ + "..\..\include\http_conf_globals.h"\ "..\..\include\http_config.h"\ "..\..\include\http_core.h"\ "..\..\include\http_log.h"\ diff --git a/usr.sbin/httpd/src/os/win32/installer/apache.iwz b/usr.sbin/httpd/src/os/win32/installer/apache.iwz index d9e6a9d18db..6af3320c83f 100644 --- a/usr.sbin/httpd/src/os/win32/installer/apache.iwz +++ b/usr.sbin/httpd/src/os/win32/installer/apache.iwz @@ -4,39 +4,38 @@ iDate=1 iTime=1 Flag=fe000000 ISX.EXE Size=630784 -ISX.EXE Date=11:43:52 24/2/1998 +ISX.EXE Date=10:43:52 24/2/1998 ISX.EXE Ver=2.0.0.143 SETUP.EXE Size=45312 -SETUP.EXE Date=10:53:32 18/1/1997 +SETUP.EXE Date=9:53:32 18/1/1997 SETUP.EXE Ver=3.0.111.0 SETUP.INS Size=70160 -SETUP.INS Date=14:16:56 11/2/1998 +SETUP.INS Date=13:16:56 11/2/1998 SETUP.INS Ver=Not available _INST16.EX_ Size=282766 -_INST16.EX_ Date=10:56:04 18/1/1997 +_INST16.EX_ Date=9:56:04 18/1/1997 _INST16.EX_ Ver=Not available _INST32I.EX_ Size=320411 -_INST32I.EX_ Date=11:04:08 18/1/1997 +_INST32I.EX_ Date=10:04:08 18/1/1997 _INST32I.EX_ Ver=Not available ISDEPEND.INI Size=320411 -ISDEPEND.INI Date=11:04:08 18/1/1997 +ISDEPEND.INI Date=10:04:08 18/1/1997 ISDEPEND.INI Ver=Not available SWDEPEND.INI Size=320411 -SWDEPEND.INI Date=11:04:08 18/1/1997 +SWDEPEND.INI Date=10:04:08 18/1/1997 SWDEPEND.INI Ver=Not available ICOMP.EXE Size=119808 -ICOMP.EXE Date=15:05:10 15/1/1996 +ICOMP.EXE Date=14:05:10 15/1/1996 ICOMP.EXE Ver=3.00.062 SPLIT.EXE Size=90624 -SPLIT.EXE Date=15:09:36 15/1/1996 +SPLIT.EXE Date=14:09:36 15/1/1996 SPLIT.EXE Ver=3.00.060 PACKLIST.EXE Size=87552 -PACKLIST.EXE Date=15:10:30 15/1/1996 +PACKLIST.EXE Date=14:10:30 15/1/1996 PACKLIST.EXE Ver=3.00.060 Version=2.02 DevTool=Generic Windows Platform=Win32 -DisksBuilt=1 DisksDir=apache\650MB\ TabsVisit=1111001110000111100011 LangNum=451 @@ -46,9 +45,9 @@ LangDir=LANG\ENG\ AppName=Apache AppExe= AppExeFile= -Version=1.3.3 +Version=1.3.7 dev Company=Apache Group -Title=Apache Web Server 1.3.3 +Title=Apache Web Server 1.3.7 dev TitleType=1 BackgrndBmp= BackgrndAlign=4 @@ -62,44 +61,44 @@ SmsMode=0 Types=3 Type1Components=6 Type1Name=Custom -Type1ComponentList=1 2 3 4 5 6 +Type1ComponentList=1 3 4 6 5 2 Type2Components=5 Type2Name=Typical -Type2ComponentList=1 3 4 5 6 +Type2ComponentList=1 3 4 6 5 Type3Components=2 Type3Name=Compact Type3ComponentList=1 6 [Components] Components=6 -Component1Groups=5 +Component1Groups=6 Component1Name=Application Files Component1Description=Application files needed to run the application -Component1GroupList=1 3 24 25 4 -Component2Groups=14 +Component1GroupList=1 3 24 25 4 35 +Component2Groups=17 Component2Name=Source Code Component2Description=Source code for Apache and support tools -Component2GroupList=10 11 12 13 14 15 16 17 18 19 20 21 22 23 -Component3Groups=5 +Component2GroupList=10 11 12 13 14 15 16 17 18 19 20 21 22 23 31 32 34 +Component3Groups=6 Component3Name=Apache Manual Component3Description=Apache documentation -Component3GroupList=5 6 7 8 9 +Component3GroupList=5 6 7 8 9 36 Component4Groups=1 Component4Name=Additional Modules Component4Description=Apache modules to extend the server Component4GroupList=2 -Component5Groups=1 +Component5Groups=2 Component5Name=Icons Component5Description=Icons for directory indexes -Component5GroupList=27 +Component5GroupList=27 33 Component6Groups=4 Component6Name=Required Directories Component6Description= Component6GroupList=26 28 29 30 [Groups] -Groups=30 -Group1Size=328050 +Groups=36 +Group1Size=346325 Group1Files=9 Group1Name=Program Executables Group1Dir=<INSTALLDIR> @@ -114,7 +113,7 @@ Group1File6=C:\Apache\LICENSE Group1File7=C:\Apache\README Group1File8=C:\apache\Makefile.tmpl Group1File9=C:\apache\README-NT.TXT -Group2Size=135680 +Group2Size=133120 Group2Files=10 Group2Name=Additional Modules Group2Dir=<INSTALLDIR>\modules @@ -130,7 +129,7 @@ Group2File7=C:\Apache\modules\ApacheModuleSpeling.dll Group2File8=C:\Apache\modules\ApacheModuleStatus.dll Group2File9=C:\Apache\modules\ApacheModuleUserTrack.dll Group2File10=C:\apache\modules\ApacheModuleRewrite.dll -Group3Size=38714 +Group3Size=49860 Group3Files=6 Group3Name=Configuration Files Group3Dir=<INSTALLDIR>\.tmp @@ -150,8 +149,8 @@ Group4Update=1 Group4TargetOS=-1 Group4File1=C:\Apache\htdocs\index.html Group4File2=C:\apache\htdocs\apache_pb.gif -Group5Size=253396 -Group5Files=31 +Group5Size=295033 +Group5Files=34 Group5Name=Manual Group5Dir=<INSTALLDIR>\htdocs\manual Group5Update=0 @@ -187,6 +186,9 @@ Group5File28=C:\apache\htdocs\manual\unixware.html Group5File29=C:\apache\htdocs\manual\upgrading_to_1_3.html Group5File30=C:\apache\htdocs\manual\windows.html Group5File31=C:\apache\htdocs\manual\bind.html +Group5File32=C:\apache\htdocs\manual\suexec_1_2.html +Group5File33=C:\apache\htdocs\manual\install-tpf.html +Group5File34=C:\apache\htdocs\manual\readme-tpf.html Group6Size=42478 Group6Files=8 Group6Name=images @@ -201,7 +203,7 @@ Group6File5=C:\apache\htdocs\manual\images\mod_rewrite_fig1.fig Group6File6=C:\apache\htdocs\manual\images\mod_rewrite_fig1.gif Group6File7=C:\apache\htdocs\manual\images\mod_rewrite_fig2.fig Group6File8=C:\apache\htdocs\manual\images\mod_rewrite_fig2.gif -Group7Size=321048 +Group7Size=329371 Group7Files=22 Group7Name=misc Group7Dir=[Manual]\misc @@ -229,7 +231,7 @@ Group7File19=C:\Apache\htdocs\manual\misc\security_tips.html Group7File20=C:\Apache\htdocs\manual\misc\vif-info.html Group7File21=C:\Apache\htdocs\manual\misc\windoz_keepalive.html Group7File22=C:\apache\htdocs\manual\misc\HTTP_Features.tsv -Group8Size=531149 +Group8Size=558131 Group8Files=48 Group8Name=mod Group8Dir=[Manual]\mod @@ -283,8 +285,8 @@ Group8File45=C:\Apache\htdocs\manual\mod\mod_unique_id.html Group8File46=C:\Apache\htdocs\manual\mod\mod_userdir.html Group8File47=C:\Apache\htdocs\manual\mod\mod_usertrack.html Group8File48=C:\apache\htdocs\manual\mod\mod_mmap_static.html -Group9Size=97112 -Group9Files=12 +Group9Size=112629 +Group9Files=13 Group9Name=vhosts Group9Dir=[Manual]\vhosts Group9Update=0 @@ -301,8 +303,9 @@ Group9File9=C:\Apache\htdocs\manual\vhosts\ip-based.html Group9File10=C:\Apache\htdocs\manual\vhosts\name-based.html Group9File11=C:\Apache\htdocs\manual\vhosts\vhosts-in-depth.html Group9File12=C:\Apache\htdocs\manual\vhosts\virtual-host.html -Group10Size=463830 -Group10Files=17 +Group9File13=C:\apache\htdocs\manual\vhosts\mass.html +Group10Size=523748 +Group10Files=19 Group10Name=src Group10Dir=<INSTALLDIR>\src Group10Update=0 @@ -324,7 +327,9 @@ Group10File14=C:\Apache\src\PORTING Group10File15=C:\Apache\src\README Group10File16=C:\Apache\src\README.EBCDIC Group10File17=C:\apache\src\BUILD.NOTES -Group11Size=68859 +Group10File18=C:\apache\src\Makefile_win32.txt +Group10File19=C:\apache\src\Makefile_win32_debug.txt +Group11Size=92924 Group11Files=10 Group11Name=ap Group11Dir=[src]\ap @@ -338,10 +343,10 @@ Group11File5=C:\Apache\src\ap\ap_signal.c Group11File6=C:\Apache\src\ap\ap_slack.c Group11File7=C:\Apache\src\ap\ap_snprintf.c Group11File8=C:\Apache\src\ap\Makefile.tmpl -Group11File9=C:\apache\src\ap\.indent.pro -Group11File10=C:\apache\src\ap\ap_fnmatch.c -Group12Size=246696 -Group12Files=30 +Group11File9=C:\apache\src\ap\ap_fnmatch.c +Group11File10=C:\apache\src\ap\ap_md5c.c +Group12Size=255397 +Group12Files=29 Group12Name=include Group12Dir=[src]\include Group12Update=0 @@ -374,38 +379,35 @@ Group12File25=C:\apache\src\include\util_uri.h Group12File26=C:\apache\src\include\ap_compat.h Group12File27=C:\apache\src\include\ap_config.h Group12File28=C:\apache\src\include\ap_ctype.h -Group12File29=C:\apache\src\include\.indent.pro -Group12File30=C:\apache\src\include\ap_mmn.h -Group13Size=771650 -Group13Files=24 +Group12File29=C:\apache\src\include\ap_mmn.h +Group13Size=789788 +Group13Files=22 Group13Name=main Group13Dir=[src]\main Group13Update=0 Group13TargetOS=-1 -Group13File1=C:\apache\src\main\.indent.pro -Group13File2=C:\apache\src\main\alloc.c -Group13File3=C:\apache\src\main\buff.c -Group13File4=C:\apache\src\main\gen_test_char.c -Group13File5=C:\apache\src\main\gen_test_char.dsp -Group13File6=C:\apache\src\main\gen_test_char.mak -Group13File7=C:\apache\src\main\gen_uri_delims.c -Group13File8=C:\apache\src\main\gen_uri_delims.dsp -Group13File9=C:\apache\src\main\gen_uri_delims.mak -Group13File10=C:\apache\src\main\http_config.c -Group13File11=C:\apache\src\main\http_core.c -Group13File12=C:\apache\src\main\http_log.c -Group13File13=C:\apache\src\main\http_main.c -Group13File14=C:\apache\src\main\http_protocol.c -Group13File15=C:\apache\src\main\http_request.c -Group13File16=C:\apache\src\main\http_vhost.c -Group13File17=C:\apache\src\main\Makefile.tmpl -Group13File18=C:\apache\src\main\md5c.c -Group13File19=C:\apache\src\main\rfc1413.c -Group13File20=C:\apache\src\main\util.c -Group13File21=C:\apache\src\main\util_date.c -Group13File22=C:\apache\src\main\util_md5.c -Group13File23=C:\apache\src\main\util_script.c -Group13File24=C:\apache\src\main\util_uri.c +Group13File1=C:\apache\src\main\alloc.c +Group13File2=C:\apache\src\main\buff.c +Group13File3=C:\apache\src\main\gen_test_char.c +Group13File4=C:\apache\src\main\gen_test_char.dsp +Group13File5=C:\apache\src\main\gen_test_char.mak +Group13File6=C:\apache\src\main\gen_uri_delims.c +Group13File7=C:\apache\src\main\gen_uri_delims.dsp +Group13File8=C:\apache\src\main\gen_uri_delims.mak +Group13File9=C:\apache\src\main\http_config.c +Group13File10=C:\apache\src\main\http_core.c +Group13File11=C:\apache\src\main\http_log.c +Group13File12=C:\apache\src\main\http_main.c +Group13File13=C:\apache\src\main\http_protocol.c +Group13File14=C:\apache\src\main\http_request.c +Group13File15=C:\apache\src\main\http_vhost.c +Group13File16=C:\apache\src\main\Makefile.tmpl +Group13File17=C:\apache\src\main\rfc1413.c +Group13File18=C:\apache\src\main\util.c +Group13File19=C:\apache\src\main\util_date.c +Group13File20=C:\apache\src\main\util_md5.c +Group13File21=C:\apache\src\main\util_script.c +Group13File22=C:\apache\src\main\util_uri.c Group14Size=895 Group14Files=1 Group14Name=modules @@ -413,8 +415,8 @@ Group14Dir=[src]\modules Group14Update=0 Group14TargetOS=-1 Group14File1=C:\Apache\src\modules\README -Group15Size=49171 -Group15Files=4 +Group15Size=48416 +Group15Files=3 Group15Name=example Group15Dir=[modules]\example Group15Update=0 @@ -422,86 +424,81 @@ Group15TargetOS=-1 Group15File1=C:\Apache\src\modules\example\Makefile.tmpl Group15File2=C:\Apache\src\modules\example\mod_example.c Group15File3=C:\Apache\src\modules\example\README -Group15File4=C:\apache\src\modules\example\.indent.pro -Group16Size=13944 -Group16Files=3 +Group16Size=13194 +Group16Files=2 Group16Name=experimental Group16Dir=[modules]\experimental Group16Update=0 Group16TargetOS=-1 Group16File1=C:\Apache\src\modules\experimental\Makefile.tmpl Group16File2=C:\Apache\src\modules\experimental\mod_mmap_static.c -Group16File3=C:\apache\src\modules\experimental\.indent.pro -Group17Size=824 -Group17Files=2 +Group17Size=69 +Group17Files=1 Group17Name=extra Group17Dir=[modules]\extra Group17Update=0 Group17TargetOS=-1 Group17File1=C:\Apache\src\modules\extra\Makefile.tmpl -Group17File2=C:\apache\src\modules\extra\.indent.pro -Group18Size=205432 -Group18Files=12 +Group18Size=205708 +Group18Files=11 Group18Name=proxy Group18Dir=[modules]\proxy Group18Update=0 Group18TargetOS=-1 -Group18File1=C:\apache\src\modules\proxy\.indent.pro -Group18File2=C:\apache\src\modules\proxy\ApacheModuleProxy.dsp -Group18File3=C:\apache\src\modules\proxy\ApacheModuleProxy.mak -Group18File4=C:\apache\src\modules\proxy\Makefile.libdir -Group18File5=C:\apache\src\modules\proxy\Makefile.tmpl -Group18File6=C:\apache\src\modules\proxy\mod_proxy.c -Group18File7=C:\apache\src\modules\proxy\mod_proxy.h -Group18File8=C:\apache\src\modules\proxy\proxy_cache.c -Group18File9=C:\apache\src\modules\proxy\proxy_connect.c -Group18File10=C:\apache\src\modules\proxy\proxy_ftp.c -Group18File11=C:\apache\src\modules\proxy\proxy_http.c -Group18File12=C:\apache\src\modules\proxy\proxy_util.c -Group19Size=831125 -Group19Files=37 +Group18File1=C:\apache\src\modules\proxy\ApacheModuleProxy.dsp +Group18File2=C:\apache\src\modules\proxy\ApacheModuleProxy.mak +Group18File3=C:\apache\src\modules\proxy\Makefile.libdir +Group18File4=C:\apache\src\modules\proxy\Makefile.tmpl +Group18File5=C:\apache\src\modules\proxy\mod_proxy.c +Group18File6=C:\apache\src\modules\proxy\mod_proxy.h +Group18File7=C:\apache\src\modules\proxy\proxy_cache.c +Group18File8=C:\apache\src\modules\proxy\proxy_connect.c +Group18File9=C:\apache\src\modules\proxy\proxy_ftp.c +Group18File10=C:\apache\src\modules\proxy\proxy_http.c +Group18File11=C:\apache\src\modules\proxy\proxy_util.c +Group19Size=863524 +Group19Files=36 Group19Name=standard Group19Dir=[modules]\standard Group19Update=0 Group19TargetOS=-1 -Group19File1=C:\apache\src\modules\standard\.indent.pro -Group19File2=C:\apache\src\modules\standard\Makefile.tmpl -Group19File3=C:\apache\src\modules\standard\mod_access.c -Group19File4=C:\apache\src\modules\standard\mod_actions.c -Group19File5=C:\apache\src\modules\standard\mod_alias.c -Group19File6=C:\apache\src\modules\standard\mod_asis.c -Group19File7=C:\apache\src\modules\standard\mod_auth.c -Group19File8=C:\apache\src\modules\standard\mod_auth_anon.c -Group19File9=C:\apache\src\modules\standard\mod_auth_db.c -Group19File10=C:\apache\src\modules\standard\mod_auth_db.module -Group19File11=C:\apache\src\modules\standard\mod_auth_dbm.c -Group19File12=C:\apache\src\modules\standard\mod_autoindex.c -Group19File13=C:\apache\src\modules\standard\mod_cern_meta.c -Group19File14=C:\apache\src\modules\standard\mod_cgi.c -Group19File15=C:\apache\src\modules\standard\mod_digest.c -Group19File16=C:\apache\src\modules\standard\mod_dir.c -Group19File17=C:\apache\src\modules\standard\mod_env.c -Group19File18=C:\apache\src\modules\standard\mod_expires.c -Group19File19=C:\apache\src\modules\standard\mod_headers.c -Group19File20=C:\apache\src\modules\standard\mod_imap.c -Group19File21=C:\apache\src\modules\standard\mod_include.c -Group19File22=C:\apache\src\modules\standard\mod_info.c -Group19File23=C:\apache\src\modules\standard\mod_log_agent.c -Group19File24=C:\apache\src\modules\standard\mod_log_config.c -Group19File25=C:\apache\src\modules\standard\mod_log_referer.c -Group19File26=C:\apache\src\modules\standard\mod_mime.c -Group19File27=C:\apache\src\modules\standard\mod_mime_magic.c -Group19File28=C:\apache\src\modules\standard\mod_negotiation.c -Group19File29=C:\apache\src\modules\standard\mod_rewrite.c -Group19File30=C:\apache\src\modules\standard\mod_rewrite.h -Group19File31=C:\apache\src\modules\standard\mod_setenvif.c -Group19File32=C:\apache\src\modules\standard\mod_so.c -Group19File33=C:\apache\src\modules\standard\mod_speling.c -Group19File34=C:\apache\src\modules\standard\mod_status.c -Group19File35=C:\apache\src\modules\standard\mod_unique_id.c -Group19File36=C:\apache\src\modules\standard\mod_userdir.c -Group19File37=C:\apache\src\modules\standard\mod_usertrack.c -Group20Size=170813 +Group19File1=C:\apache\src\modules\standard\Makefile.tmpl +Group19File2=C:\apache\src\modules\standard\mod_access.c +Group19File3=C:\apache\src\modules\standard\mod_actions.c +Group19File4=C:\apache\src\modules\standard\mod_alias.c +Group19File5=C:\apache\src\modules\standard\mod_asis.c +Group19File6=C:\apache\src\modules\standard\mod_auth.c +Group19File7=C:\apache\src\modules\standard\mod_auth_anon.c +Group19File8=C:\apache\src\modules\standard\mod_auth_db.c +Group19File9=C:\apache\src\modules\standard\mod_auth_db.module +Group19File10=C:\apache\src\modules\standard\mod_auth_dbm.c +Group19File11=C:\apache\src\modules\standard\mod_autoindex.c +Group19File12=C:\apache\src\modules\standard\mod_cern_meta.c +Group19File13=C:\apache\src\modules\standard\mod_cgi.c +Group19File14=C:\apache\src\modules\standard\mod_digest.c +Group19File15=C:\apache\src\modules\standard\mod_dir.c +Group19File16=C:\apache\src\modules\standard\mod_env.c +Group19File17=C:\apache\src\modules\standard\mod_expires.c +Group19File18=C:\apache\src\modules\standard\mod_headers.c +Group19File19=C:\apache\src\modules\standard\mod_imap.c +Group19File20=C:\apache\src\modules\standard\mod_include.c +Group19File21=C:\apache\src\modules\standard\mod_info.c +Group19File22=C:\apache\src\modules\standard\mod_log_agent.c +Group19File23=C:\apache\src\modules\standard\mod_log_config.c +Group19File24=C:\apache\src\modules\standard\mod_log_referer.c +Group19File25=C:\apache\src\modules\standard\mod_mime.c +Group19File26=C:\apache\src\modules\standard\mod_mime_magic.c +Group19File27=C:\apache\src\modules\standard\mod_negotiation.c +Group19File28=C:\apache\src\modules\standard\mod_rewrite.c +Group19File29=C:\apache\src\modules\standard\mod_rewrite.h +Group19File30=C:\apache\src\modules\standard\mod_setenvif.c +Group19File31=C:\apache\src\modules\standard\mod_so.c +Group19File32=C:\apache\src\modules\standard\mod_speling.c +Group19File33=C:\apache\src\modules\standard\mod_status.c +Group19File34=C:\apache\src\modules\standard\mod_unique_id.c +Group19File35=C:\apache\src\modules\standard\mod_userdir.c +Group19File36=C:\apache\src\modules\standard\mod_usertrack.c +Group20Size=170796 Group20Files=25 Group20Name=regex Group20Dir=[src]\regex @@ -532,47 +529,48 @@ Group20File22=C:\Apache\src\regex\split.c Group20File23=C:\Apache\src\regex\tests Group20File24=C:\Apache\src\regex\utils.h Group20File25=C:\Apache\src\regex\WHATSNEW -Group21Size=182644 -Group21Files=27 +Group21Size=210232 +Group21Files=28 Group21Name=support Group21Dir=[src]\support Group21Update=0 Group21TargetOS=-1 -Group21File1=C:\apache\src\support\.indent.pro -Group21File2=C:\apache\src\support\ab.1 -Group21File3=C:\apache\src\support\ab.c -Group21File4=C:\apache\src\support\apachectl -Group21File5=C:\apache\src\support\apachectl.1 -Group21File6=C:\apache\src\support\apxs.8 -Group21File7=C:\apache\src\support\apxs.pl -Group21File8=C:\apache\src\support\dbmmanage -Group21File9=C:\apache\src\support\dbmmanage.1 -Group21File10=C:\apache\src\support\htdigest.1 -Group21File11=C:\apache\src\support\htdigest.c -Group21File12=C:\apache\src\support\htpasswd.1 -Group21File13=C:\apache\src\support\htpasswd.c -Group21File14=C:\apache\src\support\httpd.8 -Group21File15=C:\apache\src\support\log_server_status -Group21File16=C:\apache\src\support\logresolve.8 -Group21File17=C:\apache\src\support\logresolve.c -Group21File18=C:\apache\src\support\logresolve.pl -Group21File19=C:\apache\src\support\Makefile.tmpl -Group21File20=C:\apache\src\support\phf_abuse_log.cgi -Group21File21=C:\apache\src\support\rotatelogs.8 -Group21File22=C:\apache\src\support\rotatelogs.c -Group21File23=C:\apache\src\support\split-logfile -Group21File24=C:\apache\src\support\suexec.8 -Group21File25=C:\apache\src\support\suexec.c -Group21File26=C:\apache\src\support\suexec.h -Group21File27=C:\apache\src\support\httpd.exp +Group21File1=C:\apache\src\support\ab.c +Group21File2=C:\apache\src\support\apachectl +Group21File3=C:\apache\src\support\apxs.8 +Group21File4=C:\apache\src\support\apxs.pl +Group21File5=C:\apache\src\support\dbmmanage +Group21File6=C:\apache\src\support\dbmmanage.1 +Group21File7=C:\apache\src\support\htdigest.1 +Group21File8=C:\apache\src\support\htdigest.c +Group21File9=C:\apache\src\support\htpasswd.1 +Group21File10=C:\apache\src\support\htpasswd.c +Group21File11=C:\apache\src\support\httpd.8 +Group21File12=C:\apache\src\support\log_server_status +Group21File13=C:\apache\src\support\logresolve.8 +Group21File14=C:\apache\src\support\logresolve.c +Group21File15=C:\apache\src\support\logresolve.pl +Group21File16=C:\apache\src\support\Makefile.tmpl +Group21File17=C:\apache\src\support\phf_abuse_log.cgi +Group21File18=C:\apache\src\support\rotatelogs.8 +Group21File19=C:\apache\src\support\rotatelogs.c +Group21File20=C:\apache\src\support\split-logfile +Group21File21=C:\apache\src\support\suexec.8 +Group21File22=C:\apache\src\support\suexec.c +Group21File23=C:\apache\src\support\suexec.h +Group21File24=C:\apache\src\support\httpd.exp +Group21File25=C:\apache\src\support\htpasswd.dsp +Group21File26=C:\apache\src\support\htpasswd.mak +Group21File27=C:\apache\src\support\ab.8 +Group21File28=C:\apache\src\support\apachectl.8 Group22Size=0 Group22Files=0 Group22Name=os Group22Dir=[src]\os Group22Update=0 Group22TargetOS=-1 -Group23Size=199605 -Group23Files=43 +Group23Size=210812 +Group23Files=46 Group23Name=win32 Group23Dir=[os]\win32 Group23Update=0 @@ -620,14 +618,17 @@ Group23File40=C:\apache\src\os\win32\registry.h Group23File41=C:\apache\src\os\win32\service.c Group23File42=C:\apache\src\os\win32\service.h Group23File43=C:\apache\src\os\win32\util_win32.c -Group24Size=54784 +Group23File44=C:\apache\src\os\win32\apache.ico +Group23File45=C:\apache\src\os\win32\apache.rc +Group23File46=C:\apache\src\os\win32\resource.h +Group24Size=84480 Group24Files=1 Group24Name=Installer DLL Group24Dir=<INSTALLDIR> Group24Update=0 Group24TargetOS=-1 Group24File1=C:\Apache\install.dll -Group25Size=280576 +Group25Size=254005 Group25Files=1 Group25Name=Shared DLLs Group25Dir=<WINSYSDIR> @@ -640,7 +641,7 @@ Group26Name=logs Group26Dir=<INSTALLDIR>\logs Group26Update=0 Group26TargetOS=-1 -Group27Size=37074 +Group27Size=37127 Group27Files=76 Group27Name=icons Group27Dir=<INSTALLDIR>\icons @@ -741,6 +742,91 @@ Group30Name=cgi-bin Group30Dir=<INSTALLDIR>\cgi-bin Group30Update=0 Group30TargetOS=-1 +Group31Size=37002 +Group31Files=2 +Group31Name=installer +Group31Dir=[win32]\installer +Group31Update=0 +Group31TargetOS=-1 +Group31File1=C:\apache\src\os\win32\installer\apache.iwz +Group31File2=C:\apache\src\os\win32\installer\README.TXT +Group32Size=30356 +Group32Files=4 +Group32Name=installdll +Group32Dir=[installer]\installdll +Group32Update=0 +Group32TargetOS=-1 +Group32File1=C:\apache\src\os\win32\installer\installdll\install.c +Group32File2=C:\apache\src\os\win32\installer\installdll\install.def +Group32File3=C:\apache\src\os\win32\installer\installdll\install.dsp +Group32File4=C:\apache\src\os\win32\installer\installdll\install.mak +Group33Size=8247 +Group33Files=33 +Group33Name=small +Group33Dir=[icons]\small +Group33Update=0 +Group33TargetOS=-1 +Group33File1=C:\apache\icons\small\back.gif +Group33File2=C:\apache\icons\small\binary.gif +Group33File3=C:\apache\icons\small\binhex.gif +Group33File4=C:\apache\icons\small\blank.gif +Group33File5=C:\apache\icons\small\broken.gif +Group33File6=C:\apache\icons\small\burst.gif +Group33File7=C:\apache\icons\small\comp1.gif +Group33File8=C:\apache\icons\small\comp2.gif +Group33File9=C:\apache\icons\small\compressed.gif +Group33File10=C:\apache\icons\small\continued.gif +Group33File11=C:\apache\icons\small\dir.gif +Group33File12=C:\apache\icons\small\dir2.gif +Group33File13=C:\apache\icons\small\forward.gif +Group33File14=C:\apache\icons\small\generic.gif +Group33File15=C:\apache\icons\small\generic2.gif +Group33File16=C:\apache\icons\small\generic3.gif +Group33File17=C:\apache\icons\small\image.gif +Group33File18=C:\apache\icons\small\image2.gif +Group33File19=C:\apache\icons\small\index.gif +Group33File20=C:\apache\icons\small\movie.gif +Group33File21=C:\apache\icons\small\rainbow.gif +Group33File22=C:\apache\icons\small\README.txt +Group33File23=C:\apache\icons\small\sound.gif +Group33File24=C:\apache\icons\small\sound2.gif +Group33File25=C:\apache\icons\small\tar.gif +Group33File26=C:\apache\icons\small\text.gif +Group33File27=C:\apache\icons\small\transfer.gif +Group33File28=C:\apache\icons\small\unknown.gif +Group33File29=C:\apache\icons\small\uu.gif +Group33File30=C:\apache\icons\small\key.gif +Group33File31=C:\apache\icons\small\patch.gif +Group33File32=C:\apache\icons\small\ps.gif +Group33File33=C:\apache\icons\small\doc.gif +Group34Size=21478 +Group34Files=8 +Group34Name=test +Group34Dir=[installdll]\test +Group34Update=0 +Group34TargetOS=-1 +Group34File1=C:\apache\src\os\win32\installer\installdll\test\resource.h +Group34File2=C:\apache\src\os\win32\installer\installdll\test\test.c +Group34File3=C:\apache\src\os\win32\installer\installdll\test\test.def +Group34File4=C:\apache\src\os\win32\installer\installdll\test\test.dsp +Group34File5=C:\apache\src\os\win32\installer\installdll\test\test.h +Group34File6=C:\apache\src\os\win32\installer\installdll\test\test.ico +Group34File7=C:\apache\src\os\win32\installer\installdll\test\test.mak +Group34File8=C:\apache\src\os\win32\installer\installdll\test\test.rc +Group35Size=58368 +Group35Files=1 +Group35Name=bin +Group35Dir=<INSTALLDIR>\bin +Group35Update=0 +Group35TargetOS=-1 +Group35File1=C:\apache\bin\htpasswd.exe +Group36Size=7223 +Group36Files=1 +Group36Name=search +Group36Dir=[manual]\search +Group36Update=0 +Group36TargetOS=-1 +Group36File1=C:\apache\htdocs\manual\search\manual-index.cgi [Sequence] DestinationLocationDir=<ProgramFilesDir>\Apache Group\Apache @@ -805,7 +891,7 @@ Reg9Val1Type=0 Reg9Val1Name=(Default) Reg9Val1Data=(value not set) Reg9Vals=1 -Reg10Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.3 +Reg10Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.7 dev Reg10Val1Type=0 Reg10Val1Name=(Default) Reg10Val1Data=(value not set) @@ -819,20 +905,20 @@ Regs=10 Reg1Path=HKEY_LOCAL_MACHINE\SOFTWARE Reg2Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group Reg3Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache -Reg4Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.3 -Reg5Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.3 +Reg4Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.7 dev +Reg5Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.7 dev Reg5ValName=ServerRoot Reg5ValType=0 Reg5ValData=<INSTALLDIR> Regs=5 [Icons] -Icons=3 -Icon1Param=-d "<INSTALLDIR>" +Icons=5 +Icon1Param=-d "<INSTALLDIR>" -s Icon1Cmd=[Program Executables]\Apache.exe -Icon1Description=Apache Server +Icon1Description=Start Apache as console app Icon1WorkingDir=[Program Executables] -Icon1IconFile= +Icon1IconFile=[Program Executables]\Apache.exe Icon1RealFile=C:\Apache\Apache.exe Icon1WhichIcon=0 Icon1KeyVirtual=0 @@ -861,12 +947,34 @@ Icon3KeyVirtual=0 Icon3KeyFlags=0 Icon3StartMenu=0 Icon3Window=0 +Icon4Param=-d "<INSTALLDIR>" -u +Icon4Cmd=[Program Executables]\Apache.exe +Icon4Description=Uninstall Apache Service (NT only) +Icon4WorkingDir=[Program Executables] +Icon4IconFile= +Icon4RealFile=C:\Apache\Apache.exe +Icon4WhichIcon=0 +Icon4KeyVirtual=0 +Icon4KeyFlags=0 +Icon4StartMenu=0 +Icon4Window=0 +Icon5Param=-d "<INSTALLDIR>" -k shutdown +Icon5Cmd=[Program Executables]\Apache.exe +Icon5Description=Shutdown Apache console app +Icon5WorkingDir=[Program Executables] +Icon5IconFile= +Icon5RealFile=C:\Apache\Apache.exe +Icon5WhichIcon=0 +Icon5KeyVirtual=0 +Icon5KeyFlags=0 +Icon5StartMenu=0 +Icon5Window=0 [VisualBasic] PRJFile= [Ext] -Ext1Dlg=Exit Install +Ext1Dlg=Setup Complete Ext1Param1=[Installer DLL]\install.dll Ext1Param2=BeforeExit Ext1Op=DLL diff --git a/usr.sbin/httpd/src/os/win32/installer/installdll/install.c b/usr.sbin/httpd/src/os/win32/installer/installdll/install.c index f6f775ec945..39da17a104d 100644 --- a/usr.sbin/httpd/src/os/win32/installer/installdll/install.c +++ b/usr.sbin/httpd/src/os/win32/installer/installdll/install.c @@ -4,17 +4,65 @@ * 26/06/97 PCS 1.000 Initial version * 22/02/98 PCS 1.001 Used the excellent NTemacs to apply proper formating * 04/05/98 PCS 1.002 Copy conf files to *.conf.default, then to *.conf + * 16/02/99 PCS 1.003 Add logging to "install.log" in the installed directory */ -#include <windows.h> -#include <winsock.h> +#define VERSION ( "1.003 " __DATE__ " " __TIME__ ) + +#include <winsock2.h> #include <string.h> #include <stdio.h> #include <direct.h> +#include <time.h> + +#include "conf.h" +#include "ap.h" + +#ifdef strftime +#undef strftime +#endif + +#define AP_WIN32ERROR 1 /* Global to store the instance handle */ HINSTANCE hInstance = NULL; +static char *szLogFilename = NULL; +static FILE *fpLog = NULL; + +void LogMessage(char *fmt, ...) +{ + char buf[4000]; + va_list ap; + struct tm *tms; + time_t nowtime; + char *bp = buf; + int rv; + int free = sizeof(buf); + + if (!fpLog) { + return; + } + + nowtime = time(NULL); + tms = localtime(&nowtime); + rv = strftime(bp, free, "%c", tms); + bp += rv; + free -= rv; + if (free) { + *bp++ = ' '; + free--; + } + + va_start(ap, fmt); + rv = ap_vsnprintf(bp, free, fmt, ap); + va_end(ap); + + free -= rv; + + fprintf(fpLog, "%s\n", buf); +} + /* * MessageBox_error() is a helper function to display an error in a * message box, optionally including a Win32 error message. If @@ -23,45 +71,104 @@ HINSTANCE hInstance = NULL; * the output string. The output string is given as a printf-format * and replacement arguments. The hWnd, title and mb_opt fields are * passed on to the Win32 MessageBox() call. - * - * We shouldn't use a fixed length buffer to build up the printf - * text. Umm. */ -#define AP_WIN32ERROR 1 - int MessageBox_error(HWND hWnd, int opt, char *title, int mb_opt, char *fmt, ...) { - char buf[4000]; + char buf[1000]; va_list ap; + int free = sizeof(buf); /* Number of bytes free in the buffer */ + int rv; + char *p; va_start(ap, fmt); - wvsprintf(buf, fmt, ap); + rv = ap_vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - if (opt & AP_WIN32ERROR) { - char *p; - - strcat(buf, "\r\r("); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), - 0, - buf + strlen(buf), - 4000 - strlen(buf), - NULL); - p = buf+strlen(buf)-1; - while (*p == '\r' || *p == '\n') - p--; - p++; - *p = '\0'; - strcat(buf, ")"); + free -= rv; + + if (opt & AP_WIN32ERROR && free > 3) { + /* We checked in the "if" that we have enough space in buf for + * at least three extra characters. + */ + p = buf + strlen(buf); + *p++ = '\r'; + *p++ = '\r'; + *p++ = '('; + free -= 3; + /* NB: buf is now not null terminated */ + + /* Now put the error message straight into buf. This function + * takes the free buffer size as the 6th argument. + */ + rv = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + 0, + p, + free, + NULL); + + if (rv == 0) { + /* FormatMessage failed, so get rid of the "\r\r(" we just placed + * in the buffer, since there is no system error message. + */ + p -= 3; + *p = '\0'; + free += 3; + } else { + free -= rv; + p += rv; + + /* Strip any trailing \r or \n characters to make it look nice on + * the screen. + */ + while (*(p-1) == '\r' || *(p-1) == '\n') + p--, free++; + *p = '\0'; + + /* Append a trailing ) */ + if (free >= 1) { + *p++ = ')'; + *p++ = '\0'; + } + } + } + + for (p = buf; *p; p++) { + if (*p == '\n' || *p == '\r') { + *p = ' '; + } } + LogMessage("MSG %s", buf); return MessageBox(hWnd, buf, title, mb_opt); } +int OpenLog(HWND hwnd, char *dir, char *fn) +{ + szLogFilename = malloc(strlen(dir) + 1 + strlen(fn) + 1); + sprintf(szLogFilename, "%s\\%s", dir, fn); + + if ((fpLog = fopen(szLogFilename, "a+")) == NULL) { + MessageBox_error(hwnd, + AP_WIN32ERROR, + "Installation Problem", + MB_OK | MB_ICONSTOP, + "Cannot open log file %s", szLogFilename); + return -1; + } + return 0; +} + +void CloseLog(void) +{ + if (fpLog) { + fclose(fpLog); + } +} + /* * The next few functions handle expanding the @@ServerRoot@@ type * sequences found in the distribution files. The main entry point @@ -262,8 +369,8 @@ int WINAPI ExpandConfFile(HWND hwnd, LPSTR szInst, LPSTR szinFile, LPSTR szoutFi FILE *infp; FILE *outfp; - sprintf(inFile, "%s\\%s", szInst, szinFile); - sprintf(outFile, "%s\\%s", szInst, szoutFile); + ap_snprintf(inFile, sizeof(inFile), "%s\\%s", szInst, szinFile); + ap_snprintf(outFile, sizeof(outFile), "%s\\%s", szInst, szoutFile); if (!(infp = fopen(inFile, "r"))) { MessageBox_error(hwnd, @@ -348,8 +455,11 @@ int WINAPI ExpandConfFile(HWND hwnd, LPSTR szInst, LPSTR szinFile, LPSTR szoutFi fclose(infp); fclose(outfp); + LogMessage("COPY: expanded %s to %s", inFile, outFile); + if (options & OPT_DELETESOURCE) { unlink(inFile); + LogMessage("COPY: deleted file %s", inFile); } return 0; @@ -375,6 +485,9 @@ int FillInReplaceTable(HWND hwnd, REPLACETABLE table, char *szInst) #endif for (p = item->value; *p; p++) if (*p == '\\') *p = '/'; + + LogMessage("FillInReplaceTable tmpl=%s value=%s", item->tmpl, item->value); + continue; } #if NEED_FQDN @@ -452,14 +565,6 @@ ACTIONITEM actionTable[] = { { CMD_COPY, ".tmp\\highperformance.conf-dist", "conf\\highperformance.conf-dist", OPT_EXPAND|OPT_OVERWRITE|OPT_DELETESOURCE }, - /* Move the default htdocs files into place, provided they don't already - * exist. - */ - { CMD_COPY, ".tmp\\index.html", "htdocs\\index.html", OPT_DELETESOURCE|OPT_SILENT }, - { CMD_RM, ".tmp\\index.html", NULL, OPT_SILENT }, - { CMD_COPY, ".tmp\\apache_pb.gif", "htdocs\\apache_pb.gif", OPT_DELETESOURCE|OPT_SILENT }, - { CMD_RM, ".tmp\\apache_pb.gif", NULL, OPT_SILENT }, - { CMD_RMDIR, ".tmp", NULL }, { CMD_END, NULL, NULL, OPT_NONE } @@ -477,10 +582,22 @@ CHAR WINAPI BeforeExit(HWND hwnd, LPSTR szSrcDir, LPSTR szSupport, LPSTR szInst, ACTIONITEM *pactionItem; int end = 0; + OpenLog(hwnd, szInst, "install.log"); + LogMessage("STARTED %s", VERSION); + LogMessage("src=%s support=%s inst=%s", + szSrcDir, szSupport, szInst); + FillInReplaceTable(hwnd, replaceHttpd, szInst); pactionItem = actionTable; while (!end) { + + LogMessage("command=%d 1in=%s out=%s options=%d", + pactionItem->command, + pactionItem->in ? pactionItem->in : "NULL", + pactionItem->out ? pactionItem->out : "NULL", + pactionItem->options); + switch(pactionItem->command) { case CMD_END: end = 1; @@ -498,7 +615,7 @@ CHAR WINAPI BeforeExit(HWND hwnd, LPSTR szSrcDir, LPSTR szSupport, LPSTR szInst, case CMD_RM: { char inFile[MAX_INPUT_LINE]; - sprintf(inFile, "%s\\%s", szInst, pactionItem->in); + ap_snprintf(inFile, sizeof(inFile), "%s\\%s", szInst, pactionItem->in); if (unlink(inFile) < 0 && !(pactionItem->options & OPT_SILENT)) { MessageBox_error(hwnd, AP_WIN32ERROR, "Error during configuration", MB_ICONHAND, @@ -506,12 +623,13 @@ CHAR WINAPI BeforeExit(HWND hwnd, LPSTR szSrcDir, LPSTR szSupport, LPSTR szInst, inFile); return 0; } + LogMessage("RM: deleted file %s", inFile); break; } case CMD_RMDIR: { char inFile[MAX_INPUT_LINE]; - sprintf(inFile, "%s\\%s", szInst, pactionItem->in); + ap_snprintf(inFile, sizeof(inFile), "%s\\%s", szInst, pactionItem->in); if (rmdir(inFile) < 0) { MessageBox_error(hwnd, AP_WIN32ERROR, "Error during configuration", MB_ICONHAND, @@ -519,6 +637,7 @@ CHAR WINAPI BeforeExit(HWND hwnd, LPSTR szSrcDir, LPSTR szSupport, LPSTR szInst, inFile); return 0; } + LogMessage("RMDIR: deleted directory %s", inFile); break; } default: @@ -531,6 +650,10 @@ CHAR WINAPI BeforeExit(HWND hwnd, LPSTR szSrcDir, LPSTR szSupport, LPSTR szInst, } pactionItem++; } + + LogMessage("FINISHED OK"); + CloseLog(); + return 1; } diff --git a/usr.sbin/httpd/src/os/win32/installer/installdll/install.dsp b/usr.sbin/httpd/src/os/win32/installer/installdll/install.dsp index 26ea521ab69..9c33d71a788 100644 --- a/usr.sbin/httpd/src/os/win32/installer/installdll/install.dsp +++ b/usr.sbin/httpd/src/os/win32/installer/installdll/install.dsp @@ -43,7 +43,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -69,7 +69,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -92,6 +92,10 @@ LINK32=link.exe # PROP Default_Filter "" # Begin Source File +SOURCE=..\..\..\..\ap\ap_snprintf.c +# End Source File +# Begin Source File + SOURCE=.\install.c # End Source File # Begin Source File diff --git a/usr.sbin/httpd/src/os/win32/installer/installdll/install.mak b/usr.sbin/httpd/src/os/win32/installer/installdll/install.mak index db4ad3a82d9..65d7608ba54 100644 --- a/usr.sbin/httpd/src/os/win32/installer/installdll/install.mak +++ b/usr.sbin/httpd/src/os/win32/installer/installdll/install.mak @@ -27,10 +27,6 @@ NULL= NULL=nul !ENDIF -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - !IF "$(CFG)" == "install - Win32 Release" OUTDIR=.\Release @@ -50,6 +46,7 @@ ALL : "$(OUTDIR)\install.dll" !ENDIF CLEAN : + -@erase "$(INTDIR)\ap_snprintf.obj" -@erase "$(INTDIR)\install.obj" -@erase "$(INTDIR)\vc50.idb" -@erase "$(OUTDIR)\install.dll" @@ -59,11 +56,46 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP=cl.exe +CPP_PROJ=/nologo /MT /W3 /GX /O2 /I "../../../../include" /D "WIN32" /D\ + "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\Release/ CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\install.bsc" BSC32_SBRS= \ @@ -76,6 +108,7 @@ LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ DEF_FILE= \ ".\install.def" LINK32_OBJS= \ + "$(INTDIR)\ap_snprintf.obj" \ "$(INTDIR)\install.obj" "$(OUTDIR)\install.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -102,6 +135,7 @@ ALL : "$(OUTDIR)\install.dll" !ENDIF CLEAN : + -@erase "$(INTDIR)\ap_snprintf.obj" -@erase "$(INTDIR)\install.obj" -@erase "$(INTDIR)\vc50.idb" -@erase "$(INTDIR)\vc50.pdb" @@ -114,32 +148,12 @@ CLEAN : "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" -CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\ - /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c +CPP=cl.exe +CPP_PROJ=/nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../../../include" /D "WIN32"\ + /D "_DEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\install.pch" /YX /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\Debug/ CPP_SBRS=. -MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\install.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ - advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll\ - /incremental:yes /pdb:"$(OUTDIR)\install.pdb" /debug /machine:I386\ - /def:".\install.def" /out:"$(OUTDIR)\install.dll"\ - /implib:"$(OUTDIR)\install.lib" /pdbtype:sept -DEF_FILE= \ - ".\install.def" -LINK32_OBJS= \ - "$(INTDIR)\install.obj" - -"$(OUTDIR)\install.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF .c{$(CPP_OBJS)}.obj:: $(CPP) @<< @@ -171,13 +185,112 @@ LINK32_OBJS= \ $(CPP_PROJ) $< << +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32 +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\install.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib wsock32.lib /nologo /subsystem:windows /dll\ + /incremental:yes /pdb:"$(OUTDIR)\install.pdb" /debug /machine:I386\ + /def:".\install.def" /out:"$(OUTDIR)\install.dll"\ + /implib:"$(OUTDIR)\install.lib" /pdbtype:sept +DEF_FILE= \ + ".\install.def" +LINK32_OBJS= \ + "$(INTDIR)\ap_snprintf.obj" \ + "$(INTDIR)\install.obj" + +"$(OUTDIR)\install.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + !IF "$(CFG)" == "install - Win32 Release" || "$(CFG)" ==\ "install - Win32 Debug" +SOURCE=..\..\..\..\ap\ap_snprintf.c + +!IF "$(CFG)" == "install - Win32 Release" + +DEP_CPP_AP_SN=\ + "..\..\..\..\include\alloc.h"\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\buff.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\..\..\include\httpd.h"\ + "..\..\..\..\include\util_uri.h"\ + "..\..\os.h"\ + "..\..\readdir.h"\ + + +"$(INTDIR)\ap_snprintf.obj" : $(SOURCE) $(DEP_CPP_AP_SN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "install - Win32 Debug" + +DEP_CPP_AP_SN=\ + "..\..\..\..\include\alloc.h"\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\buff.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\..\..\include\httpd.h"\ + "..\..\..\..\include\util_uri.h"\ + "..\..\os.h"\ + "..\..\readdir.h"\ + + +"$(INTDIR)\ap_snprintf.obj" : $(SOURCE) $(DEP_CPP_AP_SN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + SOURCE=.\install.c -"$(INTDIR)\install.obj" : $(SOURCE) "$(INTDIR)" +!IF "$(CFG)" == "install - Win32 Release" + +DEP_CPP_INSTA=\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\conf.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\os.h"\ + + +"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)" + +!ELSEIF "$(CFG)" == "install - Win32 Debug" + +DEP_CPP_INSTA=\ + "..\..\..\..\include\ap.h"\ + "..\..\..\..\include\ap_config.h"\ + "..\..\..\..\include\ap_ctype.h"\ + "..\..\..\..\include\ap_mmn.h"\ + "..\..\..\..\include\conf.h"\ + "..\..\..\..\include\hsregex.h"\ + "..\..\os.h"\ + + +"$(INTDIR)\install.obj" : $(SOURCE) $(DEP_CPP_INSTA) "$(INTDIR)" + + +!ENDIF !ENDIF diff --git a/usr.sbin/httpd/src/os/win32/installer/installdll/test/resource.h b/usr.sbin/httpd/src/os/win32/installer/installdll/test/resource.h index 2b47ca12b5c..6d1f9d8b4e5 100644 --- a/usr.sbin/httpd/src/os/win32/installer/installdll/test/resource.h +++ b/usr.sbin/httpd/src/os/win32/installer/installdll/test/resource.h @@ -4,20 +4,23 @@ // #define IDM_TEST 102 #define IDI_TEST 106 +#define IDM_EXIT 106 #define IDD_ABOUT 107 +#define IDD_SETDIRECTORY 109 +#define IDM_ABOUT 303 +#define IDC_DIRECTORY 1000 #define IDM_BEFOREEXIT 40001 -#define IDM_EXIT 106 -#define IDM_ABOUT 303 -#define IDC_STATIC -1 +#define IDM_CONFIGURE 40001 +#define IDC_STATIC -1 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 109 +#define _APS_NEXT_RESOURCE_VALUE 110 #define _APS_NEXT_COMMAND_VALUE 40002 -#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.c b/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.c index c2b5ed43668..8a595094ba5 100644 --- a/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.c +++ b/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.c @@ -3,6 +3,7 @@ */ #include <windows.h> +#include <direct.h> #include "test.h" @@ -12,12 +13,17 @@ HINSTANCE hInst; // current instance char szAppName[100]; // Name of the app char szTitle[100]; // The title bar text +// This is imported from the Apache INSTALL.DLL extern CHAR WINAPI BeforeExit(HWND, LPSTR,LPSTR,LPSTR,LPSTR); BOOL InitApplication(HINSTANCE); BOOL InitInstance(HINSTANCE, int); +BOOL CenterWindow (HWND hwndChild, HWND hwndParent); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK SetDirectory(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); + +char szInstDir[MAX_PATH]; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -30,6 +36,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, lstrcpy (szAppName, APPNAME); lstrcpy (szTitle, APPNAME); + getcwd(szInstDir, sizeof(szInstDir)); + if (!hPrevInstance) { if (!InitApplication(hInstance)) { return (FALSE); @@ -82,8 +90,14 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) hInst = hInstance; hWnd = CreateWindow(szAppName, szTitle, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, - NULL, NULL, hInstance, NULL); + CW_USEDEFAULT, // x + 0, // y + 400, // width + 100, // height + NULL, // parent + NULL, // menu + hInstance, // instance handle + NULL); if (!hWnd) { return (FALSE); @@ -111,10 +125,20 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About); break; - case IDM_BEFOREEXIT: - BeforeExit(hWnd, "C:\\", "C:\\", "C:\\Apache", NULL); + case IDM_CONFIGURE: + { + int rc; + + if (DialogBox(hInst, MAKEINTRESOURCE(IDD_SETDIRECTORY), hWnd, (DLGPROC)SetDirectory) == FALSE) + break; + rc = BeforeExit(hWnd, szInstDir, szInstDir, szInstDir, NULL); + if (rc == 1) { + MessageBox(hWnd, "Configuration successful", + "Configuration successful", + MB_OK); + } break; - + } case IDM_EXIT: DestroyWindow (hWnd); break; @@ -139,6 +163,7 @@ LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_INITDIALOG: + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); return (TRUE); case WM_COMMAND: @@ -152,3 +177,93 @@ LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) return FALSE; } +LRESULT CALLBACK SetDirectory(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + + switch (message) { + case WM_INITDIALOG: + CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER)); + + SetDlgItemText(hDlg, IDC_DIRECTORY, szInstDir); + //SetFocus(GetDlgItem(hDlg, IDC_DIRECTORY)); + return (TRUE); + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDCANCEL: + EndDialog(hDlg, FALSE); + return TRUE; + case IDOK: + GetDlgItemText(hDlg, IDC_DIRECTORY, szInstDir, sizeof(szInstDir)); + EndDialog(hDlg, TRUE); + return TRUE; + } + break; + } + + return FALSE; +} + +// +// FUNCTION: CenterWindow(HWND, HWND) +// +// PURPOSE: Centers one window over another. +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +// This functionwill center one window over another ensuring that +// the placement of the window is within the 'working area', meaning +// that it is both within the display limits of the screen, and not +// obscured by the tray or other framing elements of the desktop. +BOOL CenterWindow (HWND hwndChild, HWND hwndParent) +{ + RECT rChild, rParent, rWorkArea; + int wChild, hChild, wParent, hParent; + int xNew, yNew; + BOOL bResult; + + // Get the Height and Width of the child window + GetWindowRect (hwndChild, &rChild); + wChild = rChild.right - rChild.left; + hChild = rChild.bottom - rChild.top; + + // Get the Height and Width of the parent window + GetWindowRect (hwndParent, &rParent); + wParent = rParent.right - rParent.left; + hParent = rParent.bottom - rParent.top; + + // Get the limits of the 'workarea' + bResult = SystemParametersInfo( + SPI_GETWORKAREA, // system parameter to query or set + sizeof(RECT), + &rWorkArea, + 0); + if (!bResult) { + rWorkArea.left = rWorkArea.top = 0; + rWorkArea.right = GetSystemMetrics(SM_CXSCREEN); + rWorkArea.bottom = GetSystemMetrics(SM_CYSCREEN); + } + + // Calculate new X position, then adjust for workarea + xNew = rParent.left + ((wParent - wChild) /2); + if (xNew < rWorkArea.left) { + xNew = rWorkArea.left; + } else if ((xNew+wChild) > rWorkArea.right) { + xNew = rWorkArea.right - wChild; + } + + // Calculate new Y position, then adjust for workarea + yNew = rParent.top + ((hParent - hChild) /2); + if (yNew < rWorkArea.top) { + yNew = rWorkArea.top; + } else if ((yNew+hChild) > rWorkArea.bottom) { + yNew = rWorkArea.bottom - hChild; + } + + // Set it, and return + return SetWindowPos (hwndChild, NULL, xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER); +} + diff --git a/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.mak b/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.mak index 7f875d2bf40..6dcad364beb 100644 --- a/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.mak +++ b/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.mak @@ -207,15 +207,6 @@ LINK32_OBJS= \ !IF "$(CFG)" == "test - Win32 Release" || "$(CFG)" == "test - Win32 Debug" SOURCE=.\test.c - -!IF "$(CFG)" == "test - Win32 Release" - - -"$(INTDIR)\test.obj" : $(SOURCE) "$(INTDIR)" - - -!ELSEIF "$(CFG)" == "test - Win32 Debug" - DEP_CPP_TEST_=\ ".\test.h"\ @@ -223,8 +214,6 @@ DEP_CPP_TEST_=\ "$(INTDIR)\test.obj" : $(SOURCE) $(DEP_CPP_TEST_) "$(INTDIR)" -!ENDIF - SOURCE=.\test.rc DEP_RSC_TEST_R=\ ".\test.h"\ diff --git a/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.rc b/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.rc index 6f5a94712ee..45ef47efb94 100644 --- a/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.rc +++ b/usr.sbin/httpd/src/os/win32/installer/installdll/test/test.rc @@ -41,14 +41,11 @@ IDI_TEST ICON DISCARDABLE "test.ico" IDM_TEST MENU DISCARDABLE BEGIN - POPUP "&File" + POPUP "&Configure" BEGIN + MENUITEM "&Configure", IDM_CONFIGURE MENUITEM "E&xit", IDM_EXIT END - POPUP "&Test" - BEGIN - MENUITEM "Call &BeforeExit", IDM_BEFOREEXIT - END POPUP "&Help" BEGIN MENUITEM "&About", IDM_ABOUT @@ -91,14 +88,27 @@ END // Dialog // -IDD_ABOUT DIALOG DISCARDABLE 0, 0, 186, 47 +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 186, 62 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dialog" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK",IDOK,129,26,50,14 - LTEXT "Apache Install DLL Tester",IDC_STATIC,7,7,172,14,NOT - WS_GROUP + DEFPUSHBUTTON "OK",IDOK,129,41,50,14 + LTEXT "Apache post-install configuration tester",IDC_STATIC,7, + 7,172,10,NOT WS_GROUP + LTEXT "Copyright 1999 The Apache Group",IDC_STATIC,7,21,172,9 +END + +IDD_SETDIRECTORY DIALOG DISCARDABLE 0, 0, 186, 63 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configure Apache" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,39,42,50,14 + PUSHBUTTON "Cancel",IDCANCEL,95,42,50,14 + LTEXT "Directory where Apache was installled",IDC_STATIC,7,7, + 164,11 + EDITTEXT IDC_DIRECTORY,7,22,172,12,ES_AUTOHSCROLL END @@ -115,7 +125,15 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 179 TOPMARGIN, 7 - BOTTOMMARGIN, 40 + BOTTOMMARGIN, 55 + END + + IDD_SETDIRECTORY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 END END #endif // APSTUDIO_INVOKED diff --git a/usr.sbin/httpd/src/os/win32/os.h b/usr.sbin/httpd/src/os/win32/os.h index da4dd739050..80ffd7e65e3 100644 --- a/usr.sbin/httpd/src/os/win32/os.h +++ b/usr.sbin/httpd/src/os/win32/os.h @@ -18,7 +18,7 @@ #include <direct.h> #define STATUS -#define WIN32_LEAN_AND_MEAN +/*#define WIN32_LEAN_AND_MEAN Now defined in project files */ #ifndef STRICT #define STRICT #endif @@ -34,6 +34,7 @@ #define USE_MMAP_SCOREBOARD #define MULTITHREAD #define HAVE_CANONICAL_FILENAME +#define HAVE_DRIVE_LETTERS typedef int uid_t; typedef int gid_t; typedef int pid_t; @@ -119,4 +120,7 @@ API_EXPORT(int) ap_os_is_filename_valid(const char *file); #define ap_os_dso_sym(h,s) GetProcAddress(h,s) #define ap_os_dso_error() "" /* for now */ +/* Other ap_os_ routines not used by this platform */ +#define ap_os_kill(pid, sig) kill(pid, sig) + #endif /* ! APACHE_OS_H */ diff --git a/usr.sbin/httpd/src/os/win32/registry.c b/usr.sbin/httpd/src/os/win32/registry.c index 0e54ca89811..23eeb5e4495 100644 --- a/usr.sbin/httpd/src/os/win32/registry.c +++ b/usr.sbin/httpd/src/os/win32/registry.c @@ -15,6 +15,16 @@ * release to a development or beta version. */ +/* To allow for multiple services, store the configuration file's full path + * under each service entry: + * + * HKLM\System\CurrentControlSet\Services\[service name]\Parameters\ConfPath + * + * The default configuration path (for console apache) is still stored: + * + * HKLM\Software\[Vendor]\[Software]\[Version]\ServerRoot + */ + #include <windows.h> #include <stdio.h> @@ -28,10 +38,13 @@ #define VENDOR "Apache Group" #define SOFTWARE "Apache" -#define VERSION "1.3.4" +#define VERSION "1.3.9" #define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION +#define SERVICEKEYPRE "System\\CurrentControlSet\\Services\\" +#define SERVICEKEYPOST "\\Parameters" + /* * The Windows API registry key functions don't set the last error * value (the windows equivalent of errno). So we need to set it @@ -79,7 +92,7 @@ * message will be logged at priority "warning". */ -static int ap_registry_get_key_int(pool *p, char *key, char *pBuffer, int nSizeBuffer, char **ppValue) +static int ap_registry_get_key_int(pool *p, char *key, char *name, char *pBuffer, int nSizeBuffer, char **ppValue) { long rv; HKEY hKey; @@ -88,19 +101,18 @@ static int ap_registry_get_key_int(pool *p, char *key, char *pBuffer, int nSizeB int retval; rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, + key, 0, KEY_READ, &hKey); if (rv == ERROR_FILE_NOT_FOUND) { ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, - "Registry does not contain key " REGKEY); + "Registry does not contain key %s",key); return -1; } if (rv != ERROR_SUCCESS) { - do_error(rv, "RegOpenKeyEx HKLM\\" REGKEY, - NULL); + do_error(rv, "RegOpenKeyEx HKLM\\%s",key); return -4; } @@ -110,7 +122,7 @@ static int ap_registry_get_key_int(pool *p, char *key, char *pBuffer, int nSizeB * buffer if the return value is ERROR_SUCCESS. */ rv = RegQueryValueEx(hKey, - key, /* key name */ + name, /* key name */ NULL, /* reserved */ NULL, /* type */ NULL, /* for value */ @@ -139,7 +151,7 @@ static int ap_registry_get_key_int(pool *p, char *key, char *pBuffer, int nSizeB } rv = RegQueryValueEx(hKey, - key, /* key name */ + name, /* key name */ NULL, /* reserved */ NULL, /* type */ pValue, /* for value */ @@ -149,7 +161,7 @@ static int ap_registry_get_key_int(pool *p, char *key, char *pBuffer, int nSizeB if (rv == ERROR_FILE_NOT_FOUND) { ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, - "Registry does not contain value " REGKEY "\\%s", key); + "Registry does not contain value %s\\%s", key, name); retval = -1; } else if (rv == ERROR_MORE_DATA) { @@ -169,7 +181,7 @@ static int ap_registry_get_key_int(pool *p, char *key, char *pBuffer, int nSizeB rv = RegCloseKey(hKey); if (rv != ERROR_SUCCESS) { - do_error(rv, "RegCloseKey HKLM\\" REGKEY, NULL); + do_error(rv, "RegCloseKey HKLM\\%s", key); if (retval == 0) { /* Keep error status from RegQueryValueEx, if any */ retval = -4; @@ -191,7 +203,7 @@ int ap_registry_get_server_root(pool *p, char *dir, int size) { int rv; - rv = ap_registry_get_key_int(p, "ServerRoot", dir, size, NULL); + rv = ap_registry_get_key_int(p, REGKEY, "ServerRoot", dir, size, NULL); if (rv < 0) { dir[0] = '\0'; } @@ -199,10 +211,61 @@ int ap_registry_get_server_root(pool *p, char *dir, int size) return (rv < -1) ? -1 : 0; } +char *ap_get_service_key(char *service_name) +{ + char *key = malloc(strlen(SERVICEKEYPRE) + + strlen(service_name) + + strlen(SERVICEKEYPOST) + 1); + + sprintf(key,"%s%s%s", SERVICEKEYPRE, service_name, SERVICEKEYPOST); + + return(key); +} + +int ap_registry_get_service_conf(pool *p, char *dir, int size, char *service_name) +{ + int rv; + char *key = ap_get_service_key(service_name); + + rv = ap_registry_get_key_int(p, key, "ConfPath", dir, size, NULL); + if (rv < 0) { + dir[0] = '\0'; + } + + free(key); + return (rv < -1) ? -1 : 0; +} + /********************************************************************** * The rest of this file deals with storing keys or values in the registry */ +char *ap_registry_parse_key(int index, char *key) +{ + char *head = key, *skey; + int i; + + if(!key) + return(NULL); + + for(i = 0; i <= index; i++) + { + if(key && key[0] == '\\') + key++; + if (!key) + return(NULL); + head = key; + key = strchr(head, '\\'); + } + + if(!key) + return(strdup(head)); + *key = '\0'; + skey = strdup(head); + *key = '\\'; + return(skey); +} + /* * ap_registry_create_apache_key() creates the Apache registry key * (HLKM\SOFTWARE\Apache Group\Apache\version, as defined at the start @@ -215,31 +278,25 @@ int ap_registry_get_server_root(pool *p, char *dir, int size) * already have been logged. */ -static int ap_registry_create_apache_key(void) +static int ap_registry_create_key(char *longkey) { - static char *keys[] = - { "SOFTWARE", - VENDOR, - SOFTWARE, - VERSION, - NULL - }; int index; HKEY hKey; HKEY hKeyNext; int retval; int rv; + char *key; hKey = HKEY_LOCAL_MACHINE; index = 0; retval = 0; /* Walk the tree, creating at each stage if necessary */ - while (keys[index]) { + while (key=ap_registry_parse_key(index,longkey)) { int result; rv = RegCreateKeyEx(hKey, - keys[index], /* subkey */ + key, /* subkey */ 0, /* reserved */ NULL, /* class */ REG_OPTION_NON_VOLATILE, @@ -248,7 +305,7 @@ static int ap_registry_create_apache_key(void) &hKeyNext, &result); if (rv != ERROR_SUCCESS) { - do_error(rv, "RegCreateKeyEx(%s)", keys[index]); + do_error(rv, "RegCreateKeyEx(%s)", longkey); retval = -4; } @@ -266,11 +323,12 @@ static int ap_registry_create_apache_key(void) break; } + free(key); hKey = hKeyNext; index++; } - if (keys[index] == NULL) { + if (!key) { /* Close the final key we opened, if we walked the entire * tree */ @@ -283,6 +341,8 @@ static int ap_registry_create_apache_key(void) } } } + else + free(key); return retval; } @@ -302,14 +362,14 @@ static int ap_registry_create_apache_key(void) * logged via aplog_error(). */ -static int ap_registry_store_key_int(char *key, DWORD type, void *value, int value_size) +static int ap_registry_store_key_int(char *key, char *name, DWORD type, void *value, int value_size) { long rv; HKEY hKey; int retval; rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, + key, 0, KEY_WRITE, &hKey); @@ -317,7 +377,7 @@ static int ap_registry_store_key_int(char *key, DWORD type, void *value, int val if (rv == ERROR_FILE_NOT_FOUND) { /* Key could not be opened -- try to create it */ - if (ap_registry_create_apache_key() < 0) { + if (ap_registry_create_key(key) < 0) { /* Creation failed (error already reported) */ return -4; } @@ -325,28 +385,26 @@ static int ap_registry_store_key_int(char *key, DWORD type, void *value, int val /* Now it has been created we should be able to open it */ rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, + key, 0, KEY_WRITE, &hKey); if (rv == ERROR_FILE_NOT_FOUND) { - ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, - "Registry does not contain key " REGKEY " after creation"); - + ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, + "Registry does not contain key %s after creation",key); return -1; } } if (rv != ERROR_SUCCESS) { - do_error(rv, "RegOpenKeyEx HKLM\\" REGKEY, - NULL); - return -4; + do_error(rv, "RegOpenKeyEx HKLM\\%s", key); + return -4; } /* Now set the value and data */ rv = RegSetValueEx(hKey, - key, /* value key name */ + name, /* value key name */ 0, /* reserved */ type, /* type */ value, /* value data */ @@ -369,17 +427,34 @@ static int ap_registry_store_key_int(char *key, DWORD type, void *value, int val */ rv = RegCloseKey(hKey); if (rv != ERROR_SUCCESS) { - do_error(rv, "RegCloseKey HKLM\\" REGKEY, NULL); - if (retval == 0) { - /* Keep error status from RegQueryValueEx, if any */ - retval = -4; - } + do_error(rv, "RegCloseKey HKLM\\%s", key); + if (retval == 0) { + /* Keep error status from RegQueryValueEx, if any */ + retval = -4; + } } return retval; } /* + * Sets the service confpath value within the registry. Returns 0 on success + * or -1 on error. If -1 is return the error will already have been + * logged via aplog_error(). + */ + +int ap_registry_set_service_conf(char *conf, char *service_name) +{ + int rv; + char *key = ap_get_service_key(service_name); + + rv = ap_registry_store_key_int(key, "ConfPath", REG_SZ, conf, strlen(conf)+1); + free(key); + + return rv < 0 ? -1: 0; +} + +/* * Sets the serverroot value within the registry. Returns 0 on success * or -1 on error. If -1 is return the error will already have been * logged via aplog_error(). @@ -389,7 +464,8 @@ int ap_registry_set_server_root(char *dir) { int rv; - rv = ap_registry_store_key_int("ServerRoot", REG_SZ, dir, strlen(dir)+1); + rv = ap_registry_store_key_int(REGKEY, "ServerRoot", REG_SZ, dir, strlen(dir)+1); return rv < 0 ? -1 : 0; } + diff --git a/usr.sbin/httpd/src/os/win32/registry.h b/usr.sbin/httpd/src/os/win32/registry.h index cb603184af9..7075e786068 100644 --- a/usr.sbin/httpd/src/os/win32/registry.h +++ b/usr.sbin/httpd/src/os/win32/registry.h @@ -4,3 +4,5 @@ extern int ap_registry_get_server_root(pool *p, char *dir, int size); extern int ap_registry_set_server_root(char *dir); +extern int ap_registry_get_service_conf(pool *p, char *dir, int size, char *service_name); +extern int ap_registry_set_service_conf(char *dir, char *service_name); diff --git a/usr.sbin/httpd/src/os/win32/service.c b/usr.sbin/httpd/src/os/win32/service.c index 8888aa1449b..8108ae1ad93 100644 --- a/usr.sbin/httpd/src/os/win32/service.c +++ b/usr.sbin/httpd/src/os/win32/service.c @@ -26,59 +26,35 @@ static struct FILE *logFile; } globdat; -static void WINAPI service_main_fn(DWORD, char **); +static void WINAPI service_main_fn(DWORD, LPTSTR *); static void WINAPI service_ctrl(DWORD ctrlCode); static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); -static void InstallService(); -static void RemoveService(); +static int ap_start_service(SC_HANDLE); +static int ap_stop_service(SC_HANDLE); - -int service_main(int (*main_fn)(int, char **), int argc, char **argv, - char *service_name, - int install_flag, int run_as_service) +int service_main(int (*main_fn)(int, char **), int argc, char **argv ) { SERVICE_TABLE_ENTRY dispatchTable[] = { - { service_name, service_main_fn }, + { "", service_main_fn }, { NULL, NULL } }; - globdat.name = service_name; + globdat.main_fn = main_fn; + globdat.stop_event = create_event(0, 0, "apache-signal"); + globdat.connected = 1; - if(install_flag > 0) - { - InstallService(); - return(0); - } - else if(install_flag < 0) + if(!StartServiceCtrlDispatcher(dispatchTable)) { - RemoveService(); - return(0); + /* This is a genuine failure of the SCM. */ + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "Error starting service control dispatcher"); + return(globdat.exit_status); } else { - globdat.main_fn = main_fn; - globdat.stop_event = create_event(0, 0, "apache-signal"); - - if(run_as_service) - { - globdat.connected = 1; - if(!StartServiceCtrlDispatcher(dispatchTable)) - { - return((*main_fn)(argc, argv)); - } - else - { - return(globdat.exit_status); - } - } - else - { - globdat.connected = 0; - return((*main_fn)(argc, argv)); - } + return(globdat.exit_status); } - } void service_cd() @@ -90,25 +66,27 @@ void service_cd() chdir(buf); } -void __stdcall service_main_fn(DWORD argc, char **argv) +void __stdcall service_main_fn(DWORD argc, LPTSTR *argv) { - + ap_server_argv0 = globdat.name = argv[0]; if(!(globdat.hServiceStatus = RegisterServiceCtrlHandler( globdat.name, service_ctrl))) { - globdat.exit_status = -1; + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "Failure registering service handler"); return; } - ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000); // wait hint - globdat.exit_status = (*globdat.main_fn)( argc, argv ); - - + service_cd(); + if( service_init() ) + /* Arguments are ok except for \! */ + globdat.exit_status = (*globdat.main_fn)( argc, argv ); + ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0); return; @@ -207,20 +185,25 @@ int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint) return(1); } - -void InstallService() +void InstallService(char *service_name, char *conf) { SC_HANDLE schService; SC_HANDLE schSCManager; TCHAR szPath[512]; + TCHAR szQuotedPath[512]; + + printf("Installing the %s service to use %s\n", service_name, conf); if (GetModuleFileName( NULL, szPath, 512 ) == 0) { - exit(1); + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "GetModuleFileName failed"); return; } + ap_snprintf(szQuotedPath, 512, "\"%s\"", szPath); + schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) @@ -233,13 +216,13 @@ void InstallService() else { schService = CreateService( schSCManager, // SCManager database - globdat.name, // name of service - globdat.name, // name to display + service_name, // name of service + service_name, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type - szPath, // service's binary + szQuotedPath, // service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // dependencies @@ -249,8 +232,9 @@ void InstallService() if (schService) { CloseServiceHandle(schService); - /* Now store the server_root in the registry */ - ap_registry_set_server_root(ap_server_root); + /* Now store the server_root in the registry */ + if(!ap_registry_set_service_conf(conf, service_name)) + printf("The %s service has been installed successfully.\n", service_name ); } else { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, @@ -259,17 +243,16 @@ void InstallService() CloseServiceHandle(schSCManager); } - } - - -void RemoveService() +void RemoveService(char *service_name) { SC_HANDLE schService; SC_HANDLE schSCManager; + printf("Removing the %s service\n", service_name); + schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) @@ -280,7 +263,7 @@ void RemoveService() "OpenSCManager failed"); } else { - schService = OpenService(schSCManager, globdat.name, SERVICE_ALL_ACCESS); + schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS); if (schService == NULL) { /* Could not open the service */ @@ -289,28 +272,160 @@ void RemoveService() } else { /* try to stop the service */ - if (ControlService(schService, SERVICE_CONTROL_STOP, &globdat.ssStatus)) { - Sleep(1000); - while(QueryServiceStatus(schService, &globdat.ssStatus)) { - if(globdat.ssStatus.dwCurrentState == SERVICE_STOP_PENDING) - Sleep(1000); - else - break; - } - } + ap_stop_service(schService); // now remove the service if (DeleteService(schService) == 0) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "DeleteService failed"); + else + printf("The %s service has been removed successfully.\n", service_name ); CloseServiceHandle(schService); } + /* SCM removes registry parameters */ + CloseServiceHandle(schSCManager); + } + +} + +/* A hack to determine if we're running as a service without waiting for + * the SCM to fail; if AllocConsole succeeds, we're a service. + */ + +BOOL isProcessService() { + if( !AllocConsole() ) + return FALSE; + FreeConsole(); + return TRUE; +} + +/* Determine is service_name is a valid service + */ + +BOOL isValidService(char *service_name) { + SC_HANDLE schSCM, schSVC; + int Err; + + if (!(schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenSCManager failed"); + return FALSE; + } + + if ((schSVC = OpenService(schSCM, service_name, SERVICE_ALL_ACCESS))) { + CloseServiceHandle(schSVC); + CloseServiceHandle(schSCM); + return TRUE; + } + + Err = GetLastError(); + if (Err != ERROR_SERVICE_DOES_NOT_EXIST && Err != ERROR_INVALID_NAME) + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenService failed"); + + return FALSE; +} + +int send_signal_to_service(char *service_name, char *sig) { + SC_HANDLE schService; + SC_HANDLE schSCManager; + int success = FALSE; + + enum { start, restart, stop, unknown } action; + static char *param[] = { "start", "restart", "shutdown" }; + static char *participle[] = { "starting", "restarting", "stopping" }; + static char *past[] = { "started", "restarted", "stopped" }; + + for (action = start; action < unknown; action++) + if (!strcasecmp(sig, param[action])) + break; + + if (action == unknown) { + printf("signal must be start, restart, or shutdown\n"); + return FALSE; + } + + schSCManager = OpenSCManager( + NULL, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS // access required + ); + if (!schSCManager) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenSCManager failed"); + } + else { + schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS); + + if (schService == NULL) { + /* Could not open the service */ + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenService failed"); + } + else { + if (!QueryServiceStatus(schService, &globdat.ssStatus)) + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "QueryService failed"); + else { + if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED && action == stop) + printf("The %s service is not started.\n", service_name); + else if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING && action == start) + printf("The %s service has already been started.\n", service_name); + else { + printf("The %s service is %s.\n", service_name, participle[action]); + + if (action == stop || action == restart) + success = ap_stop_service(schService); + if (action == start || action == restart) + success = ap_start_service(schService); + + if( success ) + printf("The %s service has %s.\n", service_name, past[action]); + else + printf("Failed to %s the %s service.\n", sig, service_name ); + } + CloseServiceHandle(schService); + } + } + /* SCM removes registry parameters */ CloseServiceHandle(schSCManager); } + return success; +} +int ap_stop_service(SC_HANDLE schService) +{ + if (ControlService(schService, SERVICE_CONTROL_STOP, &globdat.ssStatus)) { + Sleep(1000); + while (QueryServiceStatus(schService, &globdat.ssStatus)) { + if (globdat.ssStatus.dwCurrentState == SERVICE_STOP_PENDING) + Sleep(1000); + else + break; + } + } + if (QueryServiceStatus(schService, &globdat.ssStatus)) + if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) + return TRUE; + return FALSE; } +int ap_start_service(SC_HANDLE schService) { + if (StartService(schService, 0, NULL)) { + Sleep(1000); + while(QueryServiceStatus(schService, &globdat.ssStatus)) { + if(globdat.ssStatus.dwCurrentState == SERVICE_START_PENDING) + Sleep(1000); + else + break; + } + } + if (QueryServiceStatus(schService, &globdat.ssStatus)) + if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING) + return TRUE; + return FALSE; +} + #endif /* WIN32 */ - diff --git a/usr.sbin/httpd/src/os/win32/service.h b/usr.sbin/httpd/src/os/win32/service.h index e8b3316ea3d..822596c4161 100644 --- a/usr.sbin/httpd/src/os/win32/service.h +++ b/usr.sbin/httpd/src/os/win32/service.h @@ -3,11 +3,15 @@ #define SERVICE_H #ifdef WIN32 -int service_main(int (*main_fn)(int, char **), int argc, char **argv, - char *service_name, - int install_flag, int run_as_service); +int service_main(int (*main_fn)(int, char **), int argc, char **argv); void service_set_status(int status); void service_cd(); +BOOL isProcessService(); +BOOL isValidService(char *service_name); +void InstallService(char *service_name, char *conf); +void RemoveService(char *service_name); +int service_init(); +int send_signal_to_service(char *service_name, char *sig); #endif /* WIN32 */ #endif /* SERVICE_H */ diff --git a/usr.sbin/httpd/src/os/win32/util_win32.c b/usr.sbin/httpd/src/os/win32/util_win32.c index 249faf28e6a..348e0f9e2aa 100644 --- a/usr.sbin/httpd/src/os/win32/util_win32.c +++ b/usr.sbin/httpd/src/os/win32/util_win32.c @@ -571,7 +571,7 @@ API_EXPORT(int) os_strftime(char *s, size_t max, const char *format, API_EXPORT(int) ap_os_is_filename_valid(const char *file) { const char *segstart; - char seglength; + unsigned int seglength; const char *pos; static const char * const invalid_characters = "?\"<>*|:"; static const char * const invalid_filenames[] = { @@ -621,8 +621,8 @@ API_EXPORT(int) ap_os_is_filename_valid(const char *file) } while (*pos) { - int idx; - int baselength; + unsigned int idx; + unsigned int baselength; while (*pos == '/' || *pos == '\\') { pos++; @@ -642,7 +642,7 @@ API_EXPORT(int) ap_os_is_filename_valid(const char *file) /* Test 2 */ for (idx = 0; idx < seglength; idx++) { - if (segstart[idx] < 32 || + if ((segstart[idx] > 0 && segstart[idx] < 32) || strchr(invalid_characters, segstart[idx])) { return 0; } @@ -665,7 +665,8 @@ API_EXPORT(int) ap_os_is_filename_valid(const char *file) * if it does not include any dot characters). */ if (baselength == 3 || baselength == 4) { for (idx = 0; invalid_filenames[idx]; idx++) { - if (!strnicmp(invalid_filenames[idx], segstart, baselength)) { + if (strlen(invalid_filenames[idx]) == baselength && + !strnicmp(invalid_filenames[idx], segstart, baselength)) { return 0; } } diff --git a/usr.sbin/httpd/src/regex/debug.c b/usr.sbin/httpd/src/regex/debug.c index c0feaeb1694..fdf49f6cdea 100644 --- a/usr.sbin/httpd/src/regex/debug.c +++ b/usr.sbin/httpd/src/regex/debug.c @@ -4,8 +4,9 @@ #include <limits.h> #include <stdlib.h> #include <sys/types.h> -#include <regex.h> +#include "hsregex.h" +#include "ap_ctype.h" #include "utils.h" #include "regex2.h" #include "debug.ih" @@ -234,7 +235,7 @@ int ch; { static char buf[10]; - if (isprint(ch) || ch == ' ') + if (ap_isprint(ch) || ch == ' ') sprintf(buf, "%c", ch); else sprintf(buf, "\\%o", ch); diff --git a/usr.sbin/httpd/src/regex/main.c b/usr.sbin/httpd/src/regex/main.c index 657338a2c19..1c4364cae9f 100644 --- a/usr.sbin/httpd/src/regex/main.c +++ b/usr.sbin/httpd/src/regex/main.c @@ -1,10 +1,10 @@ #include <stdio.h> #include <string.h> #include <sys/types.h> -#include <regex.h> #include <assert.h> #include <stdlib.h> +#include "hsregex.h" #include "main.ih" char *progname; @@ -20,6 +20,8 @@ regoff_t endoff = 0; extern int split(); extern void regprint(); +extern int optind; +extern char *optarg; /* - main - do the simple case, hand off to regress() for regression @@ -37,8 +39,6 @@ char *argv[]; int c; int errflg = 0; register int i; - extern int optind; - extern char *optarg; progname = argv[0]; diff --git a/usr.sbin/httpd/src/regex/regex.3 b/usr.sbin/httpd/src/regex/regex.3 index 6d4f9b89b8d..100c8a7f71c 100644 --- a/usr.sbin/httpd/src/regex/regex.3 +++ b/usr.sbin/httpd/src/regex/regex.3 @@ -36,7 +36,7 @@ matches that internal form against a string and reports results, transforms error codes from either into human-readable messages, and .I regfree -frees any dynamically allocated storage used by the internal form +frees any dynamically-allocated storage used by the internal form of an RE. .PP The header @@ -353,7 +353,7 @@ caution in software intended to be portable to other systems. Be warned also that they are considered experimental and changes are possible. .PP .I Regfree -frees any dynamically allocated storage associated with the compiled RE +frees any dynamically-allocated storage associated with the compiled RE pointed to by .IR preg . The remaining diff --git a/usr.sbin/httpd/src/regex/regex.7 b/usr.sbin/httpd/src/regex/regex.7 index fcec9a8b37c..d89012bda1d 100644 --- a/usr.sbin/httpd/src/regex/regex.7 +++ b/usr.sbin/httpd/src/regex/regex.7 @@ -93,7 +93,7 @@ or a collating-sequence name for either) enclosed in `[.' and `.]' stands for the sequence of characters of that collating element. The sequence is a single element of the bracket expression's list. -A bracket expression containing a multi-character collating element +A bracket expression containing a multi-character collating element can thus match more than one character, e.g. if the collating sequence includes a `ch' collating element, then the RE `[[.ch.]]*c' matches the first five characters diff --git a/usr.sbin/httpd/src/regex/split.c b/usr.sbin/httpd/src/regex/split.c index 188bdb775b9..6359aba8ab4 100644 --- a/usr.sbin/httpd/src/regex/split.c +++ b/usr.sbin/httpd/src/regex/split.c @@ -1,6 +1,8 @@ #include <stdio.h> #include <string.h> +extern int split(char *, char *[], int, char *); + /* - split - divide a string into fields, like awk split() = int split(char *string, char *fields[], int nfields, char *sep); diff --git a/usr.sbin/httpd/src/support/Makefile.tmpl b/usr.sbin/httpd/src/support/Makefile.tmpl index 216d9657ea4..33c13777739 100644 --- a/usr.sbin/httpd/src/support/Makefile.tmpl +++ b/usr.sbin/httpd/src/support/Makefile.tmpl @@ -1,6 +1,6 @@ CFLAGS=$(OPTIM) $(CFLAGS1) $(EXTRA_CFLAGS) -LIBS=-los -lap $(EXTRA_LIBS) $(LIBS1) +LIBS=-lap -los $(EXTRA_LIBS) $(LIBS1) INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES) LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS) -L$(OSDIR) -L$(SRCDIR)/ap @@ -35,18 +35,12 @@ apxs: apxs.pl -e 's%@CFLAGS@%$(CFLAGS)%g' \ -e 's%@CFLAGS_SHLIB@%$(CFLAGS_SHLIB)%g' \ -e 's%@LD_SHLIB@%$(LD_SHLIB)%g' \ - -e 's%@LDFLAGS_SHLIB@%$(LDFLAGS_SHLIB)%g' \ + -e 's%@LDFLAGS_MOD_SHLIB@%$(LDFLAGS_MOD_SHLIB)%g' \ -e 's%@LIBS_SHLIB@%$(LIBS_SHLIB)%g' && chmod a+x apxs suexec: suexec.o $(CC) $(CFLAGS) suexec.o -o suexec $(LDFLAGS) $(LIBS) -ca-fix: ca-fix.c - $(CC) $(INCLUDES) $(CFLAGS) $(SSL_CFLAGS) \ - $(LDFLAGS) $(SSL_LDFLAGS) \ - -o ca-fix ca-fix.c \ - $(LIBS) $(SSL_LIBS) - clean: rm -f $(TARGETS) *.o @@ -74,7 +68,7 @@ ab.o: ab.c $(INCDIR)/ap_config.h $(INCDIR)/ap_config_auto.h \ $(OSDIR)/os.h $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h htdigest.o: htdigest.c $(INCDIR)/ap_config.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(INCDIR)/ap_ctype.h \ - $(INCDIR)/hsregex.h ../main/md5c.c $(INCDIR)/ap_md5.h + $(INCDIR)/hsregex.h $(INCDIR)/ap_md5.h htpasswd.o: htpasswd.c $(INCDIR)/ap_config.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(INCDIR)/ap_ctype.h \ $(INCDIR)/hsregex.h diff --git a/usr.sbin/httpd/src/support/ab.1 b/usr.sbin/httpd/src/support/ab.1 deleted file mode 100644 index 2a034d2d9ee..00000000000 --- a/usr.sbin/httpd/src/support/ab.1 +++ /dev/null @@ -1,114 +0,0 @@ -.TH ab 1 "March 1998" -.\" Copyright (c) 1998-1999 The Apache Group. 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. All advertising materials mentioning features or use of this -.\" software must display the following acknowledgment: -.\" "This product includes software developed by the Apache Group -.\" for use in the Apache HTTP server project (http://www.apache.org/)." -.\" -.\" 4. The names "Apache Server" and "Apache Group" must not be used to -.\" endorse or promote products derived from this software without -.\" prior written permission. -.\" -.\" 5. Products derived from this software may not be called "Apache" -.\" nor may "Apache" appear in their names without prior written -.\" permission of the Apache Group. -.\" -.\" 6. Redistributions of any form whatsoever must retain the following -.\" acknowledgment: -.\" "This product includes software developed by the Apache Group -.\" for use in the Apache HTTP server project (http://www.apache.org/)." -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -.\" OF THE POSSIBILITY OF SUCH DAMAGE. -.\" ==================================================================== -.\" -.\" This software consists of voluntary contributions made by many -.\" individuals on behalf of the Apache Group and was originally based -.\" on public domain software written at the National Center for -.\" Supercomputing Applications, University of Illinois, Urbana-Champaign. -.\" For more information on the Apache Group and the Apache HTTP server -.\" project, please see <http://www.apache.org/>. -.SH NAME -ab \- Apache HTTP server benchmarking tool -.SH SYNOPSIS -.B ab -[ -.B \-k -] [ -.BI \-n " requests" -] [ -.BI \-t " timelimit" -] [ -.BI \-c " concurrency" -] -.I [http://]hostname[:port]/path - -.B ab -[ -.B \-v -] [ -.B \-h -] -.PP -.SH DESCRIPTION -.B ab -is a tool for benchmarking your Apache HyperText Transfer Protocol (HTTP) -server. It is designed to give you an impression on how performant is your -current Apache installation. This especially shows you how much requests per -time your Apache installation is capable to serve. -.PP -.SH OPTIONS -.TP 12 -.B \-k -Enable the HTTP KeepAlive feature, i.e. perform multiple requests within one -HTTP session instead. Default is no KeepAlive. -.TP 12 -.BI \-n " requests" -Number of requests to perform for the benchmarking session. The default is to -just perform one single request which usually leads to not very representative -benchmarking results. -.TP 12 -.BI \-t " timelimit" -Seconds to max. spend for benchmarking. This implies -a -.B \-n -.B 50000 -internally. Use this to benchmark the server within a fixed total amount of -time. Per default there is no timelimit. -.TP 12 -.BI \-c " concurrency" -Number of multiple requests per time to perform. -Default is one request per time. -.TP 12 -.B \-v -Display version and copyright information. -.TP 12 -.B \-h -Display usage information. -.PD -.SH SEE ALSO -.BR httpd(8) -. diff --git a/usr.sbin/httpd/src/support/ab.c b/usr.sbin/httpd/src/support/ab.c index 051d19e8dd8..0d968b247a2 100644 --- a/usr.sbin/httpd/src/support/ab.c +++ b/usr.sbin/httpd/src/support/ab.c @@ -6,7 +6,7 @@ * are met: * * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 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 @@ -55,33 +55,35 @@ * */ -/* -** This program is based on ZeusBench V1.0 written by Adam Twiss -** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/ -** -** This software is provided "as is" and any express or implied waranties, -** including but not limited to, the implied warranties of merchantability and -** fitness for a particular purpose are disclaimed. In no event shall -** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, -** exemplary, or consequential damaged (including, but not limited to, -** procurement of substitute good or services; loss of use, data, or profits; -** or business interruption) however caused and on theory of liability. Whether -** in contract, strict liability or tort (including negligence or otherwise) -** arising in any way out of the use of this software, even if advised of the -** possibility of such damage. -** -*/ +/* + ** This program is based on ZeusBench V1.0 written by Adam Twiss + ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/ + ** + ** This software is provided "as is" and any express or implied waranties, + ** including but not limited to, the implied warranties of merchantability and + ** fitness for a particular purpose are disclaimed. In no event shall + ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, + ** exemplary, or consequential damaged (including, but not limited to, + ** procurement of substitute good or services; loss of use, data, or profits; + ** or business interruption) however caused and on theory of liability. Whether + ** in contract, strict liability or tort (including negligence or otherwise) + ** arising in any way out of the use of this software, even if advised of the + ** possibility of such damage. + ** + */ /* -** HISTORY: -** - Originally written by Adam Twiss <adam@zeus.co.uk>, March 1996 -** with input from Mike Belshe <mbelshe@netscape.com> and -** Michael Campanella <campanella@stevms.enet.dec.com> -** - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997 -** - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998 -** - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998 -** -*/ + ** HISTORY: + ** - Originally written by Adam Twiss <adam@zeus.co.uk>, March 1996 + ** with input from Mike Belshe <mbelshe@netscape.com> and + ** Michael Campanella <campanella@stevms.enet.dec.com> + ** - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997 + ** - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998 + ** - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998 + ** - HTML table output added by David N. Welton <davidw@prosa.it>, January 1999 + ** - Added Cookie, Arbitrary header and auth support. <dirkx@webweaving.org>, April 199 + ** + */ /* * BUGS: @@ -95,7 +97,7 @@ * only an issue for loopback usage */ -#define VERSION "1.2" +#define VERSION "1.3a" /* -------------------------------------------------------------------- */ @@ -118,12 +120,22 @@ #include <sys/ioctl.h> #include <string.h> -#define ap_select select -#else /* (!)NO_APACHE_INCLUDES */ +#define ap_select select +#else /* (!)NO_APACHE_INCLUDES */ #include "ap_config.h" +#include "ap.h" +#ifdef CHARSET_EBCDIC +#include "ebcdic.h" +#endif #include <fcntl.h> #include <sys/time.h> -#endif /* NO_APACHE_INCLUDES */ + +#ifndef NO_WRITEV +#include <sys/types.h> +#include <sys/uio.h> +#endif + +#endif /* NO_APACHE_INCLUDES */ /* ------------------- DEFINITIONS -------------------------- */ /* maximum number of requests on a time limited test */ @@ -139,20 +151,21 @@ struct connection { int fd; int state; - int read; /* amount of bytes read */ - int bread; /* amount of body read */ - int length; /* Content-Length value used for keep-alive */ - char cbuff[CBUFFSIZE]; /* a buffer to store server response header */ - int cbx; /* offset in cbuffer */ - int keepalive; /* non-zero if a keep-alive request */ - int gotheader; /* non-zero if we have the entire header in cbuff */ + int read; /* amount of bytes read */ + int bread; /* amount of body read */ + int length; /* Content-Length value used for keep-alive */ + char cbuff[CBUFFSIZE]; /* a buffer to store server response header */ + int cbx; /* offset in cbuffer */ + int keepalive; /* non-zero if a keep-alive request */ + int gotheader; /* non-zero if we have the entire header in + * cbuff */ struct timeval start, connect, done; }; struct data { - int read; /* number of bytes read */ - int ctime; /* time in ms to connect */ - int time; /* time in ms for connection */ + int read; /* number of bytes read */ + int ctime; /* time in ms to connect */ + int time; /* time in ms for connection */ }; #define ap_min(a,b) ((a)<(b))?(a):(b) @@ -160,28 +173,37 @@ struct data { /* --------------------- GLOBALS ---------------------------- */ -int verbosity = 0; /* no verbosity by default */ -int posting = 0; /* GET by default */ -int requests = 1; /* Number of requests to make */ -int concurrency = 1; /* Number of multiple requests to make */ -int tlimit = 0; /* time limit in cs */ -int keepalive = 0; /* try and do keepalive connections */ -char servername[1024]; /* name that server reports */ -char hostname[1024]; /* host name */ -char path[1024]; /* path name */ -char postfile[1024]; /* name of file containing post data */ -char* postdata; /* *buffer containing data from postfile */ -int postlen = 0; /* length of data to be POSTed */ -char content_type[1024]; /* content type to put in POST header */ -int port = 80; /* port number */ - -int doclen = 0; /* the length the document should be */ -int totalread = 0; /* total number of bytes read */ -int totalbread = 0; /* totoal amount of entity body read */ -int totalposted = 0; /* total number of bytes posted, inc. headers */ -int done = 0; /* number of requests we have done */ -int doneka = 0; /* number of keep alive connections done */ -int good = 0, bad = 0; /* number of good and bad requests */ +int verbosity = 0; /* no verbosity by default */ +int posting = 0; /* GET by default */ +int requests = 1; /* Number of requests to make */ +int concurrency = 1; /* Number of multiple requests to make */ +int tlimit = 0; /* time limit in cs */ +int keepalive = 0; /* try and do keepalive connections */ +char servername[1024]; /* name that server reports */ +char hostname[1024]; /* host name */ +char path[1024]; /* path name */ +char postfile[1024]; /* name of file containing post data */ +char *postdata; /* *buffer containing data from postfile */ +int postlen = 0; /* length of data to be POSTed */ +char content_type[1024]; /* content type to put in POST header */ +char cookie[1024], /* optional cookie line */ + auth[1024], /* optional (basic/uuencoded) + * authentification */ + hdrs[4096]; /* optional arbitrary headers */ +int port = 80; /* port number */ + +int use_html = 0; /* use html in the report */ +char *tablestring; +char *trstring; +char *tdstring; + +int doclen = 0; /* the length the document should be */ +int totalread = 0; /* total number of bytes read */ +int totalbread = 0; /* totoal amount of entity body read */ +int totalposted = 0; /* total number of bytes posted, inc. headers */ +int done = 0; /* number of requests we have done */ +int doneka = 0; /* number of keep alive connections done */ +int good = 0, bad = 0; /* number of good and bad requests */ /* store error cases */ int err_length = 0, err_conn = 0, err_except = 0; @@ -196,11 +218,11 @@ int reqlen; /* one global throw-away buffer to read stuff into */ char buffer[8192]; -struct connection *con; /* connection array */ -struct data *stats; /* date for each request */ +struct connection *con; /* connection array */ +struct data *stats; /* date for each request */ -fd_set readbits, writebits; /* bits for select */ -struct sockaddr_in server; /* server addr structure */ +fd_set readbits, writebits; /* bits for select */ +struct sockaddr_in server; /* server addr structure */ /* --------------------------------------------------------- */ @@ -209,7 +231,7 @@ struct sockaddr_in server; /* server addr structure */ static void err(char *s) { if (errno) { - perror(s); + perror(s); } else { printf("%s", s); @@ -219,18 +241,33 @@ static void err(char *s) /* --------------------------------------------------------- */ -/* write out request to a connection - assumes we can write +/* write out request to a connection - assumes we can write (small) request out in one go into our new socket buffer */ -static void write_request(struct connection *c) +static void write_request(struct connection * c) { +#ifndef NO_WRITEV + struct iovec out[2]; int outcnt = 1; +#endif gettimeofday(&c->connect, 0); - /* XXX: this could use writev for posting -- more efficient -djg */ - write(c->fd, request, reqlen); +#ifndef NO_WRITEV + out[0].iov_base = request; + out[0].iov_len = reqlen; + if (posting) { - write(c->fd,postdata, postlen); - totalposted += (reqlen + postlen); + out[1].iov_base = postdata; + out[1].iov_len = postlen; + outcnt = 2; + totalposted += (reqlen + postlen); } + writev(c->fd,out, outcnt); +#else + write(c->fd,request,reqlen); + if (posting) { + write(c->fd,postdata,postlen); + totalposted += (reqlen + postlen); + } +#endif c->state = STATE_READ; FD_SET(c->fd, &readbits); @@ -283,65 +320,191 @@ static void output_results(void) printf("\n"); printf("Concurrency Level: %d\n", concurrency); printf("Time taken for tests: %d.%03d seconds\n", - timetaken / 1000, timetaken % 1000); + timetaken / 1000, timetaken % 1000); printf("Complete requests: %d\n", done); printf("Failed requests: %d\n", bad); if (bad) - printf(" (Connect: %d, Length: %d, Exceptions: %d)\n", - err_conn, err_length, err_except); + printf(" (Connect: %d, Length: %d, Exceptions: %d)\n", + err_conn, err_length, err_except); if (err_response) - printf("Non-2xx responses: %d\n", err_response); + printf("Non-2xx responses: %d\n", err_response); if (keepalive) - printf("Keep-Alive requests: %d\n", doneka); + printf("Keep-Alive requests: %d\n", doneka); printf("Total transferred: %d bytes\n", totalread); if (posting) - printf("Total POSTed: %d\n", totalposted); + printf("Total POSTed: %d\n", totalposted); printf("HTML transferred: %d bytes\n", totalbread); /* avoid divide by zero */ if (timetaken) { - printf("Requests per second: %.2f\n", 1000 * (float) (done) / timetaken); - printf("Transfer rate: %.2f kb/s received\n", - (float) (totalread) / timetaken); - if (posting) { - printf(" %.2f kb/s sent\n", - (float)(totalposted)/timetaken); - printf(" %.2f kb/s total\n", - (float)(totalread + totalposted)/timetaken); - } + printf("Requests per second: %.2f\n", 1000 * (float) (done) / timetaken); + printf("Transfer rate: %.2f kb/s received\n", + (float) (totalread) / timetaken); + if (posting) { + printf(" %.2f kb/s sent\n", + (float) (totalposted) / timetaken); + printf(" %.2f kb/s total\n", + (float) (totalread + totalposted) / timetaken); + } } { - /* work out connection times */ - int i; - int totalcon = 0, total = 0; - int mincon = 9999999, mintot = 999999; - int maxcon = 0, maxtot = 0; - - for (i = 0; i < requests; i++) { - struct data s = stats[i]; - mincon = ap_min(mincon, s.ctime); - mintot = ap_min(mintot, s.time); - maxcon = ap_max(maxcon, s.ctime); - maxtot = ap_max(maxtot, s.time); - totalcon += s.ctime; - total += s.time; - } - printf("\nConnnection Times (ms)\n"); - printf(" min avg max\n"); - printf("Connect: %5d %5d %5d\n", mincon, totalcon / requests, maxcon); - printf("Processing: %5d %5d %5d\n", - mintot - mincon, (total/requests) - (totalcon/requests), - maxtot - maxcon); - printf("Total: %5d %5d %5d\n", mintot, total / requests, maxtot); + /* work out connection times */ + int i; + int totalcon = 0, total = 0; + int mincon = 9999999, mintot = 999999; + int maxcon = 0, maxtot = 0; + + for (i = 0; i < requests; i++) { + struct data s = stats[i]; + mincon = ap_min(mincon, s.ctime); + mintot = ap_min(mintot, s.time); + maxcon = ap_max(maxcon, s.ctime); + maxtot = ap_max(maxtot, s.time); + totalcon += s.ctime; + total += s.time; + } + if (requests > 0) { /* avoid division by zero (if 0 requests) */ + printf("\nConnnection Times (ms)\n"); + printf(" min avg max\n"); + printf("Connect: %5d %5d %5d\n", mincon, totalcon / requests, maxcon); + printf("Processing: %5d %5d %5d\n", + mintot - mincon, (total / requests) - (totalcon / requests), + maxtot - maxcon); + printf("Total: %5d %5d %5d\n", mintot, total / requests, maxtot); + } + } +} + +/* --------------------------------------------------------- */ + +/* calculate and output results in HTML */ + +static void output_html_results(void) +{ + int timetaken; + + gettimeofday(&endtime, 0); + timetaken = timedif(endtime, start); + + printf("\n\n<table %s>\n", tablestring); + printf("<tr %s><th colspan=2 %s>Server Software:</th>" + "<td colspan=2 %s>%s</td></tr>\n", + trstring, tdstring, tdstring, servername); + printf("<tr %s><th colspan=2 %s>Server Hostname:</th>" + "<td colspan=2 %s>%s</td></tr>\n", + trstring, tdstring, tdstring, hostname); + printf("<tr %s><th colspan=2 %s>Server Port:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, port); + printf("<tr %s><th colspan=2 %s>Document Path:</th>" + "<td colspan=2 %s>%s</td></tr>\n", + trstring, tdstring, tdstring, path); + printf("<tr %s><th colspan=2 %s>Document Length:</th>" + "<td colspan=2 %s>%d bytes</td></tr>\n", + trstring, tdstring, tdstring, doclen); + printf("<tr %s><th colspan=2 %s>Concurrency Level:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, concurrency); + printf("<tr %s><th colspan=2 %s>Time taken for tests:</th>" + "<td colspan=2 %s>%d.%03d seconds</td></tr>\n", + trstring, tdstring, tdstring, timetaken / 1000, timetaken % 1000); + printf("<tr %s><th colspan=2 %s>Complete requests:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, done); + printf("<tr %s><th colspan=2 %s>Failed requests:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, bad); + if (bad) + printf("<tr %s><td colspan=4 %s > (Connect: %d, Length: %d, Exceptions: %d)</td></tr>\n", + trstring, tdstring, err_conn, err_length, err_except); + if (err_response) + printf("<tr %s><th colspan=2 %s>Non-2xx responses:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, err_response); + if (keepalive) + printf("<tr %s><th colspan=2 %s>Keep-Alive requests:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, doneka); + printf("<tr %s><th colspan=2 %s>Total transferred:</th>" + "<td colspan=2 %s>%d bytes</td></tr>\n", + trstring, tdstring, tdstring, totalread); + if (posting) + printf("<tr %s><th colspan=2 %s>Total POSTed:</th>" + "<td colspan=2 %s>%d</td></tr>\n", + trstring, tdstring, tdstring, totalposted); + printf("<tr %s><th colspan=2 %s>HTML transferred:</th>" + "<td colspan=2 %s>%d bytes</td></tr>\n", + trstring, tdstring, tdstring, totalbread); + + /* avoid divide by zero */ + if (timetaken) { + printf("<tr %s><th colspan=2 %s>Requests per second:</th>" + "<td colspan=2 %s>%.2f</td></tr>\n", + trstring, tdstring, tdstring, 1000 * (float) (done) / timetaken); + printf("<tr %s><th colspan=2 %s>Transfer rate:</th>" + "<td colspan=2 %s>%.2f kb/s received</td></tr>\n", + trstring, tdstring, tdstring, (float) (totalread) / timetaken); + if (posting) { + printf("<tr %s><td colspan=2 %s> </td>" + "<td colspan=2 %s>%.2f kb/s sent</td></tr>\n", + trstring, tdstring, tdstring, + (float) (totalposted) / timetaken); + printf("<tr %s><td colspan=2 %s> </td>" + "<td colspan=2 %s>%.2f kb/s total</td></tr>\n", + trstring, tdstring, tdstring, + (float) (totalread + totalposted) / timetaken); + } + } + + { + /* work out connection times */ + int i; + int totalcon = 0, total = 0; + int mincon = 9999999, mintot = 999999; + int maxcon = 0, maxtot = 0; + + for (i = 0; i < requests; i++) { + struct data s = stats[i]; + mincon = ap_min(mincon, s.ctime); + mintot = ap_min(mintot, s.time); + maxcon = ap_max(maxcon, s.ctime); + maxtot = ap_max(maxtot, s.time); + totalcon += s.ctime; + total += s.time; + } + + if (requests > 0) { /* avoid division by zero (if 0 requests) */ + printf("<tr %s><th %s colspan=4>Connnection Times (ms)</th></tr>\n", + trstring, tdstring); + printf("<tr %s><th %s> </th> <th %s>min</th> <th %s>avg</th> <th %s>max</th></tr>\n", + trstring, tdstring, tdstring, tdstring, tdstring); + printf("<tr %s><th %s>Connect:</th>" + "<td %s>%5d</td>" + "<td %s>%5d</td>" + "<td %s>%5d</td></tr>\n", + trstring, tdstring, tdstring, mincon, tdstring, totalcon / requests, tdstring, maxcon); + printf("<tr %s><th %s>Processing:</th>" + "<td %s>%5d</td>" + "<td %s>%5d</td>" + "<td %s>%5d</td></tr>\n", + trstring, tdstring, tdstring, mintot - mincon, tdstring, + (total / requests) - (totalcon / requests), tdstring, maxtot - maxcon); + printf("<tr %s><th %s>Total:</th>" + "<td %s>%5d</td>" + "<td %s>%5d</td>" + "<td %s>%5d</td></tr>\n", + trstring, tdstring, tdstring, mintot, tdstring, total / requests, tdstring, maxtot); + } + printf("</table>\n"); } } /* --------------------------------------------------------- */ -/* start asynchronous non-blocking connection */ +/* start asnchronous non-blocking connection */ -static void start_connect(struct connection *c) +static void start_connect(struct connection * c) { c->read = 0; c->bread = 0; @@ -351,25 +514,25 @@ static void start_connect(struct connection *c) c->fd = socket(AF_INET, SOCK_STREAM, 0); if (c->fd < 0) - err("socket"); + err("socket"); nonblock(c->fd); gettimeofday(&c->start, 0); - if (connect(c->fd, (struct sockaddr *) &server, sizeof(server)) < 0) { - if (errno == EINPROGRESS) { - c->state = STATE_CONNECTING; - FD_SET(c->fd, &writebits); - return; - } - else { - close(c->fd); - err_conn++; - if (bad++ > 10) { - err("\nTest aborted after 10 failures\n\n"); - } - start_connect(c); - } + if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) { + if (errno == EINPROGRESS) { + c->state = STATE_CONNECTING; + FD_SET(c->fd, &writebits); + return; + } + else { + close(c->fd); + err_conn++; + if (bad++ > 10) { + err("\nTest aborted after 10 failures\n\n"); + } + start_connect(c); + } } /* connected first time */ @@ -380,31 +543,31 @@ static void start_connect(struct connection *c) /* close down connection and save stats */ -static void close_connection(struct connection *c) +static void close_connection(struct connection * c) { if (c->read == 0 && c->keepalive) { - /* server has legitimately shut down an idle keep alive request */ - good--; /* connection never happend */ + /* server has legitimately shut down an idle keep alive request */ + good--; /* connection never happend */ } else { - if (good == 1) { - /* first time here */ - doclen = c->bread; - } - else if (c->bread != doclen) { - bad++; - err_length++; - } - - /* save out time */ - if (done < requests) { - struct data s; - gettimeofday(&c->done, 0); - s.read = c->read; - s.ctime = timedif(c->connect, c->start); - s.time = timedif(c->done, c->start); - stats[done++] = s; - } + if (good == 1) { + /* first time here */ + doclen = c->bread; + } + else if (c->bread != doclen) { + bad++; + err_length++; + } + + /* save out time */ + if (done < requests) { + struct data s; + gettimeofday(&c->done, 0); + s.read = c->read; + s.ctime = timedif(c->connect, c->start); + s.time = timedif(c->done, c->start); + stats[done++] = s; + } } close(c->fd); @@ -420,148 +583,154 @@ static void close_connection(struct connection *c) /* read data from connection */ -static void read_connection(struct connection *c) +static void read_connection(struct connection * c) { int r; char *part; - char respcode[4]; /* 3 digits and null */ + char respcode[4]; /* 3 digits and null */ r = read(c->fd, buffer, sizeof(buffer)); if (r == 0 || (r < 0 && errno != EAGAIN)) { - good++; - close_connection(c); - return; + good++; + close_connection(c); + return; } if (r < 0 && errno == EAGAIN) - return; + return; c->read += r; totalread += r; if (!c->gotheader) { - char *s; - int l = 4; - int space = CBUFFSIZE - c->cbx - 1; /* -1 to allow for 0 terminator */ - int tocopy = (space < r) ? space : r; + char *s; + int l = 4; + int space = CBUFFSIZE - c->cbx - 1; /* -1 to allow for 0 + * terminator */ + int tocopy = (space < r) ? space : r; #ifndef CHARSET_EBCDIC - memcpy(c->cbuff + c->cbx, buffer, space); -#else /*CHARSET_EBCDIC*/ - ascii2ebcdic(c->cbuff + c->cbx, buffer, space); -#endif /*CHARSET_EBCDIC*/ - c->cbx += tocopy; - space -= tocopy; - c->cbuff[c->cbx] = 0; /* terminate for benefit of strstr */ + memcpy(c->cbuff + c->cbx, buffer, tocopy); +#else /* CHARSET_EBCDIC */ + ascii2ebcdic(c->cbuff + c->cbx, buffer, tocopy); +#endif /* CHARSET_EBCDIC */ + c->cbx += tocopy; + space -= tocopy; + c->cbuff[c->cbx] = 0; /* terminate for benefit of strstr */ if (verbosity >= 4) { printf("LOG: header received:\n%s\n", c->cbuff); } - s = strstr(c->cbuff, "\r\n\r\n"); - /* this next line is so that we talk to NCSA 1.5 which blatantly breaks - the http specifaction */ - if (!s) { - s = strstr(c->cbuff, "\n\n"); - l = 2; - } - - if (!s) { - /* read rest next time */ - if (space) - return; - else { - /* header is in invalid or too big - close connection */ - close(c->fd); - if (bad++ > 10) { - err("\nTest aborted after 10 failures\n\n"); - } - FD_CLR(c->fd, &writebits); - start_connect(c); - } - } - else { - /* have full header */ - if (!good) { - /* this is first time, extract some interesting info */ - char *p, *q; - p = strstr(c->cbuff, "Server:"); - q = servername; - if (p) { - p += 8; - while (*p > 32) - *q++ = *p++; - } - *q = 0; - } - - /* XXX: this parsing isn't even remotely HTTP compliant... - * but in the interest of speed it doesn't totally have to be, - * it just needs to be extended to handle whatever servers - * folks want to test against. -djg */ - - /* check response code */ - part = strstr(c->cbuff, "HTTP"); /* really HTTP/1.x_ */ - strncpy(respcode, (part+strlen("HTTP/1.x_")), 3); + s = strstr(c->cbuff, "\r\n\r\n"); + /* + * this next line is so that we talk to NCSA 1.5 which blatantly + * breaks the http specification + */ + if (!s) { + s = strstr(c->cbuff, "\n\n"); + l = 2; + } + + if (!s) { + /* read rest next time */ + if (space) + return; + else { + /* header is in invalid or too big - close connection */ + close(c->fd); + if (bad++ > 10) { + err("\nTest aborted after 10 failures\n\n"); + } + FD_CLR(c->fd, &writebits); + start_connect(c); + } + } + else { + /* have full header */ + if (!good) { + /* this is first time, extract some interesting info */ + char *p, *q; + p = strstr(c->cbuff, "Server:"); + q = servername; + if (p) { + p += 8; + while (*p > 32) + *q++ = *p++; + } + *q = 0; + } + + /* + * XXX: this parsing isn't even remotely HTTP compliant... but in + * the interest of speed it doesn't totally have to be, it just + * needs to be extended to handle whatever servers folks want to + * test against. -djg + */ + + /* check response code */ + part = strstr(c->cbuff, "HTTP"); /* really HTTP/1.x_ */ + strncpy(respcode, (part + strlen("HTTP/1.x_")), 3); respcode[3] = '\0'; - if (respcode[0] != '2') { - err_response++; - if (verbosity >= 2) printf ("WARNING: Response code not 2xx (%s)\n", respcode); - } + if (respcode[0] != '2') { + err_response++; + if (verbosity >= 2) + printf("WARNING: Response code not 2xx (%s)\n", respcode); + } else if (verbosity >= 3) { - printf("LOG: Response code = %s\n", respcode); - } - - c->gotheader = 1; - *s = 0; /* terminate at end of header */ - if (keepalive && - (strstr(c->cbuff, "Keep-Alive") - || strstr(c->cbuff, "keep-alive"))) { /* for benefit of MSIIS */ - char *cl; - cl = strstr(c->cbuff, "Content-Length:"); - /* handle NCSA, which sends Content-length: */ - if (!cl) - cl = strstr(c->cbuff, "Content-length:"); - if (cl) { - c->keepalive = 1; - c->length = atoi(cl + 16); - } - } - c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy; - totalbread += c->bread; - } + printf("LOG: Response code = %s\n", respcode); + } + + c->gotheader = 1; + *s = 0; /* terminate at end of header */ + if (keepalive && + (strstr(c->cbuff, "Keep-Alive") + || strstr(c->cbuff, "keep-alive"))) { /* for benefit of MSIIS */ + char *cl; + cl = strstr(c->cbuff, "Content-Length:"); + /* handle NCSA, which sends Content-length: */ + if (!cl) + cl = strstr(c->cbuff, "Content-length:"); + if (cl) { + c->keepalive = 1; + c->length = atoi(cl + 16); + } + } + c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy; + totalbread += c->bread; + } } else { - /* outside header, everything we have read is entity body */ - c->bread += r; - totalbread += r; + /* outside header, everything we have read is entity body */ + c->bread += r; + totalbread += r; } if (c->keepalive && (c->bread >= c->length)) { - /* finished a keep-alive connection */ - good++; - doneka++; - /* save out time */ - if (good == 1) { - /* first time here */ - doclen = c->bread; - } - else if (c->bread != doclen) { - bad++; - err_length++; - } - if (done < requests) { - struct data s; - gettimeofday(&c->done, 0); - s.read = c->read; - s.ctime = timedif(c->connect, c->start); - s.time = timedif(c->done, c->start); - stats[done++] = s; - } - c->keepalive = 0; - c->length = 0; - c->gotheader = 0; - c->cbx = 0; - c->read = c->bread = 0; - write_request(c); - c->start = c->connect; /* zero connect time with keep-alive */ + /* finished a keep-alive connection */ + good++; + doneka++; + /* save out time */ + if (good == 1) { + /* first time here */ + doclen = c->bread; + } + else if (c->bread != doclen) { + bad++; + err_length++; + } + if (done < requests) { + struct data s; + gettimeofday(&c->done, 0); + s.read = c->read; + s.ctime = timedif(c->connect, c->start); + s.time = timedif(c->done, c->start); + stats[done++] = s; + } + c->keepalive = 0; + c->length = 0; + c->gotheader = 0; + c->cbx = 0; + c->read = c->bread = 0; + write_request(c); + c->start = c->connect; /* zero connect time with keep-alive */ } } @@ -575,18 +744,20 @@ static void test(void) fd_set sel_read, sel_except, sel_write; int i; - printf("Benchmarking %s (be patient)...", hostname); - fflush(stdout); + if (!use_html) { + printf("Benchmarking %s (be patient)...", hostname); + fflush(stdout); + } { - /* get server information */ - struct hostent *he; - he = gethostbyname(hostname); - if (!he) - err("bad hostname"); - server.sin_family = he->h_addrtype; - server.sin_port = htons(port); - server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0]; + /* get server information */ + struct hostent *he; + he = gethostbyname(hostname); + if (!he) + err("bad hostname"); + server.sin_family = he->h_addrtype; + server.sin_port = htons(port); + server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0]; } con = malloc(concurrency * sizeof(struct connection)); @@ -600,96 +771,111 @@ static void test(void) /* setup request */ if (!posting) { sprintf(request, "GET %s HTTP/1.0\r\n" - "User-Agent: ApacheBench/%s\r\n" - "%s" - "Host: %s\r\n" - "Accept: */*\r\n" - "\r\n", - path, - VERSION, - keepalive ? "Connection: Keep-Alive\r\n" : "", - hostname); + "User-Agent: ApacheBench/%s\r\n" + "%s" "%s" "%s" + "Host: %s\r\n" + "Accept: */*\r\n" + "\r\n" "%s", + path, + VERSION, + keepalive ? "Connection: Keep-Alive\r\n" : "", + cookie, auth, hostname, hdrs); } else { sprintf(request, "POST %s HTTP/1.0\r\n" - "User-Agent: ApacheBench/%s\r\n" - "%s" - "Host: %s\r\n" - "Accept: */*\r\n" - "Content-length: %d\r\n" - "Content-type: %s\r\n" - "\r\n", - path, - VERSION, - keepalive ? "Connection: Keep-Alive\r\n" : "", - hostname, postlen, - (content_type[0]) ? content_type : "text/plain"); + "User-Agent: ApacheBench/%s\r\n" + "%s" "%s" "%s" + "Host: %s\r\n" + "Accept: */*\r\n" + "Content-length: %d\r\n" + "Content-type: %s\r\n" + "%s" + "\r\n", + path, + VERSION, + keepalive ? "Connection: Keep-Alive\r\n" : "", + cookie, auth, + hostname, postlen, + (content_type[0]) ? content_type : "text/plain", hdrs); } - if (verbosity >= 2) printf("INFO: POST header == \n---\n%s\n---\n", request); + if (verbosity >= 2) + printf("INFO: POST header == \n---\n%s\n---\n", request); reqlen = strlen(request); #ifdef CHARSET_EBCDIC ebcdic2ascii(request, request, reqlen); -#endif /*CHARSET_EBCDIC*/ +#endif /* CHARSET_EBCDIC */ /* ok - lets start */ gettimeofday(&start, 0); /* initialise lots of requests */ for (i = 0; i < concurrency; i++) - start_connect(&con[i]); + start_connect(&con[i]); while (done < requests) { - int n; - /* setup bit arrays */ - memcpy(&sel_except, &readbits, sizeof(readbits)); - memcpy(&sel_read, &readbits, sizeof(readbits)); - memcpy(&sel_write, &writebits, sizeof(readbits)); - - /* check for time limit expiry */ - gettimeofday(&now, 0); - if (tlimit && timedif(now, start) > (tlimit * 1000)) { - requests = done; /* so stats are correct */ - } - - /* Timeout of 30 seconds. */ - timeout.tv_sec = 30; - timeout.tv_usec = 0; - n = ap_select(FD_SETSIZE, &sel_read, &sel_write, &sel_except, &timeout); - if (!n) { - err("\nServer timed out\n\n"); - } - if (n < 1) - err("select"); - - for (i = 0; i < concurrency; i++) { - int s = con[i].fd; - if (FD_ISSET(s, &sel_except)) { - bad++; - err_except++; - start_connect(&con[i]); - continue; - } - if (FD_ISSET(s, &sel_read)) - read_connection(&con[i]); - if (FD_ISSET(s, &sel_write)) - write_request(&con[i]); - } + int n; + /* setup bit arrays */ + memcpy(&sel_except, &readbits, sizeof(readbits)); + memcpy(&sel_read, &readbits, sizeof(readbits)); + memcpy(&sel_write, &writebits, sizeof(readbits)); + + /* check for time limit expiry */ + gettimeofday(&now, 0); + if (tlimit && timedif(now, start) > (tlimit * 1000)) { + requests = done; /* so stats are correct */ + } + + /* Timeout of 30 seconds. */ + timeout.tv_sec = 30; + timeout.tv_usec = 0; + n = ap_select(FD_SETSIZE, &sel_read, &sel_write, &sel_except, &timeout); + if (!n) { + err("\nServer timed out\n\n"); + } + if (n < 1) + err("select"); + + for (i = 0; i < concurrency; i++) { + int s = con[i].fd; + if (FD_ISSET(s, &sel_except)) { + bad++; + err_except++; + start_connect(&con[i]); + continue; + } + if (FD_ISSET(s, &sel_read)) + read_connection(&con[i]); + if (FD_ISSET(s, &sel_write)) + write_request(&con[i]); + } } - output_results(); + if (use_html) + output_html_results(); + else + output_results(); } /* ------------------------------------------------------- */ /* display copyright information */ -static void copyright(void) +static void copyright(void) { - printf("This is ApacheBench, Version %s\n", VERSION); - printf("Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/\n"); - printf("Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/\n"); - printf("\n"); + if (!use_html) { + printf("This is ApacheBench, Version %s\n", VERSION); + printf("Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/\n"); + printf("Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/\n"); + printf("\n"); + } + else { + printf("<p>\n"); + printf(" This is ApacheBench, Version %s<br>\n", VERSION); + printf(" Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/<br>\n"); + printf(" Copyright (c) 1998-1999 The Apache Group, http://www.apache.org/<br>\n"); + printf("</p>\n<p>\n"); + } } /* display usage information */ @@ -703,6 +889,17 @@ static void usage(char *progname) fprintf(stderr, " -p postfile File containg data to POST\n"); fprintf(stderr, " -T content-type Content-type header for POSTing\n"); fprintf(stderr, " -v verbosity How much troubleshooting info to print\n"); + fprintf(stderr, " -w Print out results in HTML tables\n"); + fprintf(stderr, " -x attributes String to insert as table attributes\n"); + fprintf(stderr, " -y attributes String to insert as tr attributes\n"); + fprintf(stderr, " -z attributes String to insert as td or th attributes\n"); + fprintf(stderr, " -C attribute Add cookie, eg. 'Apache=1234. (repeatable)\n"); + fprintf(stderr, " -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: zop'\n"); + fprintf(stderr, " Inserted after all normal header lines. (repeatable)\n"); + fprintf(stderr, " -A attribute Add Basic WWW Authentication, the attributes\n"); + fprintf(stderr, " are a colon separated username and password.\n"); + fprintf(stderr, " -p attribute Add Basic Proxy Authentication, the attributes\n"); + fprintf(stderr, " are a colon separated username and password.\n"); fprintf(stderr, " -V Print version number and exit\n"); fprintf(stderr, " -k Use HTTP KeepAlive feature\n"); fprintf(stderr, " -h Display usage information (this message)\n"); @@ -719,21 +916,21 @@ static int parse_url(char *url) char *h; char *p = NULL; - if (strlen(url) > 7 && strncmp(url, "http://", 7) == 0) - url += 7; + if (strlen(url) > 7 && strncmp(url, "http://", 7) == 0) + url += 7; h = url; if ((cp = strchr(url, ':')) != NULL) { - *cp++ = '\0'; - p = cp; - url = cp; + *cp++ = '\0'; + p = cp; + url = cp; } if ((cp = strchr(url, '/')) == NULL) - return 1; + return 1; strcpy(path, cp); *cp = '\0'; strcpy(hostname, h); if (p != NULL) - port = atoi(p); + port = atoi(p); return 0; } @@ -747,21 +944,21 @@ static int open_postfile(char *pfile) struct stat postfilestat; if ((postfd = open(pfile, O_RDONLY)) == -1) { - printf("Invalid postfile name (%s)\n", pfile); - return errno; + printf("Invalid postfile name (%s)\n", pfile); + return errno; } if ((status = fstat(postfd, &postfilestat)) == -1) { - perror("Can\'t stat postfile\n"); - return status; + perror("Can\'t stat postfile\n"); + return status; } postdata = malloc(postfilestat.st_size); if (!postdata) { - printf("Can\'t alloc postfile buffer\n"); - return ENOMEM; + printf("Can\'t alloc postfile buffer\n"); + return ENOMEM; } if (read(postfd, postdata, postfilestat.st_size) != postfilestat.st_size) { - printf("error reading postfilen"); - return EIO; + printf("error reading postfilen"); + return EIO; } postlen = postfilestat.st_size; return 0; @@ -775,61 +972,125 @@ extern int optind, opterr, optopt; /* sort out command-line args and call test */ int main(int argc, char **argv) { - int c, r; + int c, r,l; + char tmp[1024]; + + /* table defaults */ + tablestring = ""; + trstring = ""; + tdstring = "bgcolor=white"; + cookie[0] = '\0'; + auth[0] = '\0'; + hdrs[0] = '\0'; optind = 1; - while ((c = getopt(argc, argv, "n:c:t:T:p:v:kVh")) > 0) { - switch (c) { - case 'n': - requests = atoi(optarg); - if (!requests) { - err("Invalid number of requests\n"); - } - break; - case 'k': - keepalive = 1; - break; - case 'c': - concurrency = atoi(optarg); - break; - case 'p': - if (0 == (r = open_postfile(optarg))) { - posting = 1; - } + while ((c = getopt(argc, argv, "n:c:t:T:p:v:kVhwx:y:z:C:H:P:A:")) > 0) { + switch (c) { + case 'n': + requests = atoi(optarg); + if (!requests) { + err("Invalid number of requests\n"); + } + break; + case 'k': + keepalive = 1; + break; + case 'c': + concurrency = atoi(optarg); + break; + case 'p': + if (0 == (r = open_postfile(optarg))) { + posting = 1; + } else if (postdata) { - exit(r); + exit(r); } - break; - case 'v': - verbosity = atoi(optarg); - break; - case 't': - tlimit = atoi(optarg); - requests = MAX_REQUESTS; /* need to size data array on something */ - break; - case 'T': - strcpy(content_type, optarg); - break; - case 'V': - copyright(); - exit(0); - break; - case 'h': - usage(argv[0]); - break; - default: - fprintf(stderr, "%s: invalid option `%c'\n", argv[0], c); - usage(argv[0]); - break; - } + break; + case 'v': + verbosity = atoi(optarg); + break; + case 't': + tlimit = atoi(optarg); + requests = MAX_REQUESTS; /* need to size data array on + * something */ + break; + case 'T': + strcpy(content_type, optarg); + break; + case 'C': + strncat(cookie, "Cookie: ", sizeof(cookie)); + strncat(cookie, optarg, sizeof(cookie)); + strncat(cookie, "\r\n", sizeof(cookie)); + break; + case 'A': + /* assume username passwd already to be in colon separated form. Ready + * to be uu-encoded. + */ + while(isspace(*optarg)) + optarg++; + l=ap_base64encode(tmp,optarg,strlen(optarg)); + tmp[l]='\0'; + + strncat(auth, "Authorization: basic ", sizeof(auth)); + strncat(auth, tmp, sizeof(auth)); + strncat(auth, "\r\n", sizeof(auth)); + break; + case 'P': + /* + * assume username passwd already to be in colon separated form. + */ + while(isspace(*optarg)) + optarg++; + l=ap_base64encode(tmp,optarg,strlen(optarg)); + tmp[l]='\0'; + + strncat(auth, "Proxy-Authorization: basic ", sizeof(auth)); + strncat(auth, tmp, sizeof(auth)); + strncat(auth, "\r\n", sizeof(auth)); + break; + case 'H': + strncat(hdrs, optarg, sizeof(hdrs)); + strncat(hdrs, "\r\n", sizeof(hdrs)); + break; + case 'V': + copyright(); + exit(0); + break; + case 'w': + use_html = 1; + break; + /* + * if any of the following three are used, turn on html output + * automatically + */ + case 'x': + use_html = 1; + tablestring = optarg; + break; + case 'y': + use_html = 1; + trstring = optarg; + break; + case 'z': + use_html = 1; + tdstring = optarg; + break; + case 'h': + usage(argv[0]); + break; + default: + fprintf(stderr, "%s: invalid option `%c'\n", argv[0], c); + usage(argv[0]); + break; + } } - if (optind != argc-1) { - fprintf(stderr, "%s: wrong number of arguments\n", argv[0]); - usage(argv[0]); + if (optind != argc - 1) { + fprintf(stderr, "%s: wrong number of arguments\n", argv[0]); + usage(argv[0]); } if (parse_url(argv[optind++])) { - fprintf(stderr, "%s: invalid URL\n", argv[0]); - usage(argv[0]); + fprintf(stderr, "%s: invalid URL\n", argv[0]); + usage(argv[0]); } copyright(); @@ -837,4 +1098,3 @@ int main(int argc, char **argv) exit(0); } - diff --git a/usr.sbin/httpd/src/support/apachectl b/usr.sbin/httpd/src/support/apachectl index a3ea6fdc695..5b176d9d1a0 100644 --- a/usr.sbin/httpd/src/support/apachectl +++ b/usr.sbin/httpd/src/support/apachectl @@ -50,7 +50,7 @@ do # check for pidfile if [ -f $PIDFILE ] ; then PID=`cat $PIDFILE` - if kill -0 $PID; then + if [ "x$PID" != "x" ] && kill -0 $PID 2>/dev/null ; then STATUS="httpd (pid $PID) running" RUNNING=1 else diff --git a/usr.sbin/httpd/src/support/apachectl.1 b/usr.sbin/httpd/src/support/apachectl.1 deleted file mode 100644 index ebda1bc256b..00000000000 --- a/usr.sbin/httpd/src/support/apachectl.1 +++ /dev/null @@ -1,133 +0,0 @@ -.TH apachectl 1 "September 1997" -.\" Copyright (c) 1997-1999 The Apache Group. 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. All advertising materials mentioning features or use of this -.\" software must display the following acknowledgment: -.\" "This product includes software developed by the Apache Group -.\" for use in the Apache HTTP server project (http://www.apache.org/)." -.\" -.\" 4. The names "Apache Server" and "Apache Group" must not be used to -.\" endorse or promote products derived from this software without -.\" prior written permission. -.\" -.\" 5. Products derived from this software may not be called "Apache" -.\" nor may "Apache" appear in their names without prior written -.\" permission of the Apache Group. -.\" -.\" 6. Redistributions of any form whatsoever must retain the following -.\" acknowledgment: -.\" "This product includes software developed by the Apache Group -.\" for use in the Apache HTTP server project (http://www.apache.org/)." -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -.\" OF THE POSSIBILITY OF SUCH DAMAGE. -.\" ==================================================================== -.\" -.\" This software consists of voluntary contributions made by many -.\" individuals on behalf of the Apache Group and was originally based -.\" on public domain software written at the National Center for -.\" Supercomputing Applications, University of Illinois, Urbana-Champaign. -.\" For more information on the Apache Group and the Apache HTTP server -.\" project, please see <http://www.apache.org/>. -.SH NAME -apachectl \- Apache HTTP server control interface -.SH SYNOPSIS -.B apachectl -\fIcommand\fP [...] -.SH DESCRIPTION -.B apachectl -is a front end to the Apache HyperText Transfer Protocol (HTTP) -server. It is designed to help the administrator control the -functioning of the Apache -.B httpd -daemon. -.PP -.B NOTE: -If your Apache installation uses non-standard paths, you will need to -edit the -.B apachectl -script to set the appropriate paths to your PID file and your -.B httpd -binary. See the comments in the script for details. -.PP -The -.B apachectl -script returns a 0 exit value on success, and >0 if an error -occurs. For more details, view the comments in the script. -.PP -Full documentation for Apache is available at -.B http://www.apache.org/ -. -.SH OPTIONS -The \fIcommand\fP can be any one or more of the following options: -.TP 12 -.BI start -Start the Apache daemon. Gives an error if it is already running. -.TP -.BI stop -Stops the Apache daemon. -.TP -.BI restart -Restarts the Apache daemon by sending it a SIGHUP. If the daemon -is not running, it is started. -This command automatically checks the configuration files via -.BI configtest -before initiating the restart to make sure Apache doesn't die. -.TP -.BI fullstatus -Displays a full status report from -.B mod_status. -For this to work, you need to have mod_status enabled on your server -and a text-based browser such as \fIlynx\fP available on your system. The -URL used to access the status report can be set by editing the -.B STATUSURL -variable in the script. -.TP -.BI status -Displays a brief status report. Similar to the fullstatus option, -except that the list of requests currently being served is omitted. -.TP -.BI graceful -Gracefully restarts the Apache daemon by sending it a SIGUSR1. If -the daemon is not running, it is started. This differs from a -normal restart in that currently open connections are not aborted. -A side effect is that old log files will not be closed immediately. -This means that if used in a log rotation script, a substantial delay may be -necessary to ensure that the old log files are closed before processing them. -This command automatically checks the configuration files via -.BI configtest -before initiating the restart to make sure Apache doesn't die. -.TP -.BI configtest -Run a configuration file syntax test. It parses the configuration -files and either reports -.B "Syntax Ok" -or detailed information about the particular syntax error. -.TP -.BI help -Displays a short help message. -.SH SEE ALSO -.BR httpd(8) -. diff --git a/usr.sbin/httpd/src/support/apxs.8 b/usr.sbin/httpd/src/support/apxs.8 index 3c4c6a53792..464766c75fe 100644 --- a/usr.sbin/httpd/src/support/apxs.8 +++ b/usr.sbin/httpd/src/support/apxs.8 @@ -6,7 +6,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 @@ -56,15 +56,24 @@ apxs \- APache eXtenSion tool .SH SYNOPSIS .B apxs .B \-g +[ +.BI \-S " name=value +] .BI \-n " modname" .B apxs .B \-q +[ +.BI \-S " name=value +] .IR query " ..." .B apxs .B \-c [ +.BI \-S " name=value +] +[ .BI \-o " dsofile" ] [ @@ -90,6 +99,25 @@ apxs \- APache eXtenSion tool .B apxs .B \-i [ +.BI \-S " name=value +] +[ +.BI \-n " modname" +] +[ +.B \-a +] +[ +.B \-A +] +.IR dsofile " ..." + +.B apxs +.B \-e +[ +.BI \-S " name=value +] +[ .BI \-n " modname" ] [ @@ -159,7 +187,7 @@ even a library archive (.a). The tool automatically recognizes these extensions and automtaically used the C source files for compilation while just using the object and archive files for the linking phase. But when using such pre-compiled objects make sure they are -compiled for position independent code (PIC) to be able to use them for a +compiled for position independend code (PIC) to be able to use them for a dynamically loaded shared object. For instance with GCC you always just have to use .BR -fpic . @@ -198,18 +226,18 @@ by guessing it from the filename. .PP Query options: .TP 12 -.B \-q -Performs a query for +.B \-q +Performs a query for .BR apxs 's knowledge about certain settings. The .I query parameters can be one or more of the following strings: .nf CC TARGET - CFLAGS SBINDIR - CFLAGS_SHLIB INCLUDEDIR - LD_SHLIB LIBEXECDIR - LDFLAGS_SHLIB SYSCONFDIR + CFLAGS SBINDIR + CFLAGS_SHLIB INCLUDEDIR + LD_SHLIB LIBEXECDIR + LDFLAGS_SHLIB SYSCONFDIR LIBS_SHLIB .fi Use this for manually determining settings. For instance use @@ -219,6 +247,11 @@ Use this for manually determining settings. For instance use inside your own Makefiles if you need manual access to Apache's C header files. .PP +Configuration options: +.TP 12 +.BI \-S " name=value" +This option changes the apxs settings described above. +.PP Template Generation options: .TP 12 .B \-g @@ -278,42 +311,51 @@ This option is directly passed through to the linker command. Use this to add your own libraries to search to the build process. .TP 12 .BI \-Wc, "compiler-flags" -This option passes +This option passes .I compiler-flags as additional flags to the compiler command. Use this to add local compiler-specific options. .TP 12 .BI \-Wl, "linker-flags" -This option passes +This option passes .I linker-flags as additional flags to the linker command. Use this to add local linker-specific options. .PP -DSO installation options: +DSO installation and configuration options: .TP 12 .B \-i This indicates the installation operation and installs one or more dynamically shared objects into the -servers +server's .I libexec directory. .TP 12 .B \-a -This additionally activates the module -by automatically adding a corresponding +This activates the module by automatically adding a corresponding .B LoadModule line to Apache's .B httpd.conf -configuration file (only if still no such entry exists). +configuration file, or by enabling it if it already exists. .TP 12 .B \-A Same as option .B \-a -but the created +but the created .B LoadModule -directive is -prefixed with a hash sign (#), i.e. the module is -just prepared for later activation but initially disabled. +directive is prefixed with a hash sign (#), i.e. the module is +just prepared for later activation but initially disabled. +.TP 12 +.B \-e +This indicates the editing operation, which can be used with the +.B \-a +and +.B \-A +options similarly to the +.B \-i +operation to edit Apache's +.B httpd.conf +configuration file without attempting to install the module. .PD .SH EXAMPLES Assume you have an Apache module named mod_foo.c available which should extend diff --git a/usr.sbin/httpd/src/support/apxs.pl b/usr.sbin/httpd/src/support/apxs.pl index f08450cdab4..c9c5ea85ef5 100644 --- a/usr.sbin/httpd/src/support/apxs.pl +++ b/usr.sbin/httpd/src/support/apxs.pl @@ -68,18 +68,18 @@ package apxs; ## Configuration ## -my $CFG_TARGET = '@TARGET@'; # substituted via Makefile.tmpl -my $CFG_CC = '@CC@'; # substituted via Makefile.tmpl -my $CFG_CFLAGS = '@CFLAGS@'; # substituted via Makefile.tmpl -my $CFG_CFLAGS_SHLIB = '@CFLAGS_SHLIB@'; # substituted via Makefile.tmpl -my $CFG_LD_SHLIB = '@LD_SHLIB@'; # substituted via Makefile.tmpl -my $CFG_LDFLAGS_SHLIB = '@LDFLAGS_SHLIB@'; # substituted via Makefile.tmpl -my $CFG_LIBS_SHLIB = '@LIBS_SHLIB@'; # substituted via Makefile.tmpl -my $CFG_PREFIX = '@prefix@'; # substituted via APACI install -my $CFG_SBINDIR = '@sbindir@'; # substituted via APACI install -my $CFG_INCLUDEDIR = '@includedir@'; # substituted via APACI install -my $CFG_LIBEXECDIR = '@libexecdir@'; # substituted via APACI install -my $CFG_SYSCONFDIR = '@sysconfdir@'; # substituted via APACI install +my $CFG_TARGET = '@TARGET@'; # substituted via Makefile.tmpl +my $CFG_CC = '@CC@'; # substituted via Makefile.tmpl +my $CFG_CFLAGS = '@CFLAGS@'; # substituted via Makefile.tmpl +my $CFG_CFLAGS_SHLIB = '@CFLAGS_SHLIB@'; # substituted via Makefile.tmpl +my $CFG_LD_SHLIB = '@LD_SHLIB@'; # substituted via Makefile.tmpl +my $CFG_LDFLAGS_SHLIB = '@LDFLAGS_MOD_SHLIB@'; # substituted via Makefile.tmpl +my $CFG_LIBS_SHLIB = '@LIBS_SHLIB@'; # substituted via Makefile.tmpl +my $CFG_PREFIX = '@prefix@'; # substituted via APACI install +my $CFG_SBINDIR = '@sbindir@'; # substituted via APACI install +my $CFG_INCLUDEDIR = '@includedir@'; # substituted via APACI install +my $CFG_LIBEXECDIR = '@libexecdir@'; # substituted via APACI install +my $CFG_SYSCONFDIR = '@sysconfdir@'; # substituted via APACI install ## ## Cleanup the above stuff @@ -91,6 +91,10 @@ $CFG_CFLAGS =~ s|\s+`.+apaci`||; ## ## Initial shared object support check ## +if (not -x "$CFG_SBINDIR/$CFG_TARGET") { + print STDERR "apxs:Error: $CFG_SBINDIR/$CFG_TARGET not found or not executable\n"; + exit(1); +} if (not grep(/mod_so/, `$CFG_SBINDIR/$CFG_TARGET -l`)) { print STDERR "apxs:Error: Sorry, no shared object support for Apache\n"; print STDERR "apxs:Error: available under your platform. Make sure\n"; @@ -113,6 +117,8 @@ my @opt_I = (); my @opt_L = (); my @opt_l = (); my @opt_W = (); +my @opt_S = (); +my $opt_e = 0; my $opt_i = 0; my $opt_a = 0; my $opt_A = 0; @@ -184,27 +190,49 @@ sub Getopts { } sub usage { - print STDERR "Usage: apxs -g -n <modname>\n"; - print STDERR " apxs -q <query> ...\n"; - print STDERR " apxs -c [-o <dsofile>] [-D <name>[=<value>]] [-I <incdir>]\n"; - print STDERR " [-L <libdir>] [-l <libname>] [-Wc,<flags>] [-Wl,<flags>]\n"; - print STDERR " <files> ...\n"; - print STDERR " apxs -i [-a] [-A] [-n <modname>] <dsofile> ...\n"; + print STDERR "Usage: apxs -g [-S <var>=<val>] -n <modname>\n"; + print STDERR " apxs -q [-S <var>=<val>] <query> ...\n"; + print STDERR " apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]\n"; + print STDERR " [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]\n"; + print STDERR " [-Wl,<flags>] <files> ...\n"; + print STDERR " apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n"; + print STDERR " apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n"; exit(1); } # option handling my $rc; -($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+iaA", @ARGV); +($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaA", @ARGV); &usage if ($rc == 0); &usage if ($#ARGV == -1 and not $opt_g); -&usage if (not $opt_q and not ($opt_g and $opt_n) and not $opt_i and not $opt_c); +&usage if (not $opt_q and not ($opt_g and $opt_n) and not $opt_i and not $opt_c and not $opt_e); # argument handling my @args = @ARGV; my $name = 'unknown'; $name = $opt_n if ($opt_n ne ''); +if (@opt_S) { + my ($opt_S); + foreach $opt_S (@opt_S) { + if ($opt_S =~ m/^([^=]+)=(.*)$/) { + my ($var) = $1; + my ($val) = $2; + my $oldval = eval "\$CFG_$var"; + + unless ($var and $oldval) { + print STDERR "apxs:Error: no config variable $var\n"; + &usage; + } + + eval "\$CFG_${var}=\"${val}\""; + } else { + print STDERR "apxs:Error: malformatted -S option\n"; + &usage; + } + } +} + ## ## Operation ## @@ -354,7 +382,11 @@ if ($opt_c) { $opt = ''; my ($opt_Wl, $opt_L, $opt_l); foreach $opt_Wl (@opt_W) { - $opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|); + if($CFG_LD_SHLIB ne "gcc") { + $opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|); + } else { + $opt .= " -W$opt_Wl"; + } } foreach $opt_L (@opt_L) { $opt .= " -L$opt_L"; @@ -370,12 +402,12 @@ if ($opt_c) { &execute_cmds(@cmds); # allow one-step compilation and installation - if ($opt_i) { + if ($opt_i or $opt_e) { @args = ( $dso_file ); } } -if ($opt_i) { +if ($opt_i or $opt_e) { ## ## SHARED OBJECT INSTALLATION ## @@ -393,8 +425,10 @@ if ($opt_i) { } my $t = $f; $t =~ s|^.+/([^/]+)$|$1|; - push(@cmds, "cp $f $CFG_LIBEXECDIR/$t"); - push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t"); + if ($opt_i) { + push(@cmds, "cp $f $CFG_LIBEXECDIR/$t"); + push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t"); + } # determine module symbolname and filename my $filename = ''; @@ -455,29 +489,28 @@ if ($opt_i) { exit(1); } - my $update = 0; my $lmd; + my $c = ''; + $c = '#' if ($opt_A); foreach $lmd (@lmd) { + my $what = $opt_A ? "preparing" : "activating"; if ($content !~ m|\n#?\s*$lmd|) { - my $c = ''; - $c = '#' if ($opt_A); $content =~ s|^(.*\n#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|sg; - $update = 1; - $lmd =~ m|LoadModule\s+(.+?)_module.*|; - my $what = $opt_A ? "preparing" : "activating"; - print STDERR "[$what module `$1' in $CFG_SYSCONFDIR/$CFG_TARGET.conf]\n"; + } else { + $content =~ s|^(.*\n)#?\s*$lmd[^\n]*\n|$1$c$lmd\n|sg; } + $lmd =~ m|LoadModule\s+(.+?)_module.*|; + print STDERR "[$what module `$1' in $CFG_SYSCONFDIR/$CFG_TARGET.conf]\n"; } my $amd; foreach $amd (@amd) { if ($content !~ m|\n#?\s*$amd|) { - my $c = ''; - $c = '#' if ($opt_A); $content =~ s|^(.*\n#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|sg; - $update = 1; + } else { + $content =~ s|^(.*\n)#?\s*$amd[^\n]*\n|$1$c$amd\n|sg; } } - if ($update) { + if (@lmd or @amd) { open(FP, ">$CFG_SYSCONFDIR/$CFG_TARGET.conf.new") || die; print FP $content; close(FP); diff --git a/usr.sbin/httpd/src/support/ca-fix.c b/usr.sbin/httpd/src/support/ca-fix.c deleted file mode 100644 index dab40933a15..00000000000 --- a/usr.sbin/httpd/src/support/ca-fix.c +++ /dev/null @@ -1,609 +0,0 @@ -/* -** ca-fix, X.509 Certificate Patch Utility / Version 0.41 -** -** Copyright (c) 1997-1998 -** Dr Stephen N. Henson <shenson@drh-consultancy.demon.co.uk> -** http://www.drh-consultancy.demon.co.uk/ -** -** Commercial and non-commercial use is permitted. -** -** Any software using this code must include the following message in its -** startup code or documentation and in any advertising material: -** "This Product includes cryptographic software written by Dr S N Henson -** (shenson@bigfoot.com)" -** -** This software is allowed to be used in the mod_ssl package -** without the above advertisment clause with permission by Dr S N Henson as -** long as it's used under build-time only and never gets installed as part -** of neither the Apache nor the mod_ssl package. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <bio.h> -#include <objects.h> -#include <asn1.h> -#include <asn1_mac.h> -#include <x509.h> -#include <err.h> -#include <crypto.h> -#include <stack.h> -#include <evp.h> -#include <pem.h> - -#if SSLEAY_VERSION_NUMBER < 0x0900 -#define OBJ_create(a,b,c) OBJ_create_and_add_object(a,b,c) -#endif - -typedef struct { - int ca; - ASN1_INTEGER *pathlen; -} BASIC_CONSTRAINTS; - -int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *, unsigned char **); -ASN1_OBJECT *__OBJ_txt2obj(char *); - -int i2d_BASIC_CONSTRAINTS(BASIC_CONSTRAINTS *a, unsigned char **pp) -{ - M_ASN1_I2D_vars(a); - if (a->ca) - M_ASN1_I2D_len(a->ca, i2d_ASN1_BOOLEAN); - M_ASN1_I2D_len(a->pathlen, i2d_ASN1_INTEGER); - - M_ASN1_I2D_seq_total(); - if (a->ca) - M_ASN1_I2D_put(a->ca, i2d_ASN1_BOOLEAN); - M_ASN1_I2D_put(a->pathlen, i2d_ASN1_INTEGER); - M_ASN1_I2D_finish(); -} - -typedef struct { - char *name; - char *value; - char flag; -#define CERT_CRIT 0x1 -#define CERT_RAW 0x2 -#define CERT_RAW_FILE 0x4 -} EXT_ADD; - -STACK *exts; -STACK *extusage; - -void add_ext(char *, char *, char); - -unsigned char extbuf[10240]; - -int main(int argc, char **argv) -{ - char *infile = NULL, *outfile = NULL, *keyname = NULL; - BIO *in = NULL, *out = NULL, *inkey = NULL, *bio_err = NULL; - char **args; - int i; - int badarg = 0; - int bconsadd = 0, bconsdel = 0; - int nset = 0, nsclr = 0; - unsigned char ntype = 0, noout = 0, exthex = 0, extparse = 0; - unsigned char bscrit = 0, nscrit = 0, keycrit = 0, print = 0, sign = 1; - unsigned char setkey = 0; - X509 *cert; - EVP_PKEY *pkey = NULL; - BASIC_CONSTRAINTS bcons = {0, NULL}; - EVP_MD *dgst; - - if (bio_err == NULL) - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); - - ERR_load_crypto_strings(); - args = argv + 1; - - while (*args) { - if (*args[0] == '-') { - if (!strcmp(*args, "-caset")) { - bconsadd = 1; - bcons.ca = 0xff; - } - else if (!strcmp(*args, "-caunset")) { - if (bcons.ca) - badarg = 1; - else - bconsadd = 1; - } - else if (!strcmp(*args, "-caclr")) - bconsdel = 1; - else if (!strcmp(*args, "-setkey")) - setkey = 1; - else if (!strcmp(*args, "-print")) - print = 1; - else if (!strcmp(*args, "-noout")) - noout = 1; - else if (!strcmp(*args, "-nosign")) - sign = 0; - else if (!strcmp(*args, "-exthex")) - exthex = 1; - else if (!strcmp(*args, "-extparse")) - extparse = 1; - else if (!strcmp(*args, "-nsclr")) - nsclr = 1; - else if (!strcmp(*args, "-nobscrit")) - bscrit = 0; - else if (!strcmp(*args, "-bscrit")) - bscrit = 1; - else if (!strcmp(*args, "-nscrit")) - nscrit = 1; - else if (!strcmp(*args, "-extcrit")) - keycrit = 1; - else if (!strcmp(*args, "-pathlen")) { - if (args[1]) { - args++; - bconsadd = 1; - bcons.ca = 0xff; - bcons.pathlen = ASN1_INTEGER_new(); - ASN1_INTEGER_set(bcons.pathlen, - strtol(*args, NULL, 0)); - } - else - badarg = 1; - } - else if (!strcmp(*args, "-nscertype")) { - if (args[1]) { - args++; - nset = 1; - ntype = (unsigned char) strtol(*args, NULL, 0); - } - else - badarg = 1; - } - else if (!strcmp(*args, "-rawfile")) { - if (args[1] && args[2]) { - add_ext(args[1], args[2], CERT_RAW_FILE); - args += 2; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-Crawfile")) { - if (args[1] && args[2]) { - add_ext(args[1], args[2], CERT_RAW_FILE | CERT_CRIT); - args += 2; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-rawext")) { - if (args[1] && args[2]) { - add_ext(args[1], args[2], CERT_RAW); - args += 2; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-Crawext")) { - if (args[1] && args[2]) { - add_ext(args[1], args[2], CERT_RAW | CERT_CRIT); - args += 2; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-ext")) { - if (args[1] && args[2]) { - add_ext(args[1], args[2], 0); - args += 2; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-Cext")) { - if (args[1] && args[2]) { - add_ext(args[1], args[2], CERT_CRIT); - args += 2; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-extusage")) { - if (args[1]) { - ASN1_OBJECT *obj; - if (!extusage) - extusage = sk_new(NULL); - obj = __OBJ_txt2obj(args[1]); - if (!obj) { - BIO_printf(bio_err, "Error parsing extended usage object\n"); - ERR_print_errors(bio_err); - exit(1); - } - else - sk_push(extusage, (char *) obj); - args++; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-delext")) { - if (args[1]) { - add_ext(args[1], NULL, 0); - args++; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-inkey")) { - if (args[1]) { - args++; - keyname = *args; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-in")) { - if (args[1]) { - args++; - infile = *args; - } - else - badarg = 1; - } - else if (!strcmp(*args, "-out")) { - if (args[1]) { - args++; - outfile = *args; - } - else - badarg = 1; - } - else - badarg = 1; - } - else - badarg = 1; - args++; - } - - if (badarg || (bconsadd && bconsdel)) { - BIO_printf(bio_err, "ca-fix version 0.41, certificate patcher\n"); - BIO_printf(bio_err, "Written by Dr. S N Henson (shenson@bigfoot.com)\n"); - BIO_printf(bio_err, "ca-fix [args]\n"); - BIO_printf(bio_err, "-in cert.pem input certificate.\n"); - BIO_printf(bio_err, "-out cert.pem output certificate.\n"); - BIO_printf(bio_err, "-noout don't output certificate\n"); - BIO_printf(bio_err, "-nosign don't sign certificate\n"); - BIO_printf(bio_err, "-print print certificate\n"); - BIO_printf(bio_err, "-extparse ASN1 parse extensions\n"); - BIO_printf(bio_err, "-exthex hex dump extensions\n"); - BIO_printf(bio_err, "-caset set cA flag, add basic constraints\n"); - BIO_printf(bio_err, "-caunset don't set cA flag, add basic constraints\n"); - BIO_printf(bio_err, "-caclr delete basic constraints\n"); - BIO_printf(bio_err, "-pathlen n set path length to \'n\'\n"); - BIO_printf(bio_err, "-bscrit make basic constraints critical\n"); - BIO_printf(bio_err, "-nscrit make nscertype critical (not recommended)\n"); - BIO_printf(bio_err, "-nscertype num set nscertype to num\n"); - BIO_printf(bio_err, "-nsclr delete nscertype\n"); - BIO_printf(bio_err, "-inkey pkey.pem private key of signer\n"); - BIO_printf(bio_err, "Expert options:\n"); - BIO_printf(bio_err, "-setkey changed certificate public key to match signer\n"); - BIO_printf(bio_err, "-delext ext delete extension (can use OID)\n"); - BIO_printf(bio_err, "-ext genopt val add several extensions\n"); - BIO_printf(bio_err, "-Cext genopt val add several critical extensions\n"); - BIO_printf(bio_err, "genopt can be: keyUsage, nsCertType, nsBaseUrl, nsRevocationUrl,\n"); - BIO_printf(bio_err, " nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,\n"); - BIO_printf(bio_err, " nsSslServerName, nsComment\n"); - BIO_printf(bio_err, "-rawext opt HEX add raw extension (can use OID)\n"); - BIO_printf(bio_err, "-Crawext opt HEX add critical raw extension (can use OID)\n"); - BIO_printf(bio_err, "-Crawfile opt fn add raw extension from file (can use OID)\n"); - BIO_printf(bio_err, "-rawfile opt fn add critical raw extension from file (can use OID)\n"); - BIO_printf(bio_err, "-extusage OID add extended key usage extension\n"); - BIO_printf(bio_err, "-extcrit make extended key usage extension critical\n"); - exit(1); - } - - SSLeay_add_all_algorithms(); - X509v3_add_netscape_extensions(); - X509v3_add_standard_extensions(); - - in = BIO_new(BIO_s_file()); - out = BIO_new(BIO_s_file()); - - if (!infile) - BIO_set_fp(in, stdin, BIO_NOCLOSE); - else { - if (!keyname) - keyname = infile; - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - exit(1); - } - } - - if (keyname) { - inkey = BIO_new(BIO_s_file()); - if (BIO_read_filename(inkey, keyname) <= 0) { - perror(keyname); - exit(1); - } - } - - if (!outfile) - BIO_set_fp(out, stdout, BIO_NOCLOSE); - else { - if (BIO_write_filename(out, outfile) <= 0) { - perror(outfile); - exit(1); - } - } - - cert = PEM_read_bio_X509(in, NULL, NULL); - if (!cert) { - ERR_print_errors(bio_err); - exit(1); - } - - if (sign || setkey) { - pkey = PEM_read_bio_PrivateKey(inkey ? inkey : in, NULL, NULL); - if (!pkey) { - BIO_printf(bio_err, "Error loading private key\n"); - ERR_print_errors(bio_err); - exit(1); - } - } - - /* OK we've got the certificate: now fix it up */ - - /* Make it a V3 certificate */ - X509_set_version(cert, 2); - - if (setkey) - X509_set_pubkey(cert, pkey); - - if (bconsadd || bconsdel) { - int index; - index = X509_get_ext_by_NID(cert, NID_basic_constraints, -1); - if (index >= 0) - X509_delete_ext(cert, index); - } - if (nset || nsclr) { - int index; - index = X509_get_ext_by_NID(cert, NID_netscape_cert_type, -1); - if (index >= 0) - X509_delete_ext(cert, index); - } - - if (bconsadd) { - ASN1_OCTET_STRING *bcons_ext; - X509_EXTENSION *x; - unsigned char *bcons_der, *p; - int bcons_len; - - /* generate encoding of extension */ - bcons_len = i2d_BASIC_CONSTRAINTS(&bcons, NULL); - bcons_der = malloc(bcons_len); - p = bcons_der; - i2d_BASIC_CONSTRAINTS(&bcons, &p); - - bcons_ext = ASN1_OCTET_STRING_new(); - ASN1_OCTET_STRING_set(bcons_ext, bcons_der, bcons_len); - free(bcons_der); - x = X509_EXTENSION_create_by_NID(NULL, NID_basic_constraints, bscrit, - bcons_ext); - ASN1_OCTET_STRING_free(bcons_ext); - if (!x) { - BIO_printf(bio_err, "Error creating extension\n"); - ERR_print_errors(bio_err); - exit(1); - } - X509_add_ext(cert, x, -1); - X509_EXTENSION_free(x); - } - - if (nset) { - X509_EXTENSION *x; - ASN1_OCTET_STRING *str; - int data_type; - str = NULL; - data_type = X509v3_data_type_by_NID(NID_netscape_cert_type); - X509v3_pack_string(&str, data_type, &ntype, 1); - x = X509_EXTENSION_create_by_NID(NULL, NID_netscape_cert_type, - nscrit, str); - X509_add_ext(cert, x, -1); - X509_EXTENSION_free(x); - /*ASN1_OCTET_STRING_free(str); */ - } - /* Handle the generic extensions */ - if (exts) { - while (sk_num(exts)) { - EXT_ADD *tmpext; - int ext_nid, index; - char *ext_str; - unsigned char ext_bit; - ASN1_OCTET_STRING *str; - X509_EXTENSION *x; - ASN1_OBJECT *extobj; - tmpext = (EXT_ADD *) sk_pop(exts); - extobj = __OBJ_txt2obj(tmpext->name); - if (!extobj) { - fprintf(stderr, "Invalid object %s\n", tmpext->name); - ERR_print_errors(bio_err); - exit(1); - } - /* Delete extension if already present */ - index = X509_get_ext_by_OBJ(cert, extobj, -1); - if (index >= 0) - X509_delete_ext(cert, index); - if (!tmpext->value) - continue; - ext_nid = OBJ_obj2nid(extobj); - if (tmpext->flag & CERT_RAW) { - /* Covert hex extension into an OCTET STRING */ - unsigned char *rawext, *p, *q, tmphex[3]; - long rawlen; - rawlen = strlen(tmpext->value); - if (rawlen & 1) { - fprintf(stderr, "Invalid raw extension length\n"); - exit(1); - } - for (p = (unsigned char *)tmpext->value; *p; p++) - if (!isxdigit(*p)) { - fprintf(stderr, "Extension %s invalid hex digit %c\n", - tmpext->value, *p); - exit(1); - } - rawlen >>= 1; - rawext = Malloc(rawlen); - tmphex[2] = 0; - for (p = (unsigned char *)tmpext->value, q = rawext; *p; p += 2, q++) { - tmphex[0] = p[0]; - tmphex[1] = p[1]; - *q = (unsigned char)strtol((const char *)tmphex, NULL, 16); - } - str = ASN1_OCTET_STRING_new(); - ASN1_OCTET_STRING_set(str, rawext, rawlen); - Free(rawext); - } - else if (tmpext->flag & CERT_RAW_FILE) { - BIO *tmpin; - int extlen; - if (!(tmpin = BIO_new_file(tmpext->value, "rb"))) { - BIO_printf(bio_err, "Error opening file %s\n", tmpext->value); - ERR_print_errors(bio_err); - } - extlen = BIO_read(tmpin, (char *)extbuf, sizeof(extbuf)); - str = ASN1_STRING_new(); - ASN1_OCTET_STRING_set(str, extbuf, extlen); - } - else { - /* Get extension type */ - switch (ext_nid) { - - case NID_key_usage: - case NID_netscape_cert_type: - - ext_bit = (unsigned char) strtol(tmpext->value, NULL, 0); - ext_str = NULL; - - break; - - case NID_netscape_base_url: - case NID_netscape_revocation_url: - case NID_netscape_ca_revocation_url: - case NID_netscape_renewal_url: - case NID_netscape_ca_policy_url: - case NID_netscape_ssl_server_name: - case NID_netscape_comment: - - ext_str = tmpext->value; - - break; - - default: - - fprintf(stderr, "Unsuported extension %s\n", tmpext->name); - exit(1); - break; - } - - if (ext_str) - str = X509v3_pack_string(NULL, V_ASN1_IA5STRING, - (unsigned char *)tmpext->value, - strlen(tmpext->value)); - else - str = X509v3_pack_string(NULL, V_ASN1_BIT_STRING, - &ext_bit, 1); - } - x = X509_EXTENSION_create_by_NID(NULL, ext_nid, - tmpext->flag & CERT_CRIT, str); - X509_add_ext(cert, x, -1); - X509_EXTENSION_free(x); - } - } - - /* Handle extended key usage */ - if (extusage) { - int extlen; - unsigned char *extder, *p; - ASN1_OCTET_STRING *extkey; - X509_EXTENSION *x; - ASN1_OBJECT *extobj; - - - extobj = __OBJ_txt2obj("2.5.29.37"); - /* generate encoding of extension */ - extlen = i2d_ASN1_SET(extusage, NULL, i2d_ASN1_OBJECT, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); - extder = malloc(extlen); - p = extder; - i2d_ASN1_SET(extusage, &p, i2d_ASN1_OBJECT, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); - extkey = ASN1_OCTET_STRING_new(); - ASN1_OCTET_STRING_set(extkey, extder, extlen); - free(extder); - x = X509_EXTENSION_create_by_OBJ(NULL, extobj, keycrit, - extkey); - if (!x) { - BIO_printf(bio_err, "Error creating extension\n"); - ERR_print_errors(bio_err); - exit(1); - } - X509_add_ext(cert, x, -1); - X509_EXTENSION_free(x); - sk_pop_free(extusage, ASN1_OBJECT_free); - ASN1_OBJECT_free(extobj); - } - - - /* OK we've modified the certificate so it will have to be re-signed */ - dgst = EVP_get_digestbyobj(cert->sig_alg->algorithm); - if (sign) - X509_sign(cert, pkey, dgst); - if (print) - X509_print(out, cert); - if (extparse || exthex) { - BIO_printf(out, "X509 V3 Extensions.\n"); - for (i = 0; i < X509_get_ext_count(cert); i++) { - X509_EXTENSION *tmpext; - ASN1_OCTET_STRING *octval; - tmpext = X509_get_ext(cert, i); - octval = X509_EXTENSION_get_data(tmpext); - i2a_ASN1_OBJECT(out, X509_EXTENSION_get_object(tmpext)); - BIO_printf(out, ":\n"); - if (exthex) { - int j; - for (j = 0; j < octval->length; j++) - BIO_printf(out, "%02X", octval->data[j]); - BIO_printf(out, "\n"); - } - if (extparse) - ASN1_parse(out, octval->data, octval->length, 0); - } - } - if (!noout) - PEM_write_bio_X509(out, cert); - - return (0); - -} - -void add_ext(char *name, char *val, char flag) -{ - EXT_ADD *tmpext; - if (!exts) - exts = sk_new(NULL); - tmpext = (EXT_ADD *) Malloc(sizeof(EXT_ADD)); - tmpext->name = name; - tmpext->value = val; - tmpext->flag = flag; - sk_push(exts, (char *) tmpext); -} - -ASN1_OBJECT *__OBJ_txt2obj(char *name) -{ - int obj_nid; - ASN1_OBJECT *obj; - obj_nid = OBJ_sn2nid(name); - if (obj_nid != NID_undef) - return OBJ_nid2obj(obj_nid); - obj_nid = OBJ_create(name, name, name); - if (obj_nid <= 0) - return NULL; - obj = OBJ_nid2obj(obj_nid); - obj->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_DATA; - return obj; -} - diff --git a/usr.sbin/httpd/src/support/dbmmanage.1 b/usr.sbin/httpd/src/support/dbmmanage.1 index 67e5b60dfc4..06380ff0f59 100644 --- a/usr.sbin/httpd/src/support/dbmmanage.1 +++ b/usr.sbin/httpd/src/support/dbmmanage.1 @@ -6,7 +6,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 @@ -71,22 +71,23 @@ usernames and password for basic authentication of HTTP users. Resources available from the .B httpd Apache web server can be restricted to just the users listed -in the files created by +in the files created by .B dbmmanage. This program can only be used when the usernames are stored in a DBM file. To use a -flat-file database see +flat-file database see \fBhtpasswd\fP. .PP This manual page only lists the command line arguments. For details of -the directives necessary to configure user authentication in -.B httpd +the directives necessary to configure user authentication in +.B httpd see the Apache manual, which is part of the Apache distribution or can be found at http://www.apache.org/. .SH OPTIONS .IP \fB\fIfilename\fP -The filename of the DBM format file. Usually without the extension .pag or .dir. +The filename of the DBM format file. Usually without the +extension .db, .pag, or .dir. .IP \fB\fIcommand\fP This selects the operation to perform: .TP 12 @@ -99,7 +100,7 @@ Asks for a password and then adds an entry for \fIusername\fP to \fIfilename\fP . .TP 12 .B check -Asks for a password and then checks if +Asks for a password and then checks if \fIusername\fP is in \fIfilename\fP and if it's password matches the specified one. .TP 12 @@ -119,6 +120,52 @@ Just displays the complete contents of the DBM file. .IP \fB\fIusername\fP The user for which the update operation is performed. .PD +.SH BUGS +.PP +One should be aware that there are a number of different DBM file +formats in existance, and with all likelihood, libraries for more than +one format may exist on your system. The three primary examples are +NDBM, the GNU project's GDBM, and Berkeley DB 2. Unfortunately, all +these libraries use different file formats, and you must make sure +that the file format used by +.I filename +is the same format that +.B dbmmanage +expects to see. +.B dbmmanage +currently has no way of determining what type of DBM file it is +looking at. If used against the wrong format, +.dbmmanage +will simply return nothing, or may create a different DBM file with a +different name, or at worst, it may corrupt the DBM file if you were +attempting to write to it. +.PP +.B dbmmanage +has a list of DBM format preferences, defined by the +.B @AnyDBM::ISA +array near the beginning of the program. Since we prefer the Berkeley +DB 2 file format, the order in which +.B dbmmanage +will look for system libraries is Berkeley DB 2, then NDBM, and then +GDBM. The first library found will be the library +.B dbmmanage +will attempt to use for all DBM file transactions. This ordering is +slightly different than the standard +.B @AnyDBM::ISA +ordering in perl, as well as the ordering used by the simple dbmopen() +call in Perl, so if you use any other utilities to manage your DBM +files, they must also follow this preference ordering. Similar care +must be taken if using programs in other languages, like C, to +access these files. +.PP +Apache's +.B mod_auth_db.c +module corresponds to Berkeley DB 2 library, while +.B mod_auth_dbm.c +corresponds to the NDBM library. Also, one can usually use the +.B file +program supplied with most Unix systems to see what format a DBM file is in. +.PD .SH SEE ALSO .BR httpd(8) . diff --git a/usr.sbin/httpd/src/support/htdigest.1 b/usr.sbin/httpd/src/support/htdigest.1 index 2ab3aa5450d..c719e456ce9 100644 --- a/usr.sbin/httpd/src/support/htdigest.1 +++ b/usr.sbin/httpd/src/support/htdigest.1 @@ -6,7 +6,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 @@ -55,10 +55,10 @@ .SH NAME htdigest \- Create and update user authentication files .SH SYNOPSIS -.B htdigest +.B htdigest [ .B \-c -] +] .I passwdfile .I realm .I username @@ -69,29 +69,29 @@ usernames, realm and password for digest authentication of HTTP users. Resources available from the .B httpd Apache web server can be restricted to just the users listed -in the files created by +in the files created by .B htdigest. .PP This manual page only lists the command line arguments. For details of -the directives necessary to configure digest authentication in -.B httpd +the directives necessary to configure digest authentication in +.B httpd see the Apache manual, which is part of the Apache distribution or can be found at http://www.apache.org/. .SH OPTIONS -.IP \-c +.IP \-c Create the \fIpasswdfile\fP. If \fIpasswdfile\fP already exists, it -is deleted first. +is deleted first. .IP \fB\fIpasswdfile\fP Name of the file to contain the username, realm and password. If \-c is given, this file is created if it does not already exist, -or deleted and recreated if it does exist. +or deleted and recreated if it does exist. .IP \fB\fIrealm\fP -The realm name to which the user name belongs to. +The realm name to which the user name belongs to. .IP \fB\fIusername\fP The user name to create or update in \fBpasswdfile\fP. If \fIusername\fP does not exist is this file, an entry is added. If it does exist, the password is changed. .SH SEE ALSO -.BR httpd(8) +.BR httpd(8) . diff --git a/usr.sbin/httpd/src/support/htdigest.c b/usr.sbin/httpd/src/support/htdigest.c index 69c8e2d2c96..d1fc41800fd 100644 --- a/usr.sbin/httpd/src/support/htdigest.c +++ b/usr.sbin/httpd/src/support/htdigest.c @@ -1,3 +1,59 @@ +/* ==================================================================== + * Copyright (c) 1995-1999 The Apache Group. 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. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * 4. The names "Apache Server" and "Apache Group" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Group and was originally based + * on public domain software written at the National Center for + * Supercomputing Applications, University of Illinois, Urbana-Champaign. + * For more information on the Apache Group and the Apache HTTP server + * project, please see <http://www.apache.org/>. + * + */ /****************************************************************************** ****************************************************************************** * NOTE! This program is not safe as a setuid executable! Do not make it @@ -12,31 +68,31 @@ #include "ap_config.h" #include <sys/types.h> -#ifdef MPE +#include "ap.h" +#include "ap_md5.h" +#if defined(MPE) || defined(QNX) || defined(WIN32) || defined(__TANDEM) #include <signal.h> #else #include <sys/signal.h> #endif -/* This is probably the easiest way to do it */ -#include "../main/md5c.c" +#ifdef WIN32 +#include <conio.h> +#define unlink _unlink +#endif +#ifdef CHARSET_EBCDIC +#define LF '\n' +#define CR '\r' +#else #define LF 10 #define CR 13 +#endif /* CHARSET_EBCDIC */ #define MAX_STRING_LEN 256 char *tn; -static char *strd(char *s) -{ - char *d; - - d = (char *) malloc(strlen(s) + 1); - strcpy(d, s); - return (d); -} - static void getword(char *word, char *line, char stop) { int x = 0, y; @@ -86,15 +142,23 @@ static void add_password(char *user, char *realm, FILE *f) AP_MD5_CTX context; unsigned char digest[16]; char string[MAX_STRING_LEN]; + char pwin[MAX_STRING_LEN]; + char pwv[MAX_STRING_LEN]; unsigned int i; - pw = strd((char *) getpass("New password:")); - if (strcmp(pw, (char *) getpass("Re-type new password:"))) { + if (ap_getpass("New password: ", pwin, sizeof(pwin)) != 0) { + fprintf(stderr, "password too long"); + exit(5); + } + ap_getpass("Re-type new password: ", pwv, sizeof(pwv)); + if (strcmp(pwin, pwv) != 0) { fprintf(stderr, "They don't match, sorry.\n"); - if (tn) + if (tn) { unlink(tn); + } exit(1); } + pw = pwin; fprintf(f, "%s:%s:", user, realm); /* Do MD5 stuff */ @@ -138,7 +202,7 @@ int main(int argc, char *argv[]) int found; tn = NULL; - signal(SIGINT, (void (*)()) interrupted); + signal(SIGINT, (void (*)(int)) interrupted); if (argc == 5) { if (strcmp(argv[1], "-c")) usage(); @@ -203,5 +267,5 @@ int main(int argc, char *argv[]) #endif system(command); unlink(tn); - exit(0); + return 0; } diff --git a/usr.sbin/httpd/src/support/htpasswd.1 b/usr.sbin/httpd/src/support/htpasswd.1 index c2bf8cf8ab3..1687cde41c2 100644 --- a/usr.sbin/httpd/src/support/htpasswd.1 +++ b/usr.sbin/httpd/src/support/htpasswd.1 @@ -6,7 +6,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 @@ -55,44 +55,159 @@ .SH NAME htpasswd \- Create and update user authentication files .SH SYNOPSIS +.B htpasswd +[ +.B \-c +] +[ +.B \-m +] +.I passwdfile +.I username +.br .B htpasswd +.B \-b [ .B \-c -] +] +[ +.B \-m +.B \-d +.B \-p +.B \-s +] .I passwdfile .I username +.I password .SH DESCRIPTION .B htpasswd is used to create and update the flat-files used to store usernames and password for basic authentication of HTTP users. +If +.B htpasswd +cannot access a file, such as not being able to write to the output +file or not being able to read the file in order to update it, +it returns an error status and makes no changes. +.PP Resources available from the .B httpd Apache web server can be restricted to just the users listed -in the files created by +in the files created by .B htpasswd. This program can only be used when the usernames are stored in a flat-file. To use a -DBM database see +DBM database see \fBdbmmanage\fP. .PP +.B htpasswd +encrypts passwords using either a version of MD5 modified for Apache, +or the system's \fIcrypt()\fP routine. Files managed by +.B htpasswd +may contain both types of passwords; some user records may have +MD5-encrypted passwords while others in the same file may have passwords +encrypted with \fIcrypt()\fP. +.PP This manual page only lists the command line arguments. For details of -the directives necessary to configure user authentication in -.B httpd +the directives necessary to configure user authentication in +.B httpd see the Apache manual, which is part of the Apache distribution or can be -found at http://www.apache.org/. +found at <URL:http://www.apache.org/>. .SH OPTIONS -.IP \-c +.IP \-b +Use batch mode; \fIi.e.\fP, get the password from the command line +rather than prompting for it. \fBThis option should be used with +extreme care, since the password is clearly visible on the command +line.\fP +.IP \-c Create the \fIpasswdfile\fP. If \fIpasswdfile\fP already exists, it -is deleted first. +is rewritten and truncated. +.IP \-m +Use MD5 encryption for passwords. On Windows and TPF, this is the default. +.IP \-d +Use crypt() encryption for passwords. The default on all platforms but +Windows and TPF. Though possibly supported by +.B htpasswd +onm all platforms, it is not supported by the +.B httpd +server on Windows and TPF. +.IP \-s +Use SHA encryption for passwords. Faciliates migration from/to Netscape +servers using the LDAP Directory Interchange Format (ldif). +.IP \-p +Use plaintext passwords. Though +.B htpasswd +will support creation on all platofrms, the +.B httpd +deamon will only accept plain text passwords on Windows and TPF. .IP \fB\fIpasswdfile\fP Name of the file to contain the user name and password. If \-c is given, this file is created if it does not already exist, -or deleted and recreated if it does exist. +or rewritten and truncated if it does exist. .IP \fB\fIusername\fP The username to create or update in \fBpasswdfile\fP. If -\fIusername\fP does not exist is this file, an entry is added. If it +\fIusername\fP does not exist in this file, an entry is added. If it does exist, the password is changed. +.IP \fB\fIpassword\fP +The plaintext password to be encrypted and stored in the file. Only used +with the \fI-b\fP flag. +.SH EXIT STATUS +.B htpasswd +returns a zero status ("true") if the username and password have +been successfully added or updated in the \fIpasswdfile\fP. +.B htpasswd +returns 1 if it encounters some problem accessing files, 2 if there +was a syntax problem with the command line, 3 if the password was +entered interactively and the verification entry didn't match, 4 if +its operation was interrupted, 5 if a value is too long (username, +filename, password, or final computed record), and 6 if the username +contains illegal characters (see the \fBRESTRICTIONS\fP section). +.SH EXAMPLES +\fBhtpasswd /usr/local/etc/apache/.htpasswd-users jsmith\fP +.IP +Adds or modifies the password for user \fIjsmith\fP. +The user is prompted for the password. If executed +on a Windows system, the password will be encrypted using the +modified Apache MD5 algorithm; otherwise, the system's +\fIcrypt()\fP routine will be used. If the file does not +exist, +.B htpasswd +will do nothing except return an error. +.LP +\fBhtpasswd -c /home/doe/public_html/.htpasswd jane\fP +.IP +Creates a new file and stores a record in it for user \fIjane\fP. +The user is prompted for the password. +If the file exists and cannot be read, or cannot be written, +it is not altered and +.B htpasswd +will display a message and return an error status. +.LP +\fBhtpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve\fP +.IP +Encrypts the password from the command line (\fIPwd4Steve\fP) using +the MD5 algorithm, and stores it in the specified file. +.LP +.SH SECURITY CONSIDERATIONS +Web password files such as those managed by +.B htpasswd +should \fBnot\fP be within the Web server's URI space -- that is, +they should not be fetchable with a browser. +.PP +The use of the \fI-b\fP option is discouraged, since when it is +used the unencrypted password appears on the command line. +.SH RESTRICTIONS +On the Windows and MPE platforms, passwords encrypted with +.B htpasswd +are limited to no more than 255 characters in length. Longer +passwords will be truncated to 255 characters. +.PP +The MD5 algorithm used by +.B htpasswd +is specific to the Apache software; passwords encrypted using it will not be +usable with other Web servers. +.PP +Usernames are limited to 255 bytes and may not include the character ':'. .SH SEE ALSO .BR httpd(8) -. +and the scripts in support/SHA1 which come with the distribution. diff --git a/usr.sbin/httpd/src/support/htpasswd.c b/usr.sbin/httpd/src/support/htpasswd.c index c4a0e7e2ba0..21a24e0c0a3 100644 --- a/usr.sbin/httpd/src/support/htpasswd.c +++ b/usr.sbin/httpd/src/support/htpasswd.c @@ -1,3 +1,60 @@ +/* ==================================================================== + * Copyright (c) 1995-1999 The Apache Group. 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. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * 4. The names "Apache Server" and "Apache Group" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP 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, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Group and was originally based + * on public domain software written at the National Center for + * Supercomputing Applications, University of Illinois, Urbana-Champaign. + * For more information on the Apache Group and the Apache HTTP server + * project, please see <http://www.apache.org/>. + * + */ + /****************************************************************************** ****************************************************************************** * NOTE! This program is not safe as a setuid executable! Do not make it @@ -5,14 +62,35 @@ ****************************************************************************** *****************************************************************************/ /* - * htpasswd.c: simple program for manipulating password file for NCSA httpd + * htpasswd.c: simple program for manipulating password file for + * the Apache HTTP server * - * Rob McCool + * Originally by Rob McCool + * + * Exit values: + * 0: Success + * 1: Failure; file access/permission problem + * 2: Failure; command line syntax problem (usage message issued) + * 3: Failure; password verification failure + * 4: Failure; operation interrupted (such as with CTRL/C) + * 5: Failure; buffer would overflow (username, filename, or computed + * record too long) + * 6: Failure; username contains illegal or reserved characters */ #include "ap_config.h" #include <sys/types.h> #include <signal.h> +#include <errno.h> +#include "ap.h" +#include "ap_md5.h" +#include "ap_sha1.h" + +#ifdef WIN32 +#include <conio.h> +#include "../os/win32/getopt.h" +#define unlink _unlink +#endif #ifndef CHARSET_EBCDIC #define LF 10 @@ -23,33 +101,28 @@ #endif /*CHARSET_EBCDIC*/ #define MAX_STRING_LEN 256 +#define ALG_PLAIN 0 +#define ALG_CRYPT 1 +#define ALG_APMD5 2 +#define ALG_APSHA 3 + +#define ERR_FILEPERM 1 +#define ERR_SYNTAX 2 +#define ERR_PWMISMATCH 3 +#define ERR_INTERRUPTED 4 +#define ERR_OVERFLOW 5 +#define ERR_BADUSER 6 -char *tn; - -static char *strd(char *s) -{ - char *d; - - d = (char *) malloc(strlen(s) + 1); - strcpy(d, s); - return (d); -} - -static void getword(char *word, char *line, char stop) -{ - int x = 0, y; - - for (x = 0; ((line[x]) && (line[x] != stop)); x++) - word[x] = line[x]; - - word[x] = '\0'; - if (line[x]) - ++x; - y = 0; - - while ((line[y++] = line[x++])); -} +/* + * This needs to be declared statically so the signal handler can + * access it. + */ +static char *tempfilename; +/* + * Get a line of input from the user, not including any terminating + * newline. + */ static int getline(char *s, int n, FILE *f) { register int i = 0; @@ -57,8 +130,9 @@ static int getline(char *s, int n, FILE *f) while (1) { s[i] = (char) fgetc(f); - if (s[i] == CR) + if (s[i] == CR) { s[i] = fgetc(f); + } if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1))) { s[i] = '\0'; @@ -72,157 +146,432 @@ static void putline(FILE *f, char *l) { int x; - for (x = 0; l[x]; x++) + for (x = 0; l[x]; x++) { fputc(l[x], f); + } fputc('\n', f); } +/* + * Make a password record from the given information. A zero return + * indicates success; failure means that the output buffer contains an + * error message instead. + */ +static int mkrecord(char *user, char *record, size_t rlen, char *passwd, + int alg) +{ + char *pw; + char cpw[120]; + char pwin[MAX_STRING_LEN]; + char pwv[MAX_STRING_LEN]; + char salt[9]; + + if (passwd != NULL) { + pw = passwd; + } + else { + if (ap_getpass("New password: ", pwin, sizeof(pwin)) != 0) { + ap_snprintf(record, (rlen - 1), "password too long (>%d)", + sizeof(pwin) - 1); + return ERR_OVERFLOW; + } + ap_getpass("Re-type new password: ", pwv, sizeof(pwv)); + if (strcmp(pwin, pwv) != 0) { + ap_cpystrn(record, "password verification error", (rlen - 1)); + return ERR_PWMISMATCH; + } + pw = pwin; + memset(pwv, '\0', sizeof(pwin)); + } + switch (alg) { + + case ALG_APSHA: + /* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */ + ap_sha1_base64(pw,strlen(pw),cpw); + break; + + case ALG_APMD5: + (void) srand((int) time((time_t *) NULL)); + ap_to64(&salt[0], rand(), 8); + salt[8] = '\0'; + + ap_MD5Encode((const unsigned char *)pw, (const unsigned char *)salt, + cpw, sizeof(cpw)); + break; + + case ALG_PLAIN: + /* XXX this len limitation is not in sync with any HTTPd len. */ + ap_cpystrn(cpw,pw,sizeof(cpw)); + break; + + case ALG_CRYPT: + default: + (void) srand((int) time((time_t *) NULL)); + ap_to64(&salt[0], rand(), 8); + salt[8] = '\0'; + + ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); + break; + } + memset(pw, '\0', strlen(pw)); + + /* + * Check to see if the buffer is large enough to hold the username, + * hash, and delimiters. + */ + if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) { + ap_cpystrn(record, "resultant record too long", (rlen - 1)); + return ERR_OVERFLOW; + } + strcpy(record, user); + strcat(record, ":"); + strcat(record, cpw); + return 0; +} -/* From local_passwd.c (C) Regents of Univ. of California blah blah */ -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; +static int usage(void) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "\thtpasswd [-cmdps] passwordfile username\n"); + fprintf(stderr, "\thtpasswd -b[cmdps] passwordfile username password\n\n"); + fprintf(stderr, " -c Create a new file.\n"); + fprintf(stderr, " -m Force MD5 encryption of the password" +#if defined(WIN32) || defined(TPF) + " (default)" +#endif + ".\n"); + fprintf(stderr, " -d Force CRYPT encryption of the password" +#if (!(defined(WIN32) || defined(TPF))) + " (default)" +#endif + ".\n"); + fprintf(stderr, " -p Do not encrypt the password (plaintext).\n"); + fprintf(stderr, " -s Force SHA encryption of the password.\n"); + fprintf(stderr, " -b Use the password from the command line rather " + "than prompting for it.\n"); + fprintf(stderr, + "On Windows and TPF systems the '-m' flag is used by default.\n"); + fprintf(stderr, + "On all other systems, the '-p' flag will probably not work.\n"); + return ERR_SYNTAX; +} -static void to64(register char *s, register long v, register int n) +static void interrupted(void) { - while (--n >= 0) { - *s++ = itoa64[v & 0x3f]; - v >>= 6; + fprintf(stderr, "Interrupted.\n"); + if (tempfilename != NULL) { + unlink(tempfilename); } + exit(ERR_INTERRUPTED); } -#ifdef MPE -/* MPE lacks getpass() and a way to suppress stdin echo. So for now, just - * issue the prompt and read the results with echo. (Ugh). +/* + * Check to see if the specified file can be opened for the given + * access. */ - -static char *getpass(const char *prompt) +static int accessible(char *fname, char *mode) { + FILE *s; - static char password[81]; - - fputs(prompt, stderr); - gets((char *) &password); - - if (strlen((char *) &password) > 8) { - password[8] = '\0'; + s = fopen(fname, mode); + if (s == NULL) { + return 0; } - - return (char *) &password; + fclose(s); + return 1; } -#endif +/* + * Return true if a file is readable. + */ +static int readable(char *fname) +{ + return accessible(fname, "r"); +} -static void add_password(char *user, FILE *f) +/* + * Return true if the specified file can be opened for write access. + */ +static int writable(char *fname) { - char *pw, *cpw, salt[3]; - - pw = strd((char *) getpass("New password:")); - if (strcmp(pw, (char *) getpass("Re-type new password:"))) { - fprintf(stderr, "They don't match, sorry.\n"); - if (tn) - unlink(tn); - exit(1); - } - (void) srand((int) time((time_t *) NULL)); - to64(&salt[0], rand(), 2); - salt[2] = '\0'; - cpw = (char *)crypt(pw, salt); - free(pw); - fprintf(f, "%s:%s\n", user, cpw); + return accessible(fname, "a"); } -static void usage(void) +/* + * Return true if the named file exists, regardless of permissions. + */ +static int exists(char *fname) { - fprintf(stderr, "Usage: htpasswd [-c] passwordfile username\n"); - fprintf(stderr, "The -c flag creates a new file.\n"); - exit(1); +#ifdef WIN32 + struct _stat sbuf; +#else + struct stat sbuf; +#endif + int check; + +#ifdef WIN32 + check = _stat(fname, &sbuf); +#else + check = stat(fname, &sbuf); +#endif + return ((check == -1) && (errno == ENOENT)) ? 0 : 1; } -static void interrupted(void) +/* + * Copy from the current position of one file to the current position + * of another. + */ +static void copy_file(FILE *target, FILE *source) { - fprintf(stderr, "Interrupted.\n"); - if (tn) - unlink(tn); - exit(1); + static char line[MAX_STRING_LEN]; + + while (fgets(line, sizeof(line), source) != NULL) { + fputs(line, target); + } } +/* + * Let's do it. We end up doing a lot of file opening and closing, + * but what do we care? This application isn't run constantly. + */ int main(int argc, char *argv[]) { - FILE *tfp, *f; + FILE *ftemp = NULL; + FILE *fpw = NULL; char user[MAX_STRING_LEN]; + char password[MAX_STRING_LEN]; + char record[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; - char l[MAX_STRING_LEN]; - char w[MAX_STRING_LEN]; - char command[MAX_STRING_LEN]; - int found; - - tn = NULL; - signal(SIGINT, (void (*)()) interrupted); - if (argc == 4) { - if (strcmp(argv[1], "-c")) - usage(); - if (!(tfp = fopen(argv[2], "w+"))) { - fprintf(stderr, "Could not open passwd file %s for writing.\n", - argv[2]); - perror("fopen"); - exit(1); + char pwfilename[MAX_STRING_LEN]; + char *arg; + int found = 0; + int alg = ALG_CRYPT; + int newfile = 0; + int noninteractive = 0; + int i; + int args_left = 2; + + tempfilename = NULL; + signal(SIGINT, (void (*)(int)) interrupted); + + /* + * Preliminary check to make sure they provided at least + * three arguments, we'll do better argument checking as + * we parse the command line. + */ + if (argc < 3) { + return usage(); + } + + /* + * Go through the argument list and pick out any options. They + * have to precede any other arguments. + */ + for (i = 1; i < argc; i++) { + arg = argv[i]; + if (*arg != '-') { + break; + } + while (*++arg != '\0') { + if (*arg == 'c') { + newfile++; + } + else if (*arg == 'm') { + alg = ALG_APMD5; + } + else if (*arg == 's') { + alg = ALG_APSHA; + } + else if (*arg == 'p') { + alg = ALG_PLAIN; + } + else if (*arg == 'd') { + alg = ALG_CRYPT; + } + else if (*arg == 'b') { + noninteractive++; + args_left++; + } + else { + return usage(); + } } - printf("Adding password for %s.\n", argv[3]); - add_password(argv[3], tfp); - fclose(tfp); - exit(0); } - else if (argc != 3) - usage(); - tn = tmpnam(NULL); - if (!(tfp = fopen(tn, "w+"))) { - fprintf(stderr, "Could not open temp file.\n"); - exit(1); + /* + * Make sure we still have exactly the right number of arguments left + * (the filename, the username, and possibly the password if -b was + * specified). + */ + if ((argc - i) != args_left) { + return usage(); + } + if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) { + fprintf(stderr, "%s: filename too long\n", argv[0]); + return ERR_OVERFLOW; + } + strcpy(pwfilename, argv[i]); + if (strlen(argv[i + 1]) > (sizeof(user) - 1)) { + fprintf(stderr, "%s: username too long (>%d)\n", argv[0], + sizeof(user) - 1); + return ERR_OVERFLOW; + } + strcpy(user, argv[i + 1]); + if ((arg = strchr(user, ':')) != NULL) { + fprintf(stderr, "%s: username contains illegal character '%c'\n", + argv[0], *arg); + return ERR_BADUSER; + } + if (noninteractive) { + if (strlen(argv[i + 2]) > (sizeof(password) - 1)) { + fprintf(stderr, "%s: password too long (>%d)\n", argv[0], + sizeof(password) - 1); + return ERR_OVERFLOW; + } + strcpy(password, argv[i + 2]); } - if (!(f = fopen(argv[1], "r+"))) { - fprintf(stderr, - "Could not open passwd file %s for reading.\n", argv[1]); - fprintf(stderr, "Use -c option to create new one.\n"); - exit(1); +#ifdef WIN32 + if (alg == ALG_CRYPT) { + alg = ALG_APMD5; + fprintf(stderr, "Automatically using MD5 format on Windows.\n"); } - strcpy(user, argv[2]); +#endif - found = 0; - while (!(getline(line, MAX_STRING_LEN, f))) { - if (found || (line[0] == '#') || (!line[0])) { - putline(tfp, line); - continue; - } - strcpy(l, line); - getword(w, l, ':'); - if (strcmp(user, w)) { - putline(tfp, line); - continue; - } - else { - printf("Changing password for user %s\n", user); - add_password(user, tfp); - found = 1; +#if (!(defined(WIN32) || defined(TPF))) + if (alg == ALG_PLAIN) { + fprintf(stderr,"Warning: storing passwords as plain text might " + "just not work on this platform.\n"); + } +#endif + /* + * Verify that the file exists if -c was omitted. We give a special + * message if it doesn't. + */ + if ((! newfile) && (! exists(pwfilename))) { + fprintf(stderr, "%s: cannot modify file %s; use '-c' to create it\n", + argv[0], pwfilename); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * Verify that we can read the existing file in the case of an update + * to it (rather than creation of a new one). + */ + if ((! newfile) && (! readable(pwfilename))) { + fprintf(stderr, "%s: cannot open file %s for read access\n", + argv[0], pwfilename); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * Now check to see if we can preserve an existing file in case + * of password verification errors on a -c operation. + */ + if (newfile && exists(pwfilename) && (! readable(pwfilename))) { + fprintf(stderr, "%s: cannot open file %s for read access\n" + "%s: existing auth data would be lost on password mismatch", + argv[0], pwfilename, argv[0]); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * Now verify that the file is writable! + */ + if (! writable(pwfilename)) { + fprintf(stderr, "%s: cannot open file %s for write access\n", + argv[0], pwfilename); + perror("fopen"); + exit(ERR_FILEPERM); + } + + /* + * All the file access checks have been made. Time to go to work; + * try to create the record for the username in question. If that + * fails, there's no need to waste any time on file manipulations. + * Any error message text is returned in the record buffer, since + * the mkrecord() routine doesn't have access to argv[]. + */ + i = mkrecord(user, record, sizeof(record) - 1, + noninteractive ? password : NULL, + alg); + if (i != 0) { + fprintf(stderr, "%s: %s\n", argv[0], record); + exit(i); + } + + /* + * We can access the files the right way, and we have a record + * to add or update. Let's do it.. + */ + tempfilename = tmpnam(NULL); + ftemp = fopen(tempfilename, "w+"); + if (ftemp == NULL) { + fprintf(stderr, "%s: unable to create temporary file\n", argv[0]); + perror("fopen"); + exit(ERR_FILEPERM); + } + /* + * If we're not creating a new file, copy records from the existing + * one to the temporary file until we find the specified user. + */ + if (! newfile) { + char scratch[MAX_STRING_LEN]; + + fpw = fopen(pwfilename, "r"); + while (! (getline(line, sizeof(line), fpw))) { + char *colon; + + if ((line[0] == '#') || (line[0] == '\0')) { + putline(ftemp, line); + continue; + } + strcpy(scratch, line); + /* + * See if this is our user. + */ + colon = strchr(scratch, ':'); + if (colon != NULL) { + *colon = '\0'; + } + if (strcmp(user, scratch) != 0) { + putline(ftemp, line); + continue; + } + found++; + break; } } - if (!found) { - printf("Adding user %s\n", user); - add_password(user, tfp); + if (found) { + fprintf(stderr, "Updating "); } -/* -* make a copy from the tmp file to the actual file -*/ - rewind(f); - rewind(tfp); - while ( fgets(command,MAX_STRING_LEN,tfp) != NULL) - { - fputs(command,f); - } - - fclose(f); - fclose(tfp); - unlink(tn); - exit(0); + else { + fprintf(stderr, "Adding "); + } + fprintf(stderr, "password for user %s\n", user); + /* + * Now add the user record we created. + */ + putline(ftemp, record); + /* + * If we're updating an existing file, there may be additional + * records beyond the one we're updating, so copy them. + */ + if (! newfile) { + copy_file(ftemp, fpw); + fclose(fpw); + } + /* + * The temporary file now contains the information that should be + * in the actual password file. Close the open files, re-open them + * in the appropriate mode, and copy them file to the real one. + */ + fclose(ftemp); + fpw = fopen(pwfilename, "w+"); + ftemp = fopen(tempfilename, "r"); + copy_file(fpw, ftemp); + fclose(fpw); + fclose(ftemp); + unlink(tempfilename); + return 0; } diff --git a/usr.sbin/httpd/src/support/httpd.8 b/usr.sbin/httpd/src/support/httpd.8 index d5edaab9a21..ae320bad2ad 100644 --- a/usr.sbin/httpd/src/support/httpd.8 +++ b/usr.sbin/httpd/src/support/httpd.8 @@ -7,7 +7,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 @@ -56,7 +56,7 @@ .SH NAME httpd \- Apache hypertext transfer protocol server .SH SYNOPSIS -.B httpd +.B httpd [ .B \-X ] [ @@ -73,51 +73,57 @@ httpd \- Apache hypertext transfer protocol server .BI \-D " parameter" ] -.B httpd +.B httpd [ .B \-h -] +] [ .B \-l -] +] [ .B \-L -] +] [ .B \-v -] +] [ .B \-V -] +] [ .B \-S +] +[ +.B \-t +] +[ +.B \-T ] .SH DESCRIPTION .B httpd is the Apache HyperText Transfer Protocol (HTTP) server program. It is designed to be run as a standalone daemon process. When used like this -is will create a pool of child processes to handle requests. To stop +it will create a pool of child processes to handle requests. To stop it, send a TERM signal to the initial (parent) process. The PID of this process is written to a file as given in the configuration file. -Alternatively -.B httpd +Alternatively +.B httpd may be invoked by the Internet daemon inetd(8) each time a connection to the HTTP service is made. .PP This manual page only lists the command line arguments. For details -of the directives necessary to configure +of the directives necessary to configure .B httpd see the Apache manual, which is part of the Apache distribution or can be found at http://www.apache.org/. Paths in this manual may not reflect those -compiled into +compiled into .B httpd. .SH OPTIONS .TP 12 .BI \-R " libexecdir" This option is only available if Apache was built with -the +the .I SHARED_CORE rule enabled which forces the Apache core code to be placed into a dynamic shared object (DSO) file. This file @@ -164,18 +170,23 @@ Run syntax tests for configuration files only. The program immediately exits after these syntax parsing with either a return code of 0 (Syntax OK) or return code not equal to 0 (Syntax Error). .TP +.B \-T +Same as option +.B \-t +but does not check the configured document roots. +.TP .B \-X Run in single-process mode, for internal debugging purposes only; the daemon does not detach from the terminal or fork any children. Do NOT use this mode to provide ordinary web service. .TP .B \-v -Print the version of +Print the version of .B httpd , and then exit. .TP .B \-V -Print the version and build parameters of +Print the version and build parameters of .B httpd , and then exit. .SH FILES diff --git a/usr.sbin/httpd/src/support/httpd.exp b/usr.sbin/httpd/src/support/httpd.exp index 63faaa3fbea..083d981a4a3 100644 --- a/usr.sbin/httpd/src/support/httpd.exp +++ b/usr.sbin/httpd/src/support/httpd.exp @@ -1,7 +1,12 @@ #! +ap_MD5Encode ap_MD5Final ap_MD5Init ap_MD5Update +ap_SHA1Final +ap_SHA1Init +ap_SHA1Update_binary +ap_SHA1Update ap_add_cgi_vars ap_add_common_vars ap_add_module @@ -16,6 +21,12 @@ ap_array_cat ap_array_pstrcat ap_auth_name ap_auth_type +ap_base64encode +ap_base64encode_binary +ap_base64encode_len +ap_base64decode +ap_base64decode_binary +ap_base64decode_len ap_basic_http_header ap_bclose ap_bcreate @@ -99,12 +110,14 @@ ap_excess_requests_per_child ap_exists_config_define ap_exists_scoreboard_image ap_extended_status +ap_field_noparam ap_finalize_request_protocol ap_finalize_sub_req_protocol ap_find_command ap_find_command_in_modules ap_find_last_token ap_find_linked_module +ap_find_list_item ap_find_module_name ap_find_path_info ap_find_token @@ -115,6 +128,7 @@ ap_force_library_loading ap_get_basic_auth_pw ap_get_client_block ap_get_gmtoff +ap_get_list_item ap_get_local_host ap_get_remote_host ap_get_remote_logname @@ -203,7 +217,6 @@ ap_null_cleanup ap_open_logs ap_open_piped_log ap_os_escape_path -ap_os_is_filename_valid ap_os_is_path_absolute ap_overlay_tables ap_overlap_tables @@ -214,6 +227,8 @@ ap_parse_htaccess ap_parse_uri ap_parse_uri_components ap_parse_vhost_addrs +ap_pbase64decode +ap_pbase64encode ap_pcalloc ap_pcfg_open_custom ap_pcfg_openfile @@ -246,6 +261,8 @@ ap_pvsprintf ap_rationalize_mtime ap_read_config ap_read_request +ap_regerror +ap_regexec ap_register_cleanup ap_register_other_child ap_remove_module @@ -283,6 +300,7 @@ ap_send_http_trace ap_send_mmap ap_send_size ap_server_argv0 +ap_server_config_defines ap_server_confname ap_server_post_read_config ap_server_pre_read_config @@ -302,12 +320,13 @@ ap_set_string_slot_lower ap_set_sub_req_protocol ap_setup_client_block ap_setup_prelinked_modules +ap_sha1_base64 ap_should_client_block ap_show_directives ap_show_modules ap_signal ap_single_module_configure -ap_single_module_init +ap_size_list_item ap_slack ap_snprintf ap_soft_timeout @@ -322,6 +341,7 @@ ap_strcasecmp_match ap_strcmp_match ap_sub_req_lookup_file ap_sub_req_lookup_uri +ap_sub_req_method_uri ap_suexec_enabled ap_sync_scoreboard_image ap_table_add @@ -350,12 +370,48 @@ ap_user_name ap_util_init ap_util_uri_init ap_uudecode +ap_validate_password ap_vbprintf ap_vformatter ap_vsnprintf core_module top_module +XML_DefaultCurrent +XML_ErrorString +XML_ExternalEntityParserCreate +XML_GetBase +XML_GetBuffer +XML_GetCurrentByteCount +XML_GetCurrentByteIndex +XML_GetCurrentColumnNumber +XML_GetCurrentLineNumber +XML_GetErrorCode +XML_GetSpecifiedAttributeCount +XML_Parse +XML_ParseBuffer +XML_ParserCreate +XML_ParserCreateNS +XML_ParserFree +XML_SetBase +XML_SetCdataSectionHandler +XML_SetCharacterDataHandler +XML_SetCommentHandler +XML_SetDefaultHandler +XML_SetDefaultHandlerExpand +XML_SetElementHandler +XML_SetEncoding +XML_SetExternalEntityRefHandler +XML_SetExternalEntityRefHandlerArg +XML_SetNamespaceDeclHandler +XML_SetNotStandaloneHandler +XML_SetNotationDeclHandler +XML_SetProcessingInstructionHandler +XML_SetUnknownEncodingHandler +XML_SetUnparsedEntityDeclHandler +XML_SetUserData +XML_UseParserAsHandlerArg ap_add_config_define +ap_make_shared_sub_pool ap_global_ctx ap_ctx_new ap_ctx_get @@ -368,3 +424,45 @@ ap_hook_unregister_I ap_hook_status ap_hook_use ap_hook_call +ap_mm_useable +ap_MM_create +ap_MM_permission +ap_MM_destroy +ap_MM_lock +ap_MM_unlock +ap_MM_malloc +ap_MM_realloc +ap_MM_free +ap_MM_calloc +ap_MM_strdup +ap_MM_sizeof +ap_MM_maxsize +ap_MM_available +ap_MM_error +ap_mm_create +ap_mm_permission +ap_mm_destroy +ap_mm_lock +ap_mm_unlock +ap_mm_malloc +ap_mm_realloc +ap_mm_free +ap_mm_calloc +ap_mm_strdup +ap_mm_sizeof +ap_mm_maxsize +ap_mm_available +ap_mm_error +ap_mm_display_info +ap_mm_core_create +ap_mm_core_permission +ap_mm_core_delete +ap_mm_core_size +ap_mm_core_lock +ap_mm_core_unlock +ap_mm_core_maxsegsize +ap_mm_core_align2page +ap_mm_core_align2word +ap_mm_lib_error_set +ap_mm_lib_error_get +ap_mm_lib_version diff --git a/usr.sbin/httpd/src/support/log_server_status b/usr.sbin/httpd/src/support/log_server_status index 694247dd8b3..1eb2893edcd 100644 --- a/usr.sbin/httpd/src/support/log_server_status +++ b/usr.sbin/httpd/src/support/log_server_status @@ -67,7 +67,7 @@ # require 'sys/socket.ph'; -$wherelog = "/var/log/graph/"; # Logs will be like "/var/log/graph/960312" +$wherelog = "/var/log/graph/"; # Logs will be like "/var/log/graph/19960312" $server = "localhost"; # Name of server, could be "www.foo.com" $port = "80"; # Port on server $request = "/status/?auto"; # Request to send @@ -93,8 +93,11 @@ sub tcp_connect ### Main { - $date=`date +%y%m%d:%H%M%S`; - chop($date); + $year=`date +%y`; + chomp($year); + $year += ($year < 70) ? 2000 : 1900; + $date = $year . `date +%m%d:%H%M%S`; + chomp($date); ($day,$time)=split(/:/,$date); $res=&tcp_connect($server,$port); open(OUT,">>$wherelog$day"); diff --git a/usr.sbin/httpd/src/support/logresolve.8 b/usr.sbin/httpd/src/support/logresolve.8 index 9f12271820f..4851269ad61 100644 --- a/usr.sbin/httpd/src/support/logresolve.8 +++ b/usr.sbin/httpd/src/support/logresolve.8 @@ -6,7 +6,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 @@ -59,7 +59,7 @@ logresolve \- resolve hostnames for IP-adresses in Apache logfiles .BI \-s " filename" ] [ .B \-c -] < +] < .I access_log > .I access_log.new @@ -75,9 +75,9 @@ up the first time it is found in the log file. .BI \-s " filename" Specifies a filename to record statistics. .TP 12 -.B \-c -This causes -.B logresolve +.B \-c +This causes +.B logresolve to apply some DNS checks: after finding the hostname from the IP address, it looks up the IP addresses for the hostname and checks that one of these matches the original address. diff --git a/usr.sbin/httpd/src/support/mkcert.sh b/usr.sbin/httpd/src/support/mkcert.sh index 26b4506e024..0008ddc702e 100644 --- a/usr.sbin/httpd/src/support/mkcert.sh +++ b/usr.sbin/httpd/src/support/mkcert.sh @@ -7,21 +7,23 @@ # parameters make="$1" mflags="$2" -ssleay="$3" +openssl="$3" support="$4" type="$5" -crt="$6" -key="$7" +algo="$6" +crt="$7" +key="$8" +view="$9" # we can operate only inside the Apache 1.3 source -# tree and only when mod_ssl+SSLeay is actually configured. +# tree and only when mod_ssl+OpenSSL is actually configured. if [ ! -f "../README.configure" ]; then echo "mkcert.sh:Error: Cannot operate outside the Apache 1.3 source tree." 1>&2 echo "mkcert.sh:Hint: You have to stay inside apache_1.3.x/src." 1>&2 exit 1 fi -if [ ".$ssleay" = . ]; then - echo "mkcert.sh:Error: mod_ssl/SSLeay has to be configured before using this utility." 1>&2 +if [ ".$openssl" = . ]; then + echo "mkcert.sh:Error: mod_ssl/OpenSSL has to be configured before using this utility." 1>&2 echo "mkcert.sh:Hint: Configure mod_ssl with --enable-module=ssl in APACI, first." 1>&2 exit 1 fi @@ -31,6 +33,7 @@ fi sslcrtdir="../conf/ssl.crt" sslcsrdir="../conf/ssl.csr" sslkeydir="../conf/ssl.key" +sslprmdir="../conf/ssl.prm" # some optional terminal sequences case $TERM in @@ -50,12 +53,48 @@ esac # display header echo "${T_MD}SSL Certificate Generation Utility${T_ME} (mkcert.sh)" -echo "Copyright (c) 1998 Ralf S. Engelschall, All Rights Reserved." +echo "Copyright (c) 1998-1999 Ralf S. Engelschall, All Rights Reserved." + +# on request view certificates only +if [ ".$view" != . ]; then + if [ -f "$sslcrtdir/ca.crt" -a -f "$sslkeydir/ca.key" ]; then + echo "" + echo "${T_MD}CA X.509 Certificate${T_ME} [ca.crt]" + echo "______________________________________________________________________" + $openssl x509 -noout -text -in $sslcrtdir/ca.crt + echo "" + if [ ".`$openssl x509 -noout -text -in $sslcrtdir/ca.crt | grep "Signature Algorithm" | grep -i RSA`" != . ]; then + echo "${T_MD}CA RSA Private Key${T_ME} [ca.key]" + echo "______________________________________________________________________" + $openssl rsa -noout -text -in $sslkeydir/ca.key + else + echo "${T_MD}CA DSA Private Key${T_ME} [ca.key]" + echo "______________________________________________________________________" + $openssl dsa -noout -text -in $sslkeydir/ca.key + fi + fi + if [ -f "$sslcrtdir/server.crt" -a -f "$sslkeydir/server.key" ]; then + echo "" + echo "${T_MD}Server X.509 Certificate${T_ME} [server.crt]" + echo "______________________________________________________________________" + $openssl x509 -noout -text -in $sslcrtdir/server.crt + echo "" + if [ ".`$openssl x509 -noout -text -in $sslcrtdir/server.crt | grep "Signature Algorithm" | grep -i RSA`" != . ]; then + echo "${T_MD}Server RSA Private Key${T_ME} [server.key]" + echo "______________________________________________________________________" + $openssl rsa -noout -text -in $sslkeydir/server.key + else + echo "${T_MD}Server DSA Private Key${T_ME} [server.key]" + echo "______________________________________________________________________" + $openssl dsa -noout -text -in $sslkeydir/server.key + fi + fi + exit 0 +fi # find some random files # (do not use /dev/random here, because this device # doesn't work as expected on all platforms) -echo " + finding random files on your platform" randfiles='' for file in /var/log/messages /var/adm/messages \ /kernel /vmunix /vmlinuz \ @@ -69,22 +108,23 @@ for file in /var/log/messages /var/adm/messages \ fi done -# on-demand compile the ca-fix only -case $type in - test|custom) - cd $support - if [ ! -f ca-fix ]; then - echo " + building ca-fix auxiliary tool" - $make $mflags ca-fix >/dev/null 2>&1 - if [ $? -ne 0 ]; then - $make $mflags ca-fix - echo "**FAILED" - exit 1 - fi - fi - cd .. - cafix="$support/ca-fix" - ;; +# canonicalize parameters +case "x$type" in + x ) type=test ;; +esac +case "x$algo" in + xRSA|xrsa ) + algo=RSA + ;; + xDSA|xdsa ) + algo=DSA + ;; + x ) + algo=choose + ;; + * ) echo "Unknown algorithm \'$algo' (use RSA or DSA!)" 1>&2 + exit 1 + ;; esac # processing @@ -95,17 +135,25 @@ case $type in echo "${T_MD}Generating self-signed Snake Oil certificate [DUMMY]${T_ME}" echo "______________________________________________________________________" echo "" - cp $sslcrtdir/snakeoil.crt $sslcrtdir/server.crt - cp $sslkeydir/snakeoil.key $sslkeydir/server.key + if [ ".$algo" = .choose ]; then + algo=RSA + fi + if [ ".$algo" = .RSA ]; then + cp $sslcrtdir/snakeoil-rsa.crt $sslcrtdir/server.crt + cp $sslkeydir/snakeoil-rsa.key $sslkeydir/server.key + else + cp $sslcrtdir/snakeoil-dsa.crt $sslcrtdir/server.crt + cp $sslkeydir/snakeoil-dsa.key $sslkeydir/server.key + fi echo "${T_MD}RESULT: Server Certification Files${T_ME}" echo "" echo "o ${T_MD}conf/ssl.key/server.key${T_ME}" - echo " The PEM-encoded RSA private certificate file which you configure" + echo " The PEM-encoded $algo private key file which you configure" echo " with the 'SSLCertificateKeyFile' directive (automatically done" echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}" echo "" echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}" - echo " The PEM-encoded X.509 server certificate file which you configure" + echo " The PEM-encoded X.509 certificate file which you configure" echo " with the 'SSLCertificateFile' directive (automatically done" echo " when you install via APACI)." echo "" @@ -117,23 +165,58 @@ case $type in echo "" echo "${T_MD}Generating test certificate signed by Snake Oil CA [TEST]${T_ME}" echo "WARNING: Do not use this for real-life/production systems" + if [ ".$algo" = .choose ]; then + echo "______________________________________________________________________" + echo "" + echo "${T_MD}STEP 0: Decide the signature algorithm used for certificate${T_ME}" + echo "The generated X.509 CA certificate can contain either" + echo "RSA or DSA based ingredients. Select the one you want to use." + def1=R def2=r def=RSA + prompt="Signature Algorithm ((R)SA or (D)SA) [$def1]:" + while [ 1 ]; do + echo dummy | awk '{ printf("%s", prompt); }' "prompt=$prompt" + read algo + if [ ".$algo" = ".$def1" -o ".$algo" = ".$def2" -o ".$algo" = . ]; then + algo=$def + break + elif [ ".$algo" = ".R" -o ".$algo" = ".r" ]; then + algo=RSA + break + elif [ ".$algo" = ".D" -o ".$algo" = ".d" ]; then + algo=DSA + break + else + echo "mkcert.sh:Warning: Invalid selection" 1>&2 + fi + done + fi echo "______________________________________________________________________" echo "" - echo "${T_MD}STEP 1: Generating RSA private key (1024 bit) [server.key]${T_ME}" + echo "${T_MD}STEP 1: Generating $algo private key (1024 bit) [server.key]${T_ME}" if [ ! -f $HOME/.rnd ]; then touch $HOME/.rnd fi - if [ ".$randfiles" != . ]; then - $ssleay genrsa -rand $randfiles \ - -out $sslkeydir/server.key \ - 1024 + if [ ".$algo" = .RSA ]; then + if [ ".$randfiles" != . ]; then + $openssl genrsa -rand $randfiles -out $sslkeydir/server.key 1024 + else + $openssl genrsa -out $sslkeydir/server.key 1024 + fi + if [ $? -ne 0 ]; then + echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2 + exit 1 + fi else - $ssleay genrsa -out $sslkeydir/server.key \ - 1024 - fi - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2 - exit 1 + echo "Generating DSA private key via SnakeOil CA DSA parameters" + if [ ".$randfiles" != . ]; then + $openssl gendsa -rand $randfiles -out $sslkeydir/server.key $sslprmdir/snakeoil-ca-dsa.prm + else + $openssl gendsa -out $sslkeydir/server.key $sslprmdir/snakeoil-ca-dsa.prm + fi + if [ $? -ne 0 ]; then + echo "mkcert.sh:Error: Failed to generate DSA private key" 1>&2 + exit 1 + fi fi echo "______________________________________________________________________" echo "" @@ -162,10 +245,10 @@ emailAddress = "7. Email Address (eg, name@FQDN)" emailAddress_max = 40 emailAddress_default = www@snakeoil.dom EOT - $ssleay req -config .mkcert.cfg \ - -new \ - -key $sslkeydir/server.key \ - -out $sslcsrdir/server.csr + $openssl req -config .mkcert.cfg \ + -new \ + -key $sslkeydir/server.key \ + -out $sslcsrdir/server.csr if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2 exit 1 @@ -176,64 +259,66 @@ EOT echo "${T_MD}STEP 3: Generating X.509 certificate signed by Snake Oil CA [server.crt]${T_ME}" echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 3) [3]:" read certversion + extfile="" if [ ".$certversion" = .3 -o ".$certversion" = . ]; then - certversion=3 - else - certversion=1 + extfile="-extfile .mkcert.cfg" + cat >.mkcert.cfg <<EOT +extensions = x509v3 +[ x509v3 ] +subjectAltName = email:copy +nsComment = "mod_ssl generated test server certificate" +nsCertType = server +EOT fi if [ ! -f .mkcert.serial ]; then echo '01' >.mkcert.serial fi - $ssleay x509 -days 365 \ - -CAserial .mkcert.serial \ - -CA $sslcrtdir/snakeoil-ca.crt \ - -CAkey $sslkeydir/snakeoil-ca.key \ - -in $sslcsrdir/server.csr -req \ - -out $sslcrtdir/server.crt + if [ ".$algo" = .RSA ]; then + $openssl x509 $extfile \ + -days 365 \ + -CAserial .mkcert.serial \ + -CA $sslcrtdir/snakeoil-ca-rsa.crt \ + -CAkey $sslkeydir/snakeoil-ca-rsa.key \ + -in $sslcsrdir/server.csr -req \ + -out $sslcrtdir/server.crt + else + $openssl x509 $extfile \ + -days 365 \ + -CAserial .mkcert.serial \ + -CA $sslcrtdir/snakeoil-ca-dsa.crt \ + -CAkey $sslkeydir/snakeoil-ca-dsa.key \ + -in $sslcsrdir/server.csr -req \ + -out $sslcrtdir/server.crt + fi if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to generate X.509 certificate" 1>&2 exit 1 fi - if [ ".$certversion" = .3 ]; then - echo "Converting X.509 v1 to v3 certificate" - $cafix -nscertype 0x40 \ - -nobscrit \ - -nosign \ - -in $sslcrtdir/server.crt \ - -inkey $sslkeydir/server.key \ - -out $sslcrtdir/server.crt.fixed - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to fixup X.509 certificate contents" 1>&2 - exit 1 - fi - cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt - rm -f $sslcrtdir/server.crt.fixed - $cafix -inkey $sslkeydir/snakeoil-ca.key \ - -in $sslcrtdir/server.crt \ - -out $sslcrtdir/server.crt.fixed - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to fixup X.509 certificate signature" 1>&2 - exit 1 - fi - cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt - rm -f $sslcrtdir/server.crt.fixed - fi + rm -f .mkcert.cfg echo "Verify: matching certificate & key modulus" - modcrt=`$ssleay x509 -noout -modulus -in $sslcrtdir/server.crt` - modkey=`$ssleay rsa -noout -modulus -in $sslkeydir/server.key` + modcrt=`$openssl x509 -noout -modulus -in $sslcrtdir/server.crt | sed -e 's;.*Modulus=;;'` + if [ ".$algo" = .RSA ]; then + modkey=`$openssl rsa -noout -modulus -in $sslkeydir/server.key | sed -e 's;.*Modulus=;;'` + else + modkey=`$openssl dsa -noout -modulus -in $sslkeydir/server.key | sed -e 's;.*Key=;;'` + fi if [ ".$modcrt" != ".$modkey" ]; then echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 certificate" 1>&2 exit 1 fi echo "Verify: matching certificate signature" - $ssleay verify -CAfile $sslcrtdir/snakeoil-ca.crt $sslcrtdir/server.crt + if [ ".$algo" = .RSA ]; then + $openssl verify -CAfile $sslcrtdir/snakeoil-ca-rsa.crt $sslcrtdir/server.crt + else + $openssl verify -CAfile $sslcrtdir/snakeoil-ca-dsa.crt $sslcrtdir/server.crt + fi if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 certificate" 1>&2 exit 1 fi echo "______________________________________________________________________" echo "" - echo "${T_MD}STEP 4: Enrypting RSA private key with a pass phrase for security [server.key]${T_ME}" + echo "${T_MD}STEP 4: Enrypting $algo private key with a pass phrase for security [server.key]${T_ME}" echo "The contents of the server.key file (the generated private key) has to be" echo "kept secret. So we strongly recommend you to encrypt the server.key file" echo "with a Triple-DES cipher and a Pass Phrase." @@ -250,18 +335,24 @@ EOT fi done if [ ".$rc" = .y ]; then - $ssleay rsa -des3 \ - -in $sslkeydir/server.key \ - -out $sslkeydir/server.key.crypt + if [ ".$algo" = .RSA ]; then + $openssl rsa -des3 \ + -in $sslkeydir/server.key \ + -out $sslkeydir/server.key.crypt + else + $openssl dsa -des3 \ + -in $sslkeydir/server.key \ + -out $sslkeydir/server.key.crypt + fi if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to encrypt RSA private key" 1>&2 + echo "mkcert.sh:Error: Failed to encrypt $algo private key" 1>&2 exit 1 fi cp $sslkeydir/server.key.crypt $sslkeydir/server.key rm -f $sslkeydir/server.key.crypt - echo "Fine, you're using an encrypted private key." + echo "Fine, you're using an encrypted $algo private key." else - echo "Warning, you're using an unencrypted private key." + echo "Warning, you're using an unencrypted $algo private key." echo "Please notice this fact and do this on your own risk." fi echo "______________________________________________________________________" @@ -269,12 +360,12 @@ EOT echo "${T_MD}RESULT: Server Certification Files${T_ME}" echo "" echo "o ${T_MD}conf/ssl.key/server.key${T_ME}" - echo " The PEM-encoded RSA private certificate file which you configure" + echo " The PEM-encoded $algo private key file which you configure" echo " with the 'SSLCertificateKeyFile' directive (automatically done" echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}" echo "" echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}" - echo " The PEM-encoded X.509 server certificate file which you configure" + echo " The PEM-encoded X.509 certificate file which you configure" echo " with the 'SSLCertificateFile' directive (automatically done" echo " when you install via APACI)." echo "" @@ -292,23 +383,61 @@ EOT custom) echo "" echo "${T_MD}Generating custom certificate signed by own CA [CUSTOM]${T_ME}" + if [ ".$algo" = .choose ]; then + echo "______________________________________________________________________" + echo "" + echo "${T_MD}STEP 0: Decide the signature algorithm used for certificates${T_ME}" + echo "The generated X.509 certificates can contain either" + echo "RSA or DSA based ingredients. Select the one you want to use." + def1=R def2=r def=RSA + prompt="Signature Algorithm ((R)SA or (D)SA) [$def1]:" + while [ 1 ]; do + echo dummy | awk '{ printf("%s", prompt); }' "prompt=$prompt" + read algo + if [ ".$algo" = ".$def1" -o ".$algo" = ".$def2" -o ".$algo" = . ]; then + algo=$def + break + elif [ ".$algo" = ".R" -o ".$algo" = ".r" ]; then + algo=RSA + break + elif [ ".$algo" = ".D" -o ".$algo" = ".d" ]; then + algo=DSA + break + else + echo "mkcert.sh:Warning: Invalid selection" 1>&2 + fi + done + fi echo "______________________________________________________________________" echo "" - echo "${T_MD}STEP 1: Generating RSA private key for CA (1024 bit) [ca.key]${T_ME}" + echo "${T_MD}STEP 1: Generating $algo private key for CA (1024 bit) [ca.key]${T_ME}" if [ ! -f $HOME/.rnd ]; then touch $HOME/.rnd fi - if [ ".$randfiles" != . ]; then - $ssleay genrsa -rand $randfiles \ - -out $sslkeydir/ca.key \ - 1024 + if [ ".$algo" = .RSA ]; then + if [ ".$randfiles" != . ]; then + $openssl genrsa -rand $randfiles -out $sslkeydir/ca.key 1024 + else + $openssl genrsa -out $sslkeydir/ca.key 1024 + fi + if [ $? -ne 0 ]; then + echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2 + exit 1 + fi else - $ssleay genrsa -out $sslkeydir/ca.key \ - 1024 - fi - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2 - exit 1 + if [ ".$randfiles" != . ]; then + $openssl dsaparam -rand $randfiles -out $sslprmdir/ca.prm 1024 + echo "Generating DSA private key:" + $openssl gendsa -rand $randfiles -out $sslkeydir/ca.key $sslprmdir/ca.prm + else + $openssl dsaparam -out $sslprmdir/ca.prm 1024 + echo "Generating DSA private key:" + $openssl gendsa -out $sslkeydir/ca.key $sslprmdir/ca.prm + fi + if [ $? -ne 0 ]; then + echo "mkcert.sh:Error: Failed to generate DSA private key" 1>&2 + exit 1 + fi fi echo "______________________________________________________________________" echo "" @@ -337,10 +466,10 @@ emailAddress = "7. Email Address (eg, name@FQDN)" emailAddress_max = 40 emailAddress_default = ca@snakeoil.dom EOT - $ssleay req -config .mkcert.cfg \ - -new \ - -key $sslkeydir/ca.key \ - -out $sslcsrdir/ca.csr + $openssl req -config .mkcert.cfg \ + -new \ + -key $sslkeydir/ca.key \ + -out $sslcsrdir/ca.csr if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2 exit 1 @@ -351,64 +480,71 @@ EOT echo "${T_MD}STEP 3: Generating X.509 certificate for CA signed by itself [ca.crt]${T_ME}" echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 3) [3]:" read certversion + extfile="" if [ ".$certversion" = .3 -o ".$certversion" = . ]; then - certversion=3 - else - certversion=1 + extfile="-extfile .mkcert.cfg" + cat >.mkcert.cfg <<EOT +extensions = x509v3 +[ x509v3 ] +subjectAltName = email:copy +basicConstraints = CA:true,pathlen:0 +nsComment = "mod_ssl generated custom CA certificate" +nsCertType = sslCA +EOT fi - $ssleay x509 -days 365 \ - -signkey $sslkeydir/ca.key \ - -in $sslcsrdir/ca.csr -req \ - -out $sslcrtdir/ca.crt + $openssl x509 $extfile \ + -days 365 \ + -signkey $sslkeydir/ca.key \ + -in $sslcsrdir/ca.csr -req \ + -out $sslcrtdir/ca.crt if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to generate self-signed CA certificate" 1>&2 exit 1 fi - if [ ".$certversion" = .3 ]; then - $cafix -caset \ - -nscertype 0x07 \ - -pathlen 0 \ - -nobscrit \ - -in $sslcrtdir/ca.crt \ - -inkey $sslkeydir/ca.key \ - -out $sslcrtdir/ca.crt.fixed - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to fixup X.509 CA certificate" 1>&2 - exit 1 - fi - cp $sslcrtdir/ca.crt.fixed $sslcrtdir/ca.crt - rm -f $sslcrtdir/ca.crt.fixed - fi + rm -f .mkcert.cfg echo "Verify: matching certificate & key modulus" - modcrt=`$ssleay x509 -noout -modulus -in $sslcrtdir/ca.crt` - modkey=`$ssleay rsa -noout -modulus -in $sslkeydir/ca.key` + modcrt=`$openssl x509 -noout -modulus -in $sslcrtdir/ca.crt | sed -e 's;.*Modulus=;;'` + if [ ".$algo" = .RSA ]; then + modkey=`$openssl rsa -noout -modulus -in $sslkeydir/ca.key | sed -e 's;.*Modulus=;;'` + else + modkey=`$openssl dsa -noout -modulus -in $sslkeydir/ca.key | sed -e 's;.*Key=;;'` + fi if [ ".$modcrt" != ".$modkey" ]; then echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 certificate" 1>&2 exit 1 fi echo "Verify: matching certificate signature" - $ssleay verify $sslcrtdir/ca.crt + $openssl verify $sslcrtdir/ca.crt if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 certificate" 1>&2 exit 1 fi echo "______________________________________________________________________" echo "" - echo "${T_MD}STEP 4: Generating RSA private key for SERVER (1024 bit) [server.key]${T_ME}" + echo "${T_MD}STEP 4: Generating $algo private key for SERVER (1024 bit) [server.key]${T_ME}" if [ ! -f $HOME/.rnd ]; then touch $HOME/.rnd fi - if [ ".$randfiles" != . ]; then - $ssleay genrsa -rand $randfiles \ - -out $sslkeydir/server.key \ - 1024 + if [ ".$algo" = .RSA ]; then + if [ ".$randfiles" != . ]; then + $openssl genrsa -rand $randfiles -out $sslkeydir/server.key 1024 + else + $openssl genrsa -out $sslkeydir/server.key 1024 + fi + if [ $? -ne 0 ]; then + echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2 + exit 1 + fi else - $ssleay genrsa -out $sslkeydir/server.key \ - 1024 - fi - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to generate RSA private key" 1>&2 - exit 1 + if [ ".$randfiles" != . ]; then + $openssl gendsa -rand $randfiles -out $sslkeydir/server.key $sslprmdir/ca.prm + else + $openssl gendsa -out $sslkeydir/server.key $sslprmdir/ca.prm + fi + if [ $? -ne 0 ]; then + echo "mkcert.sh:Error: Failed to generate DSA private key" 1>&2 + exit 1 + fi fi echo "______________________________________________________________________" echo "" @@ -437,10 +573,10 @@ emailAddress = "7. Email Address (eg, name@fqdn)" emailAddress_max = 40 emailAddress_default = www@snakeoil.dom EOT - $ssleay req -config .mkcert.cfg \ - -new \ - -key $sslkeydir/server.key \ - -out $sslcsrdir/server.csr + $openssl req -config .mkcert.cfg \ + -new \ + -key $sslkeydir/server.key \ + -out $sslcsrdir/server.csr if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to generate certificate signing request" 1>&2 exit 1 @@ -451,63 +587,52 @@ EOT echo "${T_MD}STEP 6: Generating X.509 certificate signed by own CA [server.crt]${T_ME}" echo dummy | awk '{ printf("%s", prompt); }' "prompt=Certificate Version (1 or 3) [3]:" read certversion + extfile="" if [ ".$certversion" = .3 -o ".$certversion" = . ]; then - certversion=3 - else - certversion=1 + extfile="-extfile .mkcert.cfg" + cat >.mkcert.cfg <<EOT +extensions = x509v3 +[ x509v3 ] +subjectAltName = email:copy +nsComment = "mod_ssl generated custom server certificate" +nsCertType = server +EOT fi if [ ! -f .mkcert.serial ]; then echo '01' >.mkcert.serial fi - $ssleay x509 -days 365 \ - -CAserial .mkcert.serial \ - -CA $sslcrtdir/ca.crt \ - -CAkey $sslkeydir/ca.key \ - -in $sslcsrdir/server.csr -req \ - -out $sslcrtdir/server.crt + $openssl x509 $extfile \ + -days 365 \ + -CAserial .mkcert.serial \ + -CA $sslcrtdir/ca.crt \ + -CAkey $sslkeydir/ca.key \ + -in $sslcsrdir/server.csr -req \ + -out $sslcrtdir/server.crt if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to generate X.509 certificate" 1>&2 exit 1 fi - if [ ".$certversion" = .3 ]; then - $cafix -nscertype 0x40 \ - -nobscrit \ - -nosign \ - -in $sslcrtdir/server.crt \ - -inkey $sslkeydir/server.key \ - -out $sslcrtdir/server.crt.fixed - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to fixup X.509 certificate contents" 1>&2 - exit 1 - fi - cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt - rm -f $sslcrtdir/server.crt.fixed - $cafix -inkey $sslkeydir/ca.key \ - -in $sslcrtdir/server.crt \ - -out $sslcrtdir/server.crt.fixed - if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to fixup X.509 certificate signature" 1>&2 - exit 1 - fi - cp $sslcrtdir/server.crt.fixed $sslcrtdir/server.crt - rm -f $sslcrtdir/server.crt.fixed - fi + rm -f .mkcert.cfg echo "Verify: matching certificate & key modulus" - modcrt=`$ssleay x509 -noout -modulus -in $sslcrtdir/server.crt` - modkey=`$ssleay rsa -noout -modulus -in $sslkeydir/server.key` + modcrt=`$openssl x509 -noout -modulus -in $sslcrtdir/server.crt | sed -e 's;.*Modulus=;;'` + if [ ".$algo" = .RSA ]; then + modkey=`$openssl rsa -noout -modulus -in $sslkeydir/server.key | sed -e 's;.*Modulus=;;'` + else + modkey=`$openssl dsa -noout -modulus -in $sslkeydir/server.key | sed -e 's;.*Key=;;'` + fi if [ ".$modcrt" != ".$modkey" ]; then echo "mkcert.sh:Error: Failed to verify modulus on resulting X.509 certificate" 1>&2 exit 1 fi echo "Verify: matching certificate signature" - $ssleay verify -CAfile $sslcrtdir/ca.crt $sslcrtdir/server.crt + $openssl verify -CAfile $sslcrtdir/ca.crt $sslcrtdir/server.crt if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to verify signature on resulting X.509 certificate" 1>&2 exit 1 fi echo "______________________________________________________________________" echo "" - echo "${T_MD}STEP 7: Enrypting RSA private key of CA with a pass phrase for security [ca.key]${T_ME}" + echo "${T_MD}STEP 7: Enrypting $algo private key of CA with a pass phrase for security [ca.key]${T_ME}" echo "The contents of the ca.key file (the generated private key) has to be" echo "kept secret. So we strongly recommend you to encrypt the server.key file" echo "with a Triple-DES cipher and a Pass Phrase." @@ -524,11 +649,17 @@ EOT fi done if [ ".$rc" = .y ]; then - $ssleay rsa -des3 \ - -in $sslkeydir/ca.key \ - -out $sslkeydir/ca.key.crypt + if [ ".$algo" = .RSA ]; then + $openssl rsa -des3 \ + -in $sslkeydir/ca.key \ + -out $sslkeydir/ca.key.crypt + else + $openssl dsa -des3 \ + -in $sslkeydir/ca.key \ + -out $sslkeydir/ca.key.crypt + fi if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to encrypt RSA private key" 1>&2 + echo "mkcert.sh:Error: Failed to encrypt $algo private key" 1>&2 exit 1 fi cp $sslkeydir/ca.key.crypt $sslkeydir/ca.key @@ -540,7 +671,7 @@ EOT fi echo "______________________________________________________________________" echo "" - echo "${T_MD}STEP 8: Enrypting RSA private key of SERVER with a pass phrase for security [server.key]${T_ME}" + echo "${T_MD}STEP 8: Enrypting $algo private key of SERVER with a pass phrase for security [server.key]${T_ME}" echo "The contents of the server.key file (the generated private key) has to be" echo "kept secret. So we strongly recommend you to encrypt the server.key file" echo "with a Triple-DES cipher and a Pass Phrase." @@ -557,46 +688,52 @@ EOT fi done if [ ".$rc" = .y ]; then - $ssleay rsa -des3 \ - -in $sslkeydir/server.key \ - -out $sslkeydir/server.key.crypt + if [ ".$algo" = .RSA ]; then + $openssl rsa -des3 \ + -in $sslkeydir/server.key \ + -out $sslkeydir/server.key.crypt + else + $openssl dsa -des3 \ + -in $sslkeydir/server.key \ + -out $sslkeydir/server.key.crypt + fi if [ $? -ne 0 ]; then - echo "mkcert.sh:Error: Failed to encrypt RSA private key" 1>&2 + echo "mkcert.sh:Error: Failed to encrypt $algo private key" 1>&2 exit 1 fi cp $sslkeydir/server.key.crypt $sslkeydir/server.key rm -f $sslkeydir/server.key.crypt - echo "Fine, you're using an encrypted private key." + echo "Fine, you're using an encrypted $algo private key." else - echo "Warning, you're using an unencrypted private key." + echo "Warning, you're using an unencrypted $algo private key." echo "Please notice this fact and do this on your own risk." fi echo "______________________________________________________________________" echo "" - echo "${T_MD}RESULT: Server and CA Certification Files${T_ME}" + echo "${T_MD}RESULT: CA and Server Certification Files${T_ME}" echo "" echo "o ${T_MD}conf/ssl.key/ca.key${T_ME}" - echo " The PEM-encoded RSA private certificate file of the CA which you can" + echo " The PEM-encoded $algo private key file of the CA which you can" echo " use to sign other servers or clients. ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}" echo "" echo "o ${T_MD}conf/ssl.crt/ca.crt${T_ME}" - echo " The PEM-encoded X.509 CA server certificate file which you use to" + echo " The PEM-encoded X.509 certificate file of the CA which you use to" echo " sign other servers or clients. When you sign clients with it (for" echo " SSL client authentication) you can configure this file with the" echo " 'SSLCACertificateFile' directive." echo "" echo "o ${T_MD}conf/ssl.key/server.key${T_ME}" - echo " The PEM-encoded RSA private certificate file which you configure" + echo " The PEM-encoded $algo private key file of the server which you configure" echo " with the 'SSLCertificateKeyFile' directive (automatically done" echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}" echo "" echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}" - echo " The PEM-encoded X.509 server certificate file which you configure" + echo " The PEM-encoded X.509 certificate file of the server which you configure" echo " with the 'SSLCertificateFile' directive (automatically done" echo " when you install via APACI)." echo "" echo "o ${T_MD}conf/ssl.csr/server.csr${T_ME}" - echo " The PEM-encoded X.509 certificate signing request file which" + echo " The PEM-encoded X.509 certificate signing request of the server file which" echo " you can send to an official Certificate Authority (CA) in order" echo " to request a real server certificate (signed by this CA instead" echo " of our own CA) which later can replace the conf/ssl.crt/server.crt" @@ -630,23 +767,28 @@ EOT key=$crt sed -e '/-----BEGIN CERTIFICATE/,/-----END CERTIFICATE/p' -e '/.*/d' \ <$crt >$sslcrtdir/server.crt - sed -e '/-----BEGIN RSA PRIVATE KEY/,/-----END RSA PRIVATE KEY/p' -e '/.*/d' \ + sed -e '/-----BEGIN ... PRIVATE KEY/,/-----END ... PRIVATE KEY/p' -e '/.*/d' \ <$key >$sslkeydir/server.key fi - $ssleay x509 -noout -in $sslcrtdir/server.crt + $openssl x509 -noout -in $sslcrtdir/server.crt if [ $? -ne 0 ]; then echo "mkcert.sh:Error: Failed to check certificate contents: $crt" 1>&2 exit 1 fi + if [ ".`grep 'PRIVATE KEY' $sslkeydir/server.key | grep RSA`" != . ]; then + algo=RSA + else + algo=DSA + fi echo "${T_MD}RESULT: Server Certification Files${T_ME}" echo "" echo "o ${T_MD}conf/ssl.key/server.key${T_ME}" - echo " The PEM-encoded RSA private certificate file which you configure" + echo " The PEM-encoded $algo private key file which you configure" echo " with the 'SSLCertificateKeyFile' directive (automatically done" echo " when you install via APACI). ${T_MD}KEEP THIS FILE PRIVATE!${T_ME}" echo "" echo "o ${T_MD}conf/ssl.crt/server.crt${T_ME}" - echo " The PEM-encoded X.509 server certificate file which you configure" + echo " The PEM-encoded X.509 certificate file which you configure" echo " with the 'SSLCertificateFile' directive (automatically done" echo " when you install via APACI)." echo "" diff --git a/usr.sbin/httpd/src/support/rotatelogs.8 b/usr.sbin/httpd/src/support/rotatelogs.8 index 2f08ce62cf4..aee02e11ecd 100644 --- a/usr.sbin/httpd/src/support/rotatelogs.8 +++ b/usr.sbin/httpd/src/support/rotatelogs.8 @@ -6,7 +6,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 diff --git a/usr.sbin/httpd/src/support/suexec.8 b/usr.sbin/httpd/src/support/suexec.8 index cc5a8db585b..801d7abce91 100644 --- a/usr.sbin/httpd/src/support/suexec.8 +++ b/usr.sbin/httpd/src/support/suexec.8 @@ -6,7 +6,7 @@ .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. +.\" 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 @@ -55,7 +55,7 @@ suexec \- Switch User For Exec .SH SYNOPSIS No synopsis for usage, because this program -is used internally by Apache only. +is used internally by Apache only. .PP .SH DESCRIPTION .B suexec diff --git a/usr.sbin/httpd/src/support/suexec.c b/usr.sbin/httpd/src/support/suexec.c index 45fdf0d021b..2ab326321f7 100644 --- a/usr.sbin/httpd/src/support/suexec.c +++ b/usr.sbin/httpd/src/support/suexec.c @@ -145,6 +145,7 @@ char *safe_env_lst[] = "SCRIPT_URL", "SERVER_ADMIN", "SERVER_NAME", + "SERVER_ADDR", "SERVER_PORT", "SERVER_PROTOCOL", "SERVER_SOFTWARE", @@ -347,6 +348,33 @@ int main(int argc, char *argv[]) actual_gname = strdup(target_gname); } +#ifdef _OSD_POSIX + /* + * Initialize BS2000 user environment + */ + { + pid_t pid; + int status; + + switch (pid = ufork(target_uname)) + { + case -1: /* Error */ + log_err("failed to setup bs2000 environment for user %s: %s\n", + target_uname, strerror(errno)); + exit(150); + case 0: /* Child */ + break; + default: /* Father */ + while (pid != waitpid(pid, &status, 0)) + ; + /* @@@ FIXME: should we deal with STOP signals as well? */ + if (WIFSIGNALED(status)) + kill (getpid(), WTERMSIG(status)); + exit(WEXITSTATUS(status)); + } + } +#endif /*_OSD_POSIX*/ + /* * Save these for later since initgroups will hose the struct */ @@ -520,7 +548,16 @@ int main(int argc, char *argv[]) /* * Execute the command, replacing our image with its own. */ +#ifdef NEED_HASHBANG_EMUL + /* We need the #! emulation when we want to execute scripts */ + { + extern char **environ; + + ap_execve(cmd, &argv[3], environ); + } +#else /*NEED_HASHBANG_EMUL*/ execv(cmd, &argv[3]); +#endif /*NEED_HASHBANG_EMUL*/ /* * (I can't help myself...sorry.) |