git ssb

0+

cel / sslh



Commit 3386a64a4d817d03da64318fb028c49c699cee85

v1.3

Yves Rutschle committed on 7/10/2013, 9:07:49 PM
Parent: b49617923fadbe4429cbab8f4276a70ed0f73ab7

Files changed

sslh.cchanged
sslh.cView
@@ -27,10 +27,19 @@
2727
2828 LynxOS:
2929 gcc -o tcproxy tcproxy.c -lnetinet
3030
31+Linux:
32+ cc -o sslh sslh.c -lnet
33+
3134 HISTORY
3235
36+v1.3: 14MAY2008
37+ Added parsing for local interface to listen on
38+ Changed default SSL connexion to port 442 (443 doesn't make
39+ sense as a default as we're already listening on 443)
40+ Syslog incoming connexions
41+
3342 v1.2: 12MAY2008
3443 Fixed compilation warning for AMD64 (Thx Daniel Lange)
3544
3645 v1.1: 21MAY2007
@@ -45,9 +54,9 @@
4554 configurable.
4655
4756 */
4857
49-#define VERSION "1.2"
58+#define VERSION "1.3"
5059
5160 #include <sys/types.h>
5261 #include <fcntl.h>
5362 #include <string.h>
@@ -60,8 +69,9 @@
6069 #include <netinet/in.h>
6170 #include <arpa/inet.h>
6271 #include <netdb.h>
6372 #include <pwd.h>
73+#include <syslog.h>
6474
6575 #define CHECK_RES_DIE(res, str) \
6676 if (res == -1) { \
6777 perror(str); \
@@ -71,18 +81,24 @@
7181 #define USAGE_STRING \
7282 "sslh v" VERSION "\n" \
7383 "usage:\n" \
7484 "\texport PIDFILE=/var/run/sslhc.pid\n" \
75-"\tsslh [-t <timeout>] -u <username> -p <listenport> -s [sshhost:]port -l [sslhost:]port [-v]\n"
85+"\tsslh [-t <timeout>] -u <username> -p [listenaddr:]<listenport> \n" \
86+"\t\t-s [sshhost:]port -l [sslhost:]port [-v]\n\n" \
87+"-v: verbose\n" \
88+"-p: address and port to listen on. default: 0.0.0.0:443\n" \
89+"-s: SSH address: where to connect an SSH connexion. default: localhost:22\n" \
90+"-l: SSL address: where to connect an SSL connexion.\n" \
91+""
7692
7793 int verbose = 0; /* That's really quite global */
7894
79-/* Starts a listening socket on specified port.
95+/* Starts a listening socket on specified address.
8096 Returns file descriptor
8197 */
82-int start_listen_socket(int port)
98+int start_listen_socket(struct sockaddr *addr)
8399 {
84- struct sockaddr_in saddr;
100+ struct sockaddr_in *saddr = (struct sockaddr_in*)addr;
85101 int sockfd, res, reuse;
86102
87103 sockfd = socket(AF_INET, SOCK_STREAM, 0);
88104 CHECK_RES_DIE(sockfd, "socket");
@@ -90,12 +106,9 @@
90106 reuse = 1;
91107 res = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse));
92108 CHECK_RES_DIE(res, "setsockopt");
93109
94- memset(&saddr, 0, sizeof(saddr));
95- saddr.sin_port = htons(port);
96-
97- res = bind (sockfd, (struct sockaddr*)&saddr, sizeof(saddr));
110+ res = bind (sockfd, (struct sockaddr*)saddr, sizeof(*saddr));
98111 CHECK_RES_DIE(res, "bind");
99112
100113 res = listen (sockfd, 5);
101114 CHECK_RES_DIE(res, "listen");
@@ -177,12 +190,10 @@
177190
178191 /* turns a "hostname:port" string into a struct sockaddr;
179192 sock: socket address to which to copy the addr
180193 fullname: input string -- it gets clobbered
181-serv: default service/port
182-(defaults don't work yet)
183194 */
184-void resolve_name(struct sockaddr *sock, char* fullname, int port) {
195+void resolve_name(struct sockaddr *sock, char* fullname) {
185196 struct addrinfo *addr, hint;
186197 char *serv, *host;
187198 int res;
188199
@@ -190,9 +201,9 @@
190201
191202 if (!sep) /* No separator: parameter is just a port */
192203 {
193204 serv = fullname;
194- fprintf(stderr, "names must be fully specified as hostname:port for the moment\n");
205+ fprintf(stderr, "names must be fully specified as hostname:port\n");
195206 exit(1);
196207 }
197208 else {
198209 host = fullname;
@@ -214,15 +225,31 @@
214225
215226 memcpy(sock, addr->ai_addr, sizeof(*sock));
216227 }
217228
229+/* syslogs who connected to where */
230+void log_connexion(int socket, char* target)
231+{
232+ struct sockaddr peeraddr;
233+ socklen_t size = sizeof(peeraddr);
234+ char buf[64];
235+ int res;
236+
237+ res = getpeername(socket, &peeraddr, &size);
238+ CHECK_RES_DIE(res, "getpeername");
239+
240+ syslog(LOG_INFO, "connexion from %s forwarded to %s\n",
241+ sprintaddr(buf, sizeof(buf), &peeraddr), target);
242+
243+}
244+
218245 /*
219246 * Settings that depend on the command line. That's less global than verbose * :-)
220247 * They're set in main(), but also used in start_shoveler(), and it'd be heavy-handed
221248 * to pass it all as parameters
222249 */
223250 int timeout = 2;
224-int listen_port = 443;
251+struct sockaddr addr_listen;
225252 struct sockaddr addr_ssl, addr_ssh;
226253
227254
228255 /* Child process that finds out what to connect to and proxies
@@ -233,8 +260,9 @@
233260 struct timeval tv;
234261 struct sockaddr *saddr;
235262 int res;
236263 int out_socket;
264+ char *target;
237265
238266 FD_ZERO(&fds);
239267 FD_SET(in_socket, &fds);
240268 memset(&tv, 0, sizeof(tv));
@@ -246,17 +274,17 @@
246274 /* Pick the target address depending on whether we timed out or not */
247275 if (FD_ISSET(in_socket, &fds)) {
248276 /* The client wrote something to the socket: it's an SSL connection */
249277 saddr = &addr_ssl;
250- if (verbose)
251- fprintf(stderr, "Forwarding to SSL\n");
278+ target = "SSL";
252279 } else {
253280 /* The client hasn't written anything and we timed out: connect to SSH */
254281 saddr = &addr_ssh;
255- if (verbose)
256- fprintf(stderr, "Forwarding to SSH\n");
282+ target = "SSH";
257283 }
258284
285+ log_connexion(in_socket, target);
286+
259287 /* Connect the target socket */
260288 out_socket = socket(AF_INET, SOCK_STREAM, 0);
261289 res = connect(out_socket, saddr, sizeof(addr_ssl));
262290 CHECK_RES_DIE(res, "connect");
@@ -341,9 +369,9 @@
341369 sprintaddr(buf, sizeof(buf), &addr_ssl),
342370 timeout
343371 );
344372 fprintf(stderr, "SSH addr: %s\n", sprintaddr(buf, sizeof(buf), &addr_ssh));
345- fprintf(stderr, "listening on port %d\n", listen_port);
373+ fprintf(stderr, "listening on %s\n", sprintaddr(buf, sizeof(buf), &addr_listen));
346374 }
347375
348376 int main(int argc, char *argv[])
349377 {
@@ -355,13 +383,15 @@
355383 int in_socket, listen_socket;
356384
357385 /* Init defaults */
358386 char *user_name = "nobody";
359- char ssl_str[] = "localhost:443";
387+ char listen_str[] = "0.0.0.0:443";
388+ char ssl_str[] = "localhost:442";
360389 char ssh_str[] = "localhost:22";
361390
362- resolve_name(&addr_ssl, ssl_str, 443);
363- resolve_name(&addr_ssh, ssh_str, 22);
391+ resolve_name(&addr_listen, listen_str);
392+ resolve_name(&addr_ssl, ssl_str);
393+ resolve_name(&addr_ssh, ssh_str);
364394
365395 while ((c = getopt(argc, argv, "t:l:s:p:vu:")) != EOF) {
366396 switch (c) {
367397
@@ -369,17 +399,17 @@
369399 timeout = atoi(optarg);
370400 break;
371401
372402 case 'p':
373- listen_port = atoi(optarg);
403+ resolve_name(&addr_listen, optarg);
374404 break;
375405
376406 case 'l':
377- resolve_name(&addr_ssl, optarg, 443);
407+ resolve_name(&addr_ssl, optarg);
378408 break;
379409
380410 case 's':
381- resolve_name(&addr_ssh, optarg, 22);
411+ resolve_name(&addr_ssh, optarg);
382412 break;
383413
384414 case 'v':
385415 verbose += 1;
@@ -399,9 +429,9 @@
399429 printsettings();
400430
401431 setup_signals();
402432
403- listen_socket = start_listen_socket(listen_port);
433+ listen_socket = start_listen_socket(&addr_listen);
404434
405435 if (fork() > 0) exit(0); /* Detach */
406436
407437 write_pid_file();
@@ -411,8 +441,11 @@
411441 /* New session -- become group leader */
412442 res = setsid();
413443 CHECK_RES_DIE(res, "setsid: already process leader");
414444
445+ /* Open syslog connexion */
446+ openlog(argv[0], LOG_CONS, LOG_AUTH);
447+
415448 /* Main server loop: accept connections, find what they are, fork shovelers */
416449 while (1)
417450 {
418451 in_socket = accept(listen_socket, 0, 0);

Built with git-ssb-web