git ssb

0+

cel / sslh



Tree: ae008179f033c8409c69b13787a539351bace626

Files: ae008179f033c8409c69b13787a539351bace626 / sslh-main.c

5109 bytesRaw
1/*
2# main: processing of command line options and start the main loop.
3#
4# Copyright (C) 2007-2011 Yves Rutschle
5#
6# This program is free software; you can redistribute it
7# and/or modify it under the terms of the GNU General Public
8# License as published by the Free Software Foundation; either
9# version 2 of the License, or (at your option) any later
10# version.
11#
12# This program is distributed in the hope that it will be
13# useful, but WITHOUT ANY WARRANTY; without even the implied
14# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15# PURPOSE. See the GNU General Public License for more
16# details.
17#
18# The full text for the General Public License is here:
19# http://www.gnu.org/licenses/gpl.html
20
21*/
22
23#define _GNU_SOURCE
24#include <sys/types.h>
25#include <fcntl.h>
26#include <string.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <stdarg.h>
30#include <stdio.h>
31#include <signal.h>
32#include <sys/socket.h>
33#include <sys/wait.h>
34#include <netinet/in.h>
35#include <arpa/inet.h>
36#include <netdb.h>
37#include <pwd.h>
38#include <syslog.h>
39#include <libgen.h>
40#include <getopt.h>
41
42#include "common.h"
43
44const char* USAGE_STRING =
45"sslh " VERSION "\n" \
46"usage:\n" \
47"\tsslh [-v] [-i] [-V] [-f] [-n]\n"
48"\t[-t <timeout>] [-P <pidfile>] -u <username> -p <add> [-p <addr> ...] \n" \
49"%s\n\n" \
50"-v: verbose\n" \
51"-V: version\n" \
52"-f: foreground\n" \
53"-n: numeric output\n" \
54"-t: timeout before connecting to SSH.\n" \
55"-p: address and port to listen on.\n Can be used several times to bind to several addresses.\n" \
56"--[ssh,ssl,...]: where to connect connections from corresponding protocol.\n" \
57"-P: PID file. Default: /var/run/sslh.pid.\n" \
58"-i: Run as a inetd service.\n" \
59"";
60
61void print_usage(void)
62{
63 int i;
64 char *prots = "";
65
66 for (i = 0; i < num_known_protocols; i++)
67 asprintf(&prots, "%s\t[--%s <addr>]\n", prots, protocols[i].description);
68
69 fprintf(stderr, USAGE_STRING, prots);
70}
71
72void parse_cmdline(int argc, char* argv[])
73{
74 int c, affected = 0;
75 struct option const_options[] = {
76 { "inetd", no_argument, &inetd, 1 },
77 { "foreground", no_argument, &foreground, 1 },
78 { "verbose", no_argument, &verbose, 1 },
79 { "numeric", no_argument, &numeric, 1 },
80 { "user", required_argument, 0, 'u' },
81 { "pidfile", required_argument, 0, 'P' },
82 { "timeout", required_argument, 0, 't' },
83 { "listen", required_argument, 0, 'p' },
84 };
85 struct option all_options[ARRAY_SIZE(const_options) + num_known_protocols + 1];
86 struct addrinfo *addr, **a;
87
88 memset(all_options, 0, sizeof(all_options));
89 memcpy(all_options, const_options, sizeof(const_options));
90 append_protocols(all_options, ARRAY_SIZE(const_options), protocols, num_known_protocols);
91
92 while ((c = getopt_long_only(argc, argv, "t:T:p:VP:", all_options, NULL)) != -1) {
93 if (c == 0) continue;
94
95 if (c >= PROT_SHIFT) {
96 affected++;
97 protocols[c - PROT_SHIFT].affected = 1;
98 resolve_name(&addr, optarg);
99 protocols[c - PROT_SHIFT].saddr= *addr;
100 continue;
101 }
102
103 switch (c) {
104
105 case 't':
106 probing_timeout = atoi(optarg);
107 break;
108
109 case 'p':
110 /* find the end of the listen list */
111 for (a = &addr_listen; *a; a = &((*a)->ai_next));
112 /* append the specified addresses */
113 resolve_name(a, optarg);
114
115 break;
116
117 case 'V':
118 printf("%s %s\n", server_type, VERSION);
119 exit(0);
120
121 case 'u':
122 user_name = optarg;
123 break;
124
125 case 'P':
126 pid_file = optarg;
127 break;
128
129 default:
130 print_usage();
131 exit(2);
132 }
133 }
134
135 if (!affected) {
136 fprintf(stderr, "At least one target protocol must be specified.\n");
137 exit(2);
138 }
139
140 if (!addr_listen) {
141 fprintf(stderr, "No listening address specified; use at least one -p option\n");
142 exit(1);
143 }
144
145}
146
147int main(int argc, char *argv[])
148{
149
150 extern char *optarg;
151 extern int optind;
152 int res, num_addr_listen;
153
154 int *listen_sockets;
155
156 /* Init defaults */
157 pid_file = "/var/run/sslh.pid";
158 user_name = "nobody";
159 foreground = 0;
160
161 parse_cmdline(argc, argv);
162
163 if (inetd)
164 {
165 verbose = 0;
166 start_shoveler(0);
167 exit(0);
168 }
169
170 if (verbose)
171 printsettings();
172
173 num_addr_listen = start_listen_sockets(&listen_sockets, addr_listen);
174
175 if (!foreground)
176 if (fork() > 0) exit(0); /* Detach */
177
178 setup_signals();
179
180 drop_privileges(user_name);
181
182 /* New session -- become group leader */
183 if (getuid() == 0) {
184 res = setsid();
185 CHECK_RES_DIE(res, "setsid: already process leader");
186 }
187
188 write_pid_file(pid_file);
189
190 /* Open syslog connection */
191 setup_syslog(argv[0]);
192
193 main_loop(listen_sockets, num_addr_listen);
194
195 return 0;
196}
197

Built with git-ssb-web