git ssb

0+

cel / sslh



Commit d0c0689e3ce9f57db360d5d1206090211ddd92c5

v1.1

Yves Rutschle committed on 7/10/2013, 9:06:51 PM
Parent: d7e9cbb655626718177c36988d3b63a579dbfb66

Files changed

sslh.cchanged
sslh.cView
@@ -27,11 +27,24 @@
2727
2828 LynxOS:
2929 gcc -o tcproxy tcproxy.c -lnetinet
3030
31+HISTORY
32+
33+v1.1: 21MAY2007
34+ Making sslhc more like a real daemon:
35+ * If $PIDFILE is defined, write first PID to it upon startup
36+ * Fork at startup (detach from terminal)
37+ (thanks to http://www.enderunix.org/docs/eng/daemon.php -- good checklist)
38+ * Less memory usage (?)
39+
40+v1.0:
41+ * Basic functionality: privilege dropping, target hostnames and ports
42+ configurable.
43+
3144 */
3245
33-#define VERSION "1.0"
46+#define VERSION "1.1"
3447
3548 #include <sys/types.h>
3649 #include <fcntl.h>
3750 #include <string.h>
@@ -39,8 +52,9 @@
3952 #include <stdlib.h>
4053 #include <stdio.h>
4154 #include <signal.h>
4255 #include <sys/socket.h>
56+#include <sys/wait.h>
4357 #include <netinet/in.h>
4458 #include <arpa/inet.h>
4559 #include <netdb.h>
4660 #include <pwd.h>
@@ -50,10 +64,13 @@
5064 perror(str); \
5165 exit(1); \
5266 }
5367
54-#define USAGE_STRING "usage:\n\tsslh [-t <timeout>] -u <username> -p <listenport> -s [sshhost:]port -l [sslhost:]port [-v]\n"
68+#define USAGE_STRING "usage:\n" \
69+"\texport PIDFILE=/var/run/sslhc.pid" \
70+"\tsslh [-t <timeout>] -u <username> -p <listenport> -s [sshhost:]port -l [sslhost:]port [-v]\n"
5571
72+int verbose = 0; /* That's really quite global */
5673
5774 /* Starts a listening socket on specified port.
5875 Returns file descriptor
5976 */
@@ -127,41 +144,40 @@
127144
128145 if (FD_ISSET(fd1, &fds)) {
129146 res = fd2fd(fd2, fd1);
130147 if (!res) {
131- printf("client socket closed\n");
148+ if (verbose) fprintf(stderr, "client socket closed\n");
132149 return res;
133150 }
134151 }
135152
136153 if (FD_ISSET(fd2, &fds)) {
137154 res = fd2fd(fd1, fd2);
138155 if (!res) {
139- printf("server socket closed\n");
156+ if (verbose) fprintf(stderr, "server socket closed\n");
140157 return res;
141158 }
142159 }
143160 }
144161 }
145162
146-/* returns a static string that prints the IP and port of the sockaddr */
147-char* get_addr(struct sockaddr* s)
163+/* returns a string that prints the IP and port of the sockaddr */
164+char* sprintaddr(char* buf, size_t size, struct sockaddr* s)
148165 {
149166 char addr_str[1024];
150- static char addr_name[1024];
151167
152168 inet_ntop(AF_INET, &((struct sockaddr_in*)s)->sin_addr, addr_str, sizeof(addr_str));
153- snprintf(addr_name, sizeof(addr_name), "%s:%d", addr_str,ntohs(((struct sockaddr_in*)s)->sin_port));
154- return addr_name;
169+ snprintf(buf, size, "%s:%d", addr_str, ntohs(((struct sockaddr_in*)s)->sin_port));
170+ return buf;
155171 }
156172
157173 /* turns a "hostname:port" string into a struct sockaddr;
158174 sock: socket address to which to copy the addr
159175 fullname: input string -- it gets clobbered
160176 serv: default service/port
161177 (defaults don't work yet)
162178 */
163-int resolve_name(struct sockaddr *sock, char* fullname, int port) {
179+void resolve_name(struct sockaddr *sock, char* fullname, int port) {
164180 struct addrinfo *addr, hint;
165181 char *serv, *host;
166182 int res;
167183
@@ -194,13 +210,12 @@
194210 memcpy(sock, addr->ai_addr, sizeof(*sock));
195211 }
196212
197213 /*
198- * Settings that depend on the command line.
214+ * Settings that depend on the command line. That's less global than verbose * :-)
199215 * They're set in main(), but also used in start_shoveler(), and it'd be heavy-handed
200216 * to pass it all as parameters
201217 */
202-int verbose = 0;
203218 int timeout = 2;
204219 int listen_port = 443;
205220 struct sockaddr addr_ssl, addr_ssh;
206221
@@ -288,21 +303,55 @@
288303 setuid(pw->pw_uid);
289304 CHECK_RES_DIE(res, "setuid");
290305 }
291306
307+/* Writes my PID if $PIDFILE is defined */
308+void write_pid_file(void)
309+{
310+ char *pidfile = getenv("PIDFILE");
311+ FILE *f;
312+
313+ if (!pidfile)
314+ return;
315+
316+ f = fopen(pidfile, "w");
317+ if (!f) {
318+ perror(pidfile);
319+ exit(1);
320+ }
321+
322+ fprintf(f, "%d\n", getpid());
323+ fclose(f);
324+}
325+
326+void printsettings(void)
327+{
328+ char buf[64];
329+
330+ fprintf(
331+ stderr,
332+ "SSL addr: %s (after timeout %ds)\n",
333+ sprintaddr(buf, sizeof(buf), &addr_ssl),
334+ timeout
335+ );
336+ fprintf(stderr, "SSH addr: %s\n", sprintaddr(buf, sizeof(buf), &addr_ssh));
337+ fprintf(stderr, "listening on port %d\n", listen_port);
338+}
339+
292340 int main(int argc, char *argv[])
293341 {
294342
295343 extern char *optarg;
296344 extern int optind;
297345 int c, res;
298346
299- int in_socket, out_socket, listen_socket;
347+ int in_socket, listen_socket;
300348
301349 /* Init defaults */
302350 char *user_name = "nobody";
303- char ssl_str[] = "localhost:443"; /* need to copy -- Linux doesn't let write to BSS? */
351+ char ssl_str[] = "localhost:443";
304352 char ssh_str[] = "localhost:22";
353+
305354 resolve_name(&addr_ssl, ssl_str, 443);
306355 resolve_name(&addr_ssh, ssh_str, 22);
307356
308357 while ((c = getopt(argc, argv, "t:l:s:p:vu:")) != EOF) {
@@ -337,26 +386,30 @@
337386 exit(2);
338387 }
339388 }
340389
341- if (verbose) {
342- fprintf(stderr, "SSL addr: %s (after timeout %ds)\n", get_addr(&addr_ssl), timeout);
343- fprintf(stderr, "SSH addr: %s\n", get_addr(&addr_ssh));
344- fprintf(stderr, "listening on port %d\n", listen_port);
345- }
390+ if (verbose)
391+ printsettings();
346392
347-
348393 setup_signals();
349394
350395 listen_socket = start_listen_socket(listen_port);
351396
397+ if (fork() > 0) exit(0); /* Detach */
398+
399+ write_pid_file();
400+
352401 drop_privileges(user_name);
353402
403+ /* New session -- become group leader */
404+ res = setsid();
405+ CHECK_RES_DIE(res, "setsid: already process leader");
406+
354407 /* Main server loop: accept connections, find what they are, fork shovelers */
355408 while (1)
356409 {
357410 in_socket = accept(listen_socket, 0, 0);
358- fprintf(stderr, "accepted fd %d\n", in_socket);
411+ if (verbose) fprintf(stderr, "accepted fd %d\n", in_socket);
359412
360413 if (!fork())
361414 {
362415 start_shoveler(in_socket);

Built with git-ssb-web