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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
Description: Add --chroot and --user options
This allows chrooting the server, and running it with a different uid
& gid.
Origin: upstream
Bug-Debian: https://bugs.debian.org/477401
Forwarded: not-needed
---
Origin: <vendor|upstream|other>, <url of original patch>
--- httptunnel-3.3+dfsg.orig/ChangeLog
+++ httptunnel-3.3+dfsg/ChangeLog
@@ -1,3 +1,9 @@
+2003-01-10 Lars Brinkhoff <lars@nocrew.org>
+
+ From Marco Michelino <michelinux@tin.it>:
+ * hts.c (usage, parse_arguments, main): add --chroot and --user
+ options.
+
2001-06-12 lars brinkhoff <lars@nocrew.org>
* tunnel.h: Improved documentation for tunnel programming
--- httptunnel-3.3+dfsg.orig/hts.c
+++ httptunnel-3.3+dfsg/hts.c
@@ -13,6 +13,10 @@ two-way data path tunneled in HTTP reque
#include <signal.h>
#include <sys/poll_.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <time.h>
#include "common.h"
@@ -31,6 +35,8 @@ typedef struct
int strict_content_length;
int keep_alive;
int max_connection_age;
+ char *root;
+ char *user;
} Arguments;
int debug_level = 0;
@@ -61,9 +67,11 @@ usage (FILE *f, const char *me)
#endif
" -M, --max-connection-age SEC maximum time a connection will stay\n"
" open is SEC seconds (default is %d)\n"
+" -r, --chroot ROOT change root to ROOT\n"
" -s, --stdin-stdout use stdin/stdout for communication\n"
" (implies --no-daemon)\n"
" -S, --strict-content-length always write Content-Length bytes in requests\n"
+" -u, --user USER change user to USER\n"
" -V, --version output version information and exit\n"
" -w, --no-daemon don't fork into the background\n"
" -p, --pid-file LOCATION write a PID file to LOCATION\n"
@@ -93,6 +101,8 @@ parse_arguments (int argc, char **argv,
arg->strict_content_length = FALSE;
arg->keep_alive = DEFAULT_KEEP_ALIVE;
arg->max_connection_age = DEFAULT_CONNECTION_MAX_TIME;
+ arg->user = NULL;
+ arg->root = NULL;
for (;;)
{
@@ -100,24 +110,26 @@ parse_arguments (int argc, char **argv,
static struct option long_options[] =
{
{ "help", no_argument, 0, 'h' },
- { "stdin-stdout", no_argument, 0, 's' },
- { "strict-content-length", no_argument, 0, 'S' },
{ "version", no_argument, 0, 'V' },
{ "no-daemon", no_argument, 0, 'w' },
+ { "user", required_argument, 0, 'u' },
#ifdef DEBUG_MODE
{ "debug", required_argument, 0, 'D' },
{ "logfile", required_argument, 0, 'l' },
#endif
+ { "chroot", required_argument, 0, 'r' },
+ { "stdin-stdout", no_argument, 0, 's' },
{ "device", required_argument, 0, 'd' },
{ "pid-file", required_argument, 0, 'p' },
{ "keep-alive", required_argument, 0, 'k' },
{ "forward-port", required_argument, 0, 'F' },
{ "content-length", required_argument, 0, 'c' },
+ { "strict-content-length", no_argument, 0, 'S' },
{ "max-connection-age", required_argument, 0, 'M' },
{ 0, 0, 0, 0 }
};
- static const char *short_options = "c:d:F:hk:M:p:sSVw"
+ static const char *short_options = "c:d:F:hk:M:p:sSVwu:r:"
#ifdef DEBUG_MODE
"D:l:"
#endif
@@ -187,6 +199,10 @@ parse_arguments (int argc, char **argv,
arg->max_connection_age = atoi (optarg);
break;
+ case 'r':
+ arg->root = optarg;
+ break;
+
case 's':
arg->use_std=TRUE;
arg->use_daemon=FALSE;
@@ -196,6 +212,10 @@ parse_arguments (int argc, char **argv,
arg->strict_content_length = TRUE;
break;
+ case 'u':
+ arg->user = optarg;
+ break;
+
case 'V':
printf ("hts (%s) %s\n", PACKAGE, VERSION);
exit (0);
@@ -278,6 +298,8 @@ main (int argc, char **argv)
Arguments arg;
Tunnel *tunnel;
FILE *pid_file;
+ uid_t uid;
+ gid_t gid;
parse_arguments (argc, argv, &arg);
@@ -307,11 +329,13 @@ main (int argc, char **argv)
log_notice (" debug_level = %d", debug_level);
log_notice (" pid_filename = %s",
arg.pid_filename ? arg.pid_filename : "(null)");
+ log_notice (" chroot = %s", arg.root ? arg.root : "(null)");
+ log_notice (" user = %s", arg.user ? arg.user : "(null)");
tunnel = tunnel_new_server (arg.host, arg.port, arg.content_length);
if (tunnel == NULL)
{
- log_error ("couldn't create tunnel", argv[0]);
+ log_error ("couldn't create tunnel");
log_exit (1);
}
@@ -353,6 +377,65 @@ main (int argc, char **argv)
}
}
+ /* If requested to change user, get new uid and gid before chroot so we */
+ /* don't need /etc/passwd & company in the chroot jail */
+ if (arg.user)
+ {
+ struct passwd *pwd = getpwnam (arg.user);
+ if (pwd == NULL)
+ {
+ log_error ("couldn't find user");
+ log_exit (1);
+ }
+ uid = pwd->pw_uid;
+ gid = pwd->pw_gid;
+ if (setgroups (0, (const gid_t *)0) < 0)
+ {
+ log_error ("couldn't drop supplementary groups privileges");
+ log_exit (1);
+ }
+ if (setgid (gid) < 0)
+ {
+ log_error ("couldn't change primary group");
+ log_exit (1);
+ }
+ if (initgroups (arg.user, gid) < 0)
+ {
+ /* non critical error */
+ log_error ("couldn't add supplementary groups");
+ }
+ }
+
+ /* Change root if requested */
+ if (arg.root)
+ {
+ if (chroot (arg.root) < 0)
+ {
+ log_error ("couldn't change root");
+ log_exit (1);
+ }
+ if (chdir ("/") < 0)
+ {
+ log_error ("couldn't change dir to new root");
+ log_exit (1);
+ }
+ if (fclose (stdin) || fclose (stdout) || fclose (stderr))
+ {
+ log_error ("couldn't close stdin, stdout and/or stderr");
+ log_exit (1);
+ }
+ }
+
+ /* Change user if requested */
+ if (arg.user)
+ {
+ if (setuid (uid) < 0)
+ {
+ log_error ("couldn't change user");
+ log_exit (1);
+ }
+ }
+
for (;;)
{
time_t last_tunnel_write;
|