svn commit: r417636 - in head/www/thttpd: . files

Alexey Dokuchaev danfe at FreeBSD.org
Mon Jun 27 06:17:40 UTC 2016


Author: danfe
Date: Mon Jun 27 06:17:38 2016
New Revision: 417636
URL: https://svnweb.freebsd.org/changeset/ports/417636

Log:
  - Update `www/thttpd' to version 2.27 [1]
  - Install logfile rotation rule to prevent people running out of space
    in their /var partitions [2]
  - Provide an optional patch for IP-based authorization (.htaccess) [3]
  - While here, do not capitalize `Web' in the middle of the sentence
    inside `files/pkg-message.in' as it looks like a relic of the 1990s
  
  PR:		210040 [1]
  Submitted by:	phk [2]
  Obtained from:	http://ogris.de/thttpd/ [3]

Added:
  head/www/thttpd/files/extra-patch-htaccess   (contents, props changed)
Modified:
  head/www/thttpd/Makefile
  head/www/thttpd/distinfo
  head/www/thttpd/files/pkg-message.in
  head/www/thttpd/pkg-plist

Modified: head/www/thttpd/Makefile
==============================================================================
--- head/www/thttpd/Makefile	Mon Jun 27 05:47:39 2016	(r417635)
+++ head/www/thttpd/Makefile	Mon Jun 27 06:17:38 2016	(r417636)
@@ -2,8 +2,7 @@
 # $FreeBSD$
 
 PORTNAME=	thttpd
-PORTVERSION=	2.26
-PORTREVISION=	1
+PORTVERSION=	2.27
 CATEGORIES=	www ipv6
 MASTER_SITES=	http://www.acme.com/software/thttpd/
 
@@ -22,15 +21,17 @@ CPE_VENDOR=	acme
 
 MAKE_JOBS_UNSAFE=	yes
 
-OPTIONS_DEFINE=	SENDFILE IPREAL INDEXES
+OPTIONS_DEFINE=	SENDFILE IPREAL INDEXES HTACCESS
 OPTIONS_DEFAULT=	SENDFILE IPREAL
 
 SENDFILE_DESC=	Use sendfile(2) to serve files
 IPREAL_DESC=	Respect (pass on) "X-Forwarded-For" header
 INDEXES_DESC=	Generate index pages for directories
+HTACCESS_DESC=	IP-based authorization (.htaccess) support
 
 SENDFILE_EXTRA_PATCHES=	${FILESDIR}/extra-patch-config.h
 IPREAL_EXTRA_PATCHES=	${FILESDIR}/extra-patch-ip_real
+HTACCESS_EXTRA_PATCHES=	${FILESDIR}/extra-patch-htaccess
 
 .include <bsd.port.options.mk>
 
@@ -48,5 +49,8 @@ post-patch:
 
 post-install:
 	${INSTALL_DATA} ${WRKDIR}/thttpd.conf.sample ${STAGEDIR}${PREFIX}/etc
+	${PRINTF} "/var/log/thttpd.log\t  ${WWWOWN}:${WWWGRP}\t640 7 * @T00\
+		J\t/var/run/thttpd.pid\n" > \
+		${STAGEDIR}${PREFIX}/etc/newsyslog.conf.d/${PORTNAME}.conf
 
 .include <bsd.port.mk>

Modified: head/www/thttpd/distinfo
==============================================================================
--- head/www/thttpd/distinfo	Mon Jun 27 05:47:39 2016	(r417635)
+++ head/www/thttpd/distinfo	Mon Jun 27 06:17:38 2016	(r417636)
@@ -1,2 +1,2 @@
-SHA256 (thttpd-2.26.tar.gz) = 4693d7c421fe1bd25553a8891cbb447d2bab3e0df01c029dadd79596b9bdb4c5
-SIZE (thttpd-2.26.tar.gz) = 133224
+SHA256 (thttpd-2.27.tar.gz) = b1c4bc37ada7c39cc2bcfbf86b3bc05be91be49f8bb4f55379eaff1f66516d7a
+SIZE (thttpd-2.27.tar.gz) = 134005

Added: head/www/thttpd/files/extra-patch-htaccess
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/www/thttpd/files/extra-patch-htaccess	Mon Jun 27 06:17:38 2016	(r417636)
@@ -0,0 +1,312 @@
+--- config.h.orig	Sun Nov 30 04:40:00 2003
++++ config.h	Sat Oct 16 20:57:30 2004
+@@ -138,6 +138,17 @@
+ */
+ #define AUTH_FILE ".htpasswd"
+ 
++/* CONFIGURE: The file to use for restricting access on an ip basis. If
++** this is defined then thttpd checks for this file in the local
++** directory before every fetch. If the file exists then thttpd checks
++** whether the client's ip address is allowed to fetch this file, otherwise
++** the fetch is denied.
++**
++** If you undefine this then thttpd will not implement access checks
++** at all and will not check for access files, which saves a bit of CPU time.
++*/
++#define ACCESS_FILE ".htaccess"
++
+ /* CONFIGURE: The default character set name to use with text MIME types.
+ ** This gets substituted into the MIME types where they have a "%s".
+ **
+--- libhttpd.c.orig	Thu Dec 25 20:06:05 2003
++++ libhttpd.c	Sat Oct 16 21:14:04 2004
+@@ -136,6 +136,10 @@
+ static int auth_check( httpd_conn* hc, char* dirname  );
+ static int auth_check2( httpd_conn* hc, char* dirname  );
+ #endif /* AUTH_FILE */
++#ifdef ACCESS_FILE
++static int access_check (httpd_conn* hc, char* dirname);
++static int access_check2 (httpd_conn* hc, char* dirname);
++#endif /* ACCESS_FILE */
+ static void send_dirredirect( httpd_conn* hc );
+ static int hexit( char c );
+ static void strdecode( char* to, char* from );
+@@ -876,6 +880,139 @@
+     }
+ #endif /* ERR_DIR */
+ 
++#ifdef ACCESS_FILE
++static int err_accessfile (httpd_conn* hc, char* accesspath, char* err, FILE* f)
++{
++  fclose(f);
++
++  syslog(LOG_ERR, "%.80s access file %.80s: invalid line: %s",
++    httpd_ntoa(&hc->client_addr), accesspath, err);
++
++  httpd_send_err(hc, 403, err403title, "", ERROR_FORM(err403form, 
++    "The requested URL '%.80s' is protected by an access file, but the "
++    "access file contains garbage.\n"), hc->encodedurl);
++
++  return -1;
++}
++
++/* Returns -1 == unauthorized, 0 == no access file, 1 = authorized. */
++static int
++access_check( httpd_conn* hc, char* dirname  )
++    {
++    if ( hc->hs->global_passwd )
++	{
++	char* topdir;
++	if ( hc->hs->vhost && hc->hostdir[0] != '\0' )
++	    topdir = hc->hostdir;
++	else
++	    topdir = ".";
++	switch ( access_check2( hc, topdir ) )
++	    {
++	    case -1:
++	    return -1;
++	    case 1:
++	    return 1;
++	    }
++	}
++    return access_check2( hc, dirname );
++    }
++
++/* Returns -1 == unauthorized, 0 == no access file, 1 = authorized. */
++static int access_check2 (httpd_conn* hc, char* dirname)
++{
++  static char* accesspath;
++  static size_t maxaccesspath = 0;
++  struct in_addr ipv4_addr, ipv4_mask = { 0xffffffff };
++  FILE* fp;
++  char line[500];
++  struct stat sb;
++  char *addr, *addr1, *addr2, *mask;
++  unsigned long l;
++
++  /* Construct access filename. */
++  httpd_realloc_str(&accesspath, &maxaccesspath, strlen(dirname) + 1 +
++    sizeof(ACCESS_FILE));
++
++  my_snprintf(accesspath, maxaccesspath, "%s/%s", dirname, ACCESS_FILE);
++
++  /* Does this directory have an access file? */
++  if (lstat(accesspath, &sb) < 0)
++    /* Nope, let the request go through. */
++    return 0;
++
++  /* Open the access file. */
++  fp = fopen(accesspath, "r");
++  if (!fp) {
++    /* The file exists but we can't open it? Disallow access. */
++    syslog(LOG_ERR, "%.80s access file %.80s could not be opened - %m",
++      httpd_ntoa(&hc->client_addr), accesspath);
++
++    httpd_send_err(hc, 403, err403title, "", ERROR_FORM(err403form, 
++      "The requested URL '%.80s' is protected by an access file, but "
++      "the access file cannot be opened.\n"), hc->encodedurl);
++
++    return -1;
++  }
++
++  /* Read it. */
++  while (fgets(line, sizeof(line), fp)) {
++    /* Nuke newline. */
++    l = strlen(line);
++    if (line[l - 1] == '\n') line[l - 1] = '\0';
++
++    addr1 = strrchr(line, ' ');
++    addr2 = strrchr(line, '\t');
++    if (addr1 > addr2) addr = addr1;
++    else addr = addr2;
++    if (!addr) return err_accessfile(hc, accesspath, line, fp);
++
++    mask = strchr(++addr, '/');
++    if (mask) {
++      *mask++ = '\0';
++      if (!*mask) return err_accessfile(hc, accesspath, line, fp);
++      if (!strchr(mask, '.')) {
++        l = atol(mask);
++        if ((l < 0) || (l > 32))
++          return err_accessfile(hc, accesspath, line, fp);
++        for (l = 32 - l; l > 0; --l) ipv4_mask.s_addr ^= 1 << (l - 1);
++        ipv4_mask.s_addr = htonl(ipv4_mask.s_addr);
++      }
++      else {
++        if (!inet_aton(mask, &ipv4_mask))
++          return err_accessfile(hc, accesspath, line, fp);
++      }
++    }
++
++    if (!inet_aton(addr, &ipv4_addr))
++      return err_accessfile(hc, accesspath, line, fp);
++
++    /* Does client addr match this rule? */
++    if ((hc->client_addr.sa_in.sin_addr.s_addr & ipv4_mask.s_addr) ==
++      (ipv4_addr.s_addr & ipv4_mask.s_addr)) {
++      /* Yes. */
++      switch (line[0]) {
++        case 'd':
++        case 'D':
++	  break;
++
++        case 'a':
++        case 'A':
++          fclose(fp);
++          return 1;
++
++        default:
++          return err_accessfile(hc, accesspath, line, fp);
++      }
++    }
++  }
++
++  httpd_send_err(hc, 403, err403title, "", ERROR_FORM(err403form, 
++    "The requested URL '%.80s' is protected by an address restriction."),
++    hc->encodedurl);
++  fclose(fp);
++  return -1;
++}
++#endif /* ACCESS_FILE */
+ 
+ #ifdef AUTH_FILE
+ 
+@@ -1030,7 +1167,7 @@
+     (void) my_snprintf( authpath, maxauthpath, "%s/%s", dirname, AUTH_FILE );
+ 
+     /* Does this directory have an auth file? */
+-    if ( stat( authpath, &sb ) < 0 )
++    if ( lstat( authpath, &sb ) < 0 )
+ 	/* Nope, let the request go through. */
+ 	return 0;
+ 
+@@ -3683,6 +3820,11 @@
+ 		hc->encodedurl );
+ 	    return -1;
+ 	    }
++#ifdef ACCESS_FILE
++	/* Check access file for this directory. */
++	if ( access_check( hc, hc->expnfilename ) == -1 )
++	    return -1;
++#endif /* ACCESS_FILE */
+ #ifdef AUTH_FILE
+ 	/* Check authorization for this directory. */
+ 	if ( auth_check( hc, hc->expnfilename ) == -1 )
+@@ -3732,6 +3874,50 @@
+ 	    return -1;
+ 	    }
+ 	}
++
++#ifdef ACCESS_FILE
++    /* Check access for this directory. */
++    httpd_realloc_str( &dirname, &maxdirname, expnlen );
++    (void) strcpy( dirname, hc->expnfilename );
++    cp = strrchr( dirname, '/' );
++    if ( cp == (char*) 0 )
++	(void) strcpy( dirname, "." );
++    else
++	*cp = '\0';
++    if ( access_check( hc, dirname ) == -1 )
++	return -1;
++
++    /* Check if the filename is the ACCESS_FILE itself - that's verboten. */
++    if ( expnlen == sizeof(ACCESS_FILE) - 1 )
++	{
++	if ( strcmp( hc->expnfilename, ACCESS_FILE ) == 0 )
++	    {
++	    syslog(
++		LOG_NOTICE,
++		"%.80s URL \"%.80s\" tried to retrieve an access file",
++		httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++	    httpd_send_err(
++		hc, 403, err403title, "",
++		ERROR_FORM( err403form, "The requested URL '%.80s' is an access file, retrieving it is not permitted.\n" ),
++		hc->encodedurl );
++	    return -1;
++	    }
++	}
++    else if ( expnlen >= sizeof(ACCESS_FILE) &&
++	      strcmp( &(hc->expnfilename[expnlen - sizeof(ACCESS_FILE) + 1]), ACCESS_FILE ) == 0 &&
++	      hc->expnfilename[expnlen - sizeof(ACCESS_FILE)] == '/' )
++	{
++	syslog(
++	    LOG_NOTICE,
++	    "%.80s URL \"%.80s\" tried to retrieve an access file",
++	    httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++	httpd_send_err(
++	    hc, 403, err403title, "",
++	    ERROR_FORM( err403form, "The requested URL '%.80s' is an access file, retrieving it is not permitted.\n" ),
++	    hc->encodedurl );
++	return -1;
++	}
++#endif /* ACCESS_FILE */
+ 
+ #ifdef AUTH_FILE
+     /* Check authorization for this directory. */
+--- thttpd.8.orig	Sat Nov 15 00:43:51 2003
++++ thttpd.8	Sat Oct 16 21:19:13 2004
+@@ -100,14 +100,15 @@
+ and the config.h option is ALWAYS_VHOST.
+ .TP
+ .B -g
+-Use a global passwd file.
++Use global passwd/access files.
+ This means that every file in the entire document tree is protected by
+-the single .htpasswd file at the top of the tree.
+-Otherwise the semantics of the .htpasswd file are the same.
+-If this option is set but there is no .htpasswd file in
++a single .htpasswd or .htaccess file at the top of the tree.
++Otherwise the semantics of the .htpasswd and .htaccess files are the same.
++If this option is set but there are no .htpasswd and no .htaccess files in
+ the top-level directory, then thttpd proceeds as if the option was
+-not set - first looking for a local .htpasswd file, and if that doesn't
+-exist either then serving the file without any password.
++not set - first looking for local .htpasswd and .htaccess files, and if that doesn't
++exist either then serving the file without any password and without any access
++restriction.
+ If -g is the compiled-in default, then -nog disables it.
+ The config-file option names for this flag are "globalpasswd" and
+ "noglobalpasswd",
+@@ -274,6 +275,42 @@
+ modify .htpasswd files.
+ .PP
+ Relevant config.h option: AUTH_FILE
++.SH "ACCESS RESTRICTION"
++.PP
++Access restriction is available as an option at compile time.
++If enabled, it uses an access file in the directory to be protected,
++called .htaccess by default.
++This file consists of a rule and a host address or a network range per
++line.
++Valid rules are:
++.TP
++.B allow from
++The following host address or network range is allowed to access the requested
++directory and its files.
++.TP
++.B deny from
++The following host address or network range is not allowed to access the
++requested directory and its files.
++.PP
++The protection does not carry over to subdirectories.
++There are three ways to specify a valid host address or network range:
++.TP
++.B IPv4 host address
++eg. 10.2.3.4
++.TP
++.B IPv4 network with subnet mask
++eg. 10.0.0.0/255.255.0.0
++.TP
++.B IPv4 network using CIDR notation
++eg. 10.0.0.0/16
++.PP
++Note that rules are processed in the same order as they are listed in the
++access file and that the first rule which matches the client's address is
++applied (there is no order clause).
++So if there is no allow from 0.0.0.0/0 at the end of the file the default
++action is to deny access.
++.PP
++Relevant config.h option: ACCESS_FILE
+ .SH "THROTTLING"
+ .PP
+ The throttle file lets you set maximum byte rates on URLs or URL groups.

Modified: head/www/thttpd/files/pkg-message.in
==============================================================================
--- head/www/thttpd/files/pkg-message.in	Mon Jun 27 05:47:39 2016	(r417635)
+++ head/www/thttpd/files/pkg-message.in	Mon Jun 27 06:17:38 2016	(r417636)
@@ -1,5 +1,5 @@
 -----------------------------------------------------------------
-If you want users to be able to create their own Web
+If you want users to be able to create their own web
 subdirectories off of the main web directory, you need to:
 
   1. Add a group for www admins (or use "%%WWWGRP%%")

Modified: head/www/thttpd/pkg-plist
==============================================================================
--- head/www/thttpd/pkg-plist	Mon Jun 27 05:47:39 2016	(r417635)
+++ head/www/thttpd/pkg-plist	Mon Jun 27 06:17:38 2016	(r417636)
@@ -1,3 +1,4 @@
+etc/newsyslog.conf.d/thttpd.conf
 @sample etc/thttpd.conf.sample
 man/man1/makeweb.1.gz
 man/man1/thtpasswd.1.gz


More information about the svn-ports-head mailing list