From f8407b5f7bcee62fb4ae02bdc06420ea9863f868 Mon Sep 17 00:00:00 2001
From: gary-wzl77 <gary.wang@canonical.com>
Date: Sat, 25 Feb 2017 15:02:47 +0800
Subject: [PATCH] Enable tinyproxy packaging as a snap.

This PR enable tinyproxy to package as a snap. Also added conditional
for snap packaging by testing "--enable-snap". The reason here for
'--enable-snap' is that all services run as root thanks to confinement
in snap world and regarding system call(setuid, setgid) will trigger
apparmor "DENIED" error when running tinyproxy snap in confined mode.
Please refer to syslog here http://paste.ubuntu.com/24063282/.
---
 README.md                                     |  32 ++
 configure.ac                                  |  10 +
 snap/setup/gui/icon.png                       | Bin 0 -> 16238 bytes
 snap/snapcraft.yaml                           |  50 +++
 .../tinyproxy/conf/tinyproxy.conf.template    | 330 ++++++++++++++++++
 snap/src/tinyproxy/script/run-tinyproxy       |  17 +
 snap/src/tinyproxy/script/settings            |  24 ++
 src/main.c                                    |   2 +
 8 files changed, 465 insertions(+)
 create mode 100755 snap/setup/gui/icon.png
 create mode 100644 snap/snapcraft.yaml
 create mode 100644 snap/src/tinyproxy/conf/tinyproxy.conf.template
 create mode 100755 snap/src/tinyproxy/script/run-tinyproxy
 create mode 100755 snap/src/tinyproxy/script/settings

diff --git a/README.md b/README.md
index 2cb8d59..ba22c6e 100644
--- a/README.md
+++ b/README.md
@@ -65,9 +65,41 @@ Enable reverse proxying.
 - `--with-stathost=HOST`: 
 Set the default name of the stats host.
 
+- `--enable-snap`:
+Enable snap packaging and running tinyproxy in snap world.
+
 For more information about the build system, read the INSTALL file
 that is generated by `autogen.sh` and comes with the release tar ball.
 
+## Snap
+
+If you would like to build tinyproxy as a snap package, please make sure
+you have snapd and snapcraft packages installed firstly.
+
+```
+sudo apt-get install snapd snapcraft
+sudo snap install core
+```
+
+Then run the following command to create a snap package.
+
+```
+cd snap && snapcraft
+```
+
+After it's done, you can simply run the following command to install it
+locally.
+
+```
+sudo snap install --dangerous tinyproxy-snap_[VER]_[ARCH].snap
+```
+
+Also you can install tinyproxy from the store by running the following
+command.
+
+```
+sudo snap install tinyproxy
+```
 
 
 ## Support
diff --git a/configure.ac b/configure.ac
index 3990c2f..4248160 100644
--- a/configure.ac
+++ b/configure.ac
@@ -131,6 +131,16 @@ if test x"$transparent_enabled" = x"yes"; then
    AC_DEFINE(TRANSPARENT_PROXY)
 fi
 
+dnl Include support for packaging and running tinyproxy in snap world.
+AH_TEMPLATE([SNAP_SUPPORT],
+            [Include support for snap package.])
+TP_ARG_ENABLE(snap,
+              [Enable snap packaging (default is NO)],
+              no)
+if test x"$snap_enabled" = x"yes"; then
+    AC_DEFINE(SNAP_SUPPORT)
+fi
+
 # This is required to build test programs below
 AC_PROG_CC
 
diff --git a/snap/setup/gui/icon.png b/snap/setup/gui/icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..ce87640184a4d74b4e8e4c2b2ea626ba31b98940
GIT binary patch
literal 16238
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

literal 0
HcmV?d00001

diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
new file mode 100644
index 0000000..fba9b57
--- /dev/null
+++ b/snap/snapcraft.yaml
@@ -0,0 +1,50 @@
+name: tinyproxy-snap
+version: '0.2'
+summary: a light-weight HTTP(S) proxy daemon for POSIX operating systems.
+description: |
+  Tinyproxy is a small, efficient HTTP/SSL proxy daemon released under the GNU General Public License. 
+  Tinyproxy is very useful in a small network setting, where a larger proxy would either be too resource intensive, or a security risk.
+
+  usage: $ sudo snap set tinyproxy port=9876
+         $ sudo snap disable tinyproxy
+         $ sudo snap enable tinyproxy
+  supported parameters:
+    - port: The socket addresses where tinyproxy will listen for HTTP/HTTPS client requests. The default value is '8888'
+    - max-clients: This is the absolute highest number of threads which will be created. The default value is 100.
+    - start-servers: The number of servers to start initially. The default value is 10.
+
+grade: stable
+confinement: strict
+
+apps:
+  tinyproxy:
+    command: run-tinyproxy start
+    daemon: simple
+    plugs: [ network, network-bind ]
+
+parts:
+  tinyproxy:
+    plugin: autotools
+    source: https://github.com/tinyproxy/tinyproxy.git
+    source-type: git
+    source-tag: 1.8.4
+    configflags:
+      - --enable-xtinyproxy 
+      - --enable-filter 
+      - --enable-upstream 
+      - --enable-reverse 
+      - --enable-transparent
+      - --enable-snap
+    build-packages:
+      - asciidoc 
+      - xsltproc 
+    organize:
+      sbin: bin 
+    stage:
+      - -etc
+  tinyproxy-customized:
+    plugin: dump
+    organize:
+      src/tinyproxy/script/*: bin/
+      src/tinyproxy/conf/tinyproxy.conf.template: etc/
+      src/tinyproxy/conf/configure: meta/hooks/configure
diff --git a/snap/src/tinyproxy/conf/tinyproxy.conf.template b/snap/src/tinyproxy/conf/tinyproxy.conf.template
new file mode 100644
index 0000000..c07811d
--- /dev/null
+++ b/snap/src/tinyproxy/conf/tinyproxy.conf.template
@@ -0,0 +1,330 @@
+##
+## tinyproxy.conf -- tinyproxy daemon configuration file
+##
+## This example tinyproxy.conf file contains example settings
+## with explanations in comments. For decriptions of all
+## parameters, see the tinproxy.conf(5) manual page.
+##
+
+#
+# User/Group: This allows you to set the user and group that will be
+# used for tinyproxy after the initial binding to the port has been done
+# as the root user. Either the user or group name or the UID or GID
+# number may be used.
+#
+User root
+Group root
+
+#
+# Port: Specify the port which tinyproxy will listen on.  Please note
+# that should you choose to run on a port lower than 1024 you will need
+# to start tinyproxy using root.
+#
+Port 8888
+
+#
+# Listen: If you have multiple interfaces this allows you to bind to
+# only one. If this is commented out, tinyproxy will bind to all
+# interfaces present.
+#
+#Listen 192.168.0.1
+
+#
+# Bind: This allows you to specify which interface will be used for
+# outgoing connections.  This is useful for multi-home'd machines where
+# you want all traffic to appear outgoing from one particular interface.
+#
+#Bind 192.168.0.1
+
+#
+# BindSame: If enabled, tinyproxy will bind the outgoing connection to the
+# ip address of the incoming connection.
+#
+#BindSame yes
+
+#
+# Timeout: The maximum number of seconds of inactivity a connection is
+# allowed to have before it is closed by tinyproxy.
+#
+Timeout 600
+
+#
+# ErrorFile: Defines the HTML file to send when a given HTTP error
+# occurs.  You will probably need to customize the location to your
+# particular install.  The usual locations to check are:
+#   /usr/local/share/tinyproxy
+#   /usr/share/tinyproxy
+#   /etc/tinyproxy
+#
+#ErrorFile 404 "@pkgdatadir@/404.html"
+#ErrorFile 400 "@pkgdatadir@/400.html"
+#ErrorFile 503 "@pkgdatadir@/503.html"
+#ErrorFile 403 "@pkgdatadir@/403.html"
+#ErrorFile 408 "@pkgdatadir@/408.html"
+
+#
+# DefaultErrorFile: The HTML file that gets sent if there is no
+# HTML file defined with an ErrorFile keyword for the HTTP error
+# that has occured.
+#
+DefaultErrorFile "${SNAP}/share/tinyproxy/default.html"
+
+#
+# StatHost: This configures the host name or IP address that is treated
+# as the stat host: Whenever a request for this host is received,
+# Tinyproxy will return an internal statistics page instead of
+# forwarding the request to that host.  The default value of StatHost is
+# @TINYPROXY_STATHOST@.
+#
+#StatHost "@TINYPROXY_STATHOST@"
+#
+
+#
+# StatFile: The HTML file that gets sent when a request is made
+# for the stathost.  If this file doesn't exist a basic page is
+# hardcoded in tinyproxy.
+#
+StatFile "${SNAP}/share/tinyproxy/stats.html"
+
+#
+# LogFile: Allows you to specify the location where information should
+# be logged to.  If you would prefer to log to syslog, then disable this
+# and enable the Syslog directive.  These directives are mutually
+# exclusive.
+#
+LogFile "${SNAP_DATA}/var/log/tinyproxy/tinyproxy.log"
+
+#
+# Syslog: Tell tinyproxy to use syslog instead of a logfile.  This
+# option must not be enabled if the Logfile directive is being used.
+# These two directives are mutually exclusive.
+#
+#Syslog On
+
+#
+# LogLevel: 
+#
+# Set the logging level. Allowed settings are:
+#	Critical	(least verbose)
+#	Error
+#	Warning
+#	Notice
+#	Connect		(to log connections without Info's noise)
+#	Info		(most verbose)
+#
+# The LogLevel logs from the set level and above. For example, if the
+# LogLevel was set to Warning, then all log messages from Warning to
+# Critical would be output, but Notice and below would be suppressed.
+#
+LogLevel Info
+
+#
+# PidFile: Write the PID of the main tinyproxy thread to this file so it
+# can be used for signalling purposes.
+#
+PidFile "${SNAP_DATA}/var/run/tinyproxy/tinyproxy.pid"
+
+#
+# XTinyproxy: Tell Tinyproxy to include the X-Tinyproxy header, which
+# contains the client's IP address.
+#
+#XTinyproxy Yes
+
+#
+# Upstream:
+#
+# Turns on upstream proxy support.
+#
+# The upstream rules allow you to selectively route upstream connections
+# based on the host/domain of the site being accessed.
+#
+# For example:
+#  # connection to test domain goes through testproxy
+#  upstream testproxy:8008 ".test.domain.invalid"
+#  upstream testproxy:8008 ".our_testbed.example.com"
+#  upstream testproxy:8008 "192.168.128.0/255.255.254.0"
+#
+#  # no upstream proxy for internal websites and unqualified hosts
+#  no upstream ".internal.example.com"
+#  no upstream "www.example.com"
+#  no upstream "10.0.0.0/8"
+#  no upstream "192.168.0.0/255.255.254.0"
+#  no upstream "."
+#
+#  # connection to these boxes go through their DMZ firewalls
+#  upstream cust1_firewall:8008 "testbed_for_cust1"
+#  upstream cust2_firewall:8008 "testbed_for_cust2"
+#
+#  # default upstream is internet firewall
+#  upstream firewall.internal.example.com:80
+#
+# The LAST matching rule wins the route decision.  As you can see, you
+# can use a host, or a domain:
+#  name     matches host exactly
+#  .name    matches any host in domain "name"
+#  .        matches any host with no domain (in 'empty' domain)
+#  IP/bits  matches network/mask
+#  IP/mask  matches network/mask
+#
+#Upstream some.remote.proxy:port
+
+#
+# MaxClients: This is the absolute highest number of threads which will
+# be created. In other words, only MaxClients number of clients can be
+# connected at the same time.
+#
+MaxClients 100
+
+#
+# MinSpareServers/MaxSpareServers: These settings set the upper and
+# lower limit for the number of spare servers which should be available.
+#
+# If the number of spare servers falls below MinSpareServers then new
+# server processes will be spawned.  If the number of servers exceeds
+# MaxSpareServers then the extras will be killed off.
+#
+MinSpareServers 5
+MaxSpareServers 20
+
+#
+# StartServers: The number of servers to start initially.
+#
+StartServers 10
+
+#
+# MaxRequestsPerChild: The number of connections a thread will handle
+# before it is killed. In practise this should be set to 0, which
+# disables thread reaping. If you do notice problems with memory
+# leakage, then set this to something like 10000.
+#
+MaxRequestsPerChild 0
+
+#
+# Allow: Customization of authorization controls. If there are any
+# access control keywords then the default action is to DENY. Otherwise,
+# the default action is ALLOW.
+#
+# The order of the controls are important. All incoming connections are
+# tested against the controls based on order.
+#
+#Allow 127.0.0.1
+
+#
+# AddHeader: Adds the specified headers to outgoing HTTP requests that
+# Tinyproxy makes. Note that this option will not work for HTTPS
+# traffic, as Tinyproxy has no control over what headers are exchanged.
+#
+#AddHeader "X-My-Header" "Powered by Tinyproxy"
+
+#
+# ViaProxyName: The "Via" header is required by the HTTP RFC, but using
+# the real host name is a security concern.  If the following directive
+# is enabled, the string supplied will be used as the host name in the
+# Via header; otherwise, the server's host name will be used.
+#
+ViaProxyName "tinyproxy"
+
+#
+# DisableViaHeader: When this is set to yes, Tinyproxy does NOT add
+# the Via header to the requests. This virtually puts Tinyproxy into
+# stealth mode. Note that RFC 2616 requires proxies to set the Via
+# header, so by enabling this option, you break compliance.
+# Don't disable the Via header unless you know what you are doing...
+#
+#DisableViaHeader Yes
+
+#
+# Filter: This allows you to specify the location of the filter file.
+#
+#Filter "@sysconfdir@/filter"
+
+#
+# FilterURLs: Filter based on URLs rather than domains.
+#
+#FilterURLs On
+
+#
+# FilterExtended: Use POSIX Extended regular expressions rather than
+# basic.
+#
+#FilterExtended On
+
+#
+# FilterCaseSensitive: Use case sensitive regular expressions.
+#
+#FilterCaseSensitive On
+
+#
+# FilterDefaultDeny: Change the default policy of the filtering system.
+# If this directive is commented out, or is set to "No" then the default
+# policy is to allow everything which is not specifically denied by the
+# filter file.
+#
+# However, by setting this directive to "Yes" the default policy becomes
+# to deny everything which is _not_ specifically allowed by the filter
+# file.
+#
+#FilterDefaultDeny Yes
+
+#
+# Anonymous: If an Anonymous keyword is present, then anonymous proxying
+# is enabled.  The headers listed are allowed through, while all others
+# are denied. If no Anonymous keyword is present, then all headers are
+# allowed through.  You must include quotes around the headers.
+#
+# Most sites require cookies to be enabled for them to work correctly, so
+# you will need to allow Cookies through if you access those sites.
+#
+#Anonymous "Host"
+#Anonymous "Authorization"
+#Anonymous "Cookie"
+
+#
+# ConnectPort: This is a list of ports allowed by tinyproxy when the
+# CONNECT method is used.  To disable the CONNECT method altogether, set
+# the value to 0.  If no ConnectPort line is found, all ports are
+# allowed (which is not very secure.)
+#
+# The following two ports are used by SSL.
+#
+ConnectPort 443
+ConnectPort 563
+
+#
+# Configure one or more ReversePath directives to enable reverse proxy
+# support. With reverse proxying it's possible to make a number of
+# sites appear as if they were part of a single site.
+#
+# If you uncomment the following two directives and run tinyproxy
+# on your own computer at port 8888, you can access Google using
+# http://localhost:8888/google/ and Wired News using
+# http://localhost:8888/wired/news/. Neither will actually work
+# until you uncomment ReverseMagic as they use absolute linking.
+#
+#ReversePath "/google/"	"http://www.google.com/"
+#ReversePath "/wired/"	"http://www.wired.com/"
+
+#
+# When using tinyproxy as a reverse proxy, it is STRONGLY recommended
+# that the normal proxy is turned off by uncommenting the next directive.
+#
+#ReverseOnly Yes
+
+#
+# Use a cookie to track reverse proxy mappings. If you need to reverse
+# proxy sites which have absolute links you must uncomment this.
+#
+#ReverseMagic Yes
+
+#
+# The URL that's used to access this reverse proxy. The URL is used to
+# rewrite HTTP redirects so that they won't escape the proxy. If you
+# have a chain of reverse proxies, you'll need to put the outermost
+# URL here (the address which the end user types into his/her browser).
+#
+# If not set then no rewriting occurs.
+#
+#ReverseBaseURL "http://localhost:8888/"
+
+
+
diff --git a/snap/src/tinyproxy/script/run-tinyproxy b/snap/src/tinyproxy/script/run-tinyproxy
new file mode 100755
index 0000000..e4a5f2e
--- /dev/null
+++ b/snap/src/tinyproxy/script/run-tinyproxy
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+test -d ${SNAP_DATA}/etc || mkdir -p ${SNAP_DATA}/etc
+test -d ${SNAP_DATA}/var/run/tinyproxy || mkdir -p ${SNAP_DATA}/var/run/tinyproxy
+test -d ${SNAP_DATA}/var/log/tinyproxy || mkdir -p ${SNAP_DATA}/var/log/tinyproxy
+test -f ${SNAP_DATA}/etc/tinyproxy.conf || sed -e "s|\${SNAP_DATA}|$SNAP_DATA|" ${SNAP}/etc/tinyproxy.conf.template > ${SNAP_DATA}/etc/tinyproxy.conf.ori && sed -e "s|\${SNAP}|$SNAP|" ${SNAP_DATA}/etc/tinyproxy.conf.ori > ${SNAP_DATA}/etc/tinyproxy.conf
+
+#waiting custom_config file is generated.
+#That's sth hooks feature neeeds.
+while [ ! -f "$SNAP_DATA/custom_config" ]; do
+    sleep 1
+    echo "waiting for custom config file generated."
+done
+
+source ${SNAP}/bin/settings
+
+tinyproxy -d -c ${SNAP_DATA}/etc/tinyproxy.conf
diff --git a/snap/src/tinyproxy/script/settings b/snap/src/tinyproxy/script/settings
new file mode 100755
index 0000000..9f0b93b
--- /dev/null
+++ b/snap/src/tinyproxy/script/settings
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+source $SNAP_DATA/custom_config
+
+tinyproxy_conf="${SNAP_DATA}/etc/tinyproxy.conf"
+
+params=("Port" "MaxClients" "StartServers")
+line_number=(23 176 192)
+length=${#params[@]}
+
+#sed -i in-place option is not available by default on some other distro.
+modify() {
+    sed -u "$1" "$2" > "$2".bak && mv "$2".bak "$2"
+}
+
+for ((i = 0; i < $length; i++))
+do
+  if [ ! -z "${!params[i]}" ]; then
+      echo "customized config: ${params[i]}=${!params[i]}"
+      modify "${line_number[i]}d" $tinyproxy_conf
+      #space sensitive
+      modify "${line_number[i]}i${params[i]} ${!params[i]}" $tinyproxy_conf
+  fi
+done
diff --git a/src/main.c b/src/main.c
index ae2a3a8..7f81f3e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -436,12 +436,14 @@ main (int argc, char **argv)
                 exit (EX_OSERR);
         }
 
+#ifndef SNAP_SUPPORT
         /* Switch to a different user if we're running as root */
         if (geteuid () == 0)
                 change_user (argv[0]);
         else
                 log_message (LOG_WARNING,
                              "Not running as root, so not changing UID/GID.");
+#endif
 
         /* Create log file after we drop privileges */
         if (setup_logging ()) {