1 /*
2  * Copyright (c) 2002-2006 Tomas Svensson <ts@codepix.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
19  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "conf.h"
29 
30 #include <errno.h>
31 #include <memory.h>
32 #include <stdio.h>
33 #include <string.h>
34 #ifdef WIN32
35 extern const char *srv_name;
36 extern const char *srv_name2;
37 extern char *srv_desc;
38 #include <conio.h>
39 #include <process.h>
40 #define snprintf _snprintf
41 #define close closesocket
42 #else
43 #include <unistd.h>
44 #endif
45 
46 #include "tlswrap.h"
47 #include "misc.h"
48 
49 extern int debug;
50 #ifdef WIN32
51 extern struct parm serv_param;
52 #endif
53 
sys_err(const char * err)54 void sys_err(const char *err){
55 	perror(err);
56   	exit(1);
57 }
58 
user_close(struct user_data * ud)59 void user_close(struct user_data *ud)
60 {
61 	if (ud->connected == CONN_YES || ud->connected == CONN_IN_PROG)
62 		close(ud->serv_fd);
63 	close(ud->user_fd);
64 
65 	if (ud->ssl_ctrl)
66 		SSL_free(ud->ssl_ctrl);
67 
68 	if (debug)
69 		printf("user_close\n");
70 	if (ud->data_connected != CONN_NO)
71 		data_close(ud);
72 	if (ud->ssl_sess)
73 		SSL_SESSION_free(ud->ssl_sess);
74 	if (ud->ssl_ctx)
75 		SSL_CTX_free(ud->ssl_ctx);
76 	/* memset(ud, 0, sizeof(struct user_data)); */
77 	ud->user_fd = -1;
78 	ud->serv_fd = -1;
79 	ud->connected = CONN_NO;
80 	ud->ssl_data_fd_mode = TLS_NONE;
81 
82 	ud->s2u_i = ud->s2u_o = ud->s2u_buf;
83 	ud->u2s_i = ud->u2s_o = ud->u2s_buf;
84 
85 }
86 
data_close(struct user_data * ud)87 void data_close(struct user_data *ud)
88 {
89 	if (ud->ssl_data) {
90 		if (1) {
91 		//if (SSL_get_shutdown(ud->ssl_data) & SSL_RECEIVED_SHUTDOWN) {
92 			/* SSL connection was shutdown cleanly */
93 			ud->ssl_sess = SSL_get1_session(ud->ssl_data);
94 			SSL_shutdown(ud->ssl_data);
95 		} else
96 			SSL_clear(ud->ssl_data);
97 		SSL_free(ud->ssl_data);
98 		ud->ssl_data = NULL;
99 	}
100 
101 	if (ud->data_connected == CONN_DATA_OK ||
102 	    ud->data_connected == CONN_DATA_LISTEN)
103 		close(ud->user_data_fd);
104 	if (ud->data_connected == CONN_IN_PROG ||
105 	    ud->data_connected == CONN_DATA_TLS ||
106 	    ud->data_connected == CONN_DATA_OK)
107 		close(ud->serv_data_fd);
108 
109 	ud->user_data_fd = -1;
110 	ud->serv_data_fd = -1;
111 
112 	ud->data_connected = CONN_NO;
113 	ud->ssl_data_fd_mode = TLS_NONE;
114 	ud->dc2s_i = ud->dc2s_o = ud->dc2s_buf;
115 	ud->ds2c_i = ud->ds2c_o = ud->ds2c_buf;
116 
117 	ud->serv_data_close = CLOSE_NONE;
118 	ud->user_data_close = CLOSE_NONE;
119 	ud->user_read_cnt = 0;
120 	ud->serv_read_cnt = 0;
121 	ud->tls_status &= ~TLS_DATA;
122 	ud->retry_data = 0;
123 	ud->active = 0;
124 	if (debug)
125 		printf("data_close\n");
126 
127 }
128 
129 size_t
extr_str(const char * src,size_t src_len,char * dst,size_t dst_len)130 extr_str(const char *src, size_t src_len, char *dst, size_t dst_len) {
131 
132 	/* Extract a \r\n (or just \n) terminated string from a binary
133      	buffer. The copied string will always be null-terminated and
134      	without \r\n. The function will return a pointer to the next
135      	byte after the extracted string or NULL if no string could be
136      	found */
137 
138   	char *ptr;
139   	int ext_size,size;
140 
141   	if ((ptr = memchr(src,'\n',src_len)) == NULL)
142 		return 0;
143 
144   	ext_size = size = ptr - src;
145 
146   	if (src[ext_size-1] == '\r')
147     		ext_size--;
148 
149   	if ( (ext_size + 1) <= dst_len) {
150     		memcpy(dst, src, ext_size);
151     		dst[ext_size] = 0;
152   	} else {
153     		printf("ext_str: dst buffer too small for extracted string\n");
154     		return 0;
155   	}
156 
157   	return size + 1;
158 }
print_to_ud(struct user_data * ud,const char * s)159 int print_to_ud(struct user_data *ud, const char *s) {
160 
161 	/* all pointers must be setup correctly prior to calling this
162      	function, or it will segfault */
163 
164   	size_t slen;
165   	char str[1024];
166 
167   	snprintf(str, sizeof(str), s);
168 
169   	slen = strlen(str); /* NOT including null char */
170 
171   	if ( (&ud->s2u_buf[S2U_SIZE] - ud->s2u_i) < slen) {
172     		printf("print_to_ud: can't fit string to buffer\n");
173     		return 1;
174   	} else {
175     		memcpy(ud->s2u_i,str,slen);
176     		ud->s2u_i+=slen;
177   	}
178 
179  	return 0;
180 }
181 
print_to_serv(struct user_data * ud,const char * s)182 int print_to_serv(struct user_data *ud, const char *s) {
183 
184 	size_t slen;
185 	char str[130];
186 
187 	snprintf(str, sizeof(str), s);
188 	slen = strlen(str); /* NOT including null char */
189 	if ( (&ud->u2s_buf[U2S_SIZE]-ud->u2s_i)<slen) {
190 		printf("print_to_ud: can't fit string to buffer\n");
191 		return 1;
192 	} else {
193 		memcpy(ud->u2s_i,str,slen);
194 		ud->u2s_i+=slen;
195 	}
196 
197 	return 0;
198 }
199 #if 1
find_max_fd(int listen,struct user_data * ud,int max_users)200 int find_max_fd(int listen, struct user_data *ud, int max_users) {
201 	int i, max_fd = listen;
202 
203   	for(i = 0; i < max_users; i++) {
204     		if (ud[i].user_fd != -1) {
205       			if (ud[i].user_fd > max_fd)
206 				max_fd = ud[i].user_fd;
207       			if ((ud[i].serv_fd > max_fd) &&
208 			    ((ud[i].connected == CONN_YES)||
209 	  	   	    (ud[i].connected == CONN_IN_PROG )))
210 				max_fd = ud[i].serv_fd;
211       			if ( (ud[i].serv_data_fd > max_fd) &&
212 			    ((ud[i].data_connected == CONN_YES) ||
213 	  	    	    (ud[i].data_connected == CONN_IN_PROG )))
214 				max_fd = ud[i].serv_data_fd;
215       			if (ud[i].data_connected == CONN_DATA_LISTEN)
216 				if (ud[i].user_data_fd > max_fd)
217 					max_fd = ud[i].user_data_fd;
218       			if (ud[i].ssl_data_fd_mode != TLS_NONE)
219 	 			if (ud[i].serv_data_fd > max_fd)
220 					max_fd = ud[i].serv_data_fd;
221       			if (ud[i].data_connected == CONN_DATA_OK) {
222 				if (ud[i].user_data_fd > max_fd)
223 					max_fd = ud[i].user_data_fd;
224 				if (ud[i].serv_data_fd > max_fd)
225 					max_fd = ud[i].serv_data_fd;
226 			}
227       		}
228     	}
229 
230   	return max_fd;
231 }
232 #else
233 
find_max_fd(fd_set * fd_r,fd_set * fd_w)234 int find_max_fd(fd_set *fd_r, fd_set *fd_w)
235 {
236 	int i, max_fd;
237 
238 	max_fd = 0;
239 
240 	for (i = FD_SETSIZE - 1; i >= 0 ; i--) {
241 		if ( FD_ISSET(i,fd_r) || FD_ISSET(i,fd_w) )
242 			return i;
243 	}
244 
245 	return 0;
246 }
247 #endif
init_ud(struct user_data * ud,int max_users)248 void init_ud(struct user_data *ud, int max_users) {
249 
250 	/* Initializes the user_data structures */
251 
252 	int i;
253   	memset(&ud[0], 0, max_users * sizeof(struct user_data));
254   	for (i = 0; i < max_users; i++)
255     		ud[i].user_fd = -1;
256 }
257 
find_free_slot(struct user_data * ud,int max_users)258 int find_free_slot(struct user_data *ud, int max_users) {
259 
260 	/* Returns the index of the first free ud slot, otherwise
261      	   it returns -1 */
262 
263   	int i;
264 
265   	for (i = 0; i < max_users; i++)
266     		if (ud++->user_fd == -1) return i;
267 
268   	return -1;
269 }
270 
271 
272 #ifndef HAVE_STRLCPY
273 
274 /*	$Id: strlcpy.c,v 1.1 2000/07/29 13:33:34 lukem Exp $	*/
275 /*	$NetBSD: strlcpy.c,v 1.5 1999/09/20 04:39:47 lukem Exp $	*/
276 /*	from OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp 	*/
277 
278 /*
279  * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
280  * All rights reserved.
281  *
282  * Redistribution and use in source and binary forms, with or without
283  * modification, are permitted provided that the following conditions
284  * are met:
285  * 1. Redistributions of source code must retain the above copyright
286  *    notice, this list of conditions and the following disclaimer.
287  * 2. Redistributions in binary form must reproduce the above copyright
288  *    notice, this list of conditions and the following disclaimer in the
289  *    documentation and/or other materials provided with the distribution.
290  * 3. The name of the author may not be used to endorse or promote products
291  *    derived from this software without specific prior written permission.
292  *
293  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
294  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
295  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
296  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
297  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
298  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
299  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
300  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
301  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
302  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
303  */
304 
305 /*
306  * Copy src to string dst of size siz.  At most siz-1 characters
307  * will be copied.  Always NUL terminates (unless siz == 0).
308  * Returns strlen(src); if retval >= siz, truncation occurred.
309  */
310 size_t
strlcpy(char * dst,const char * src,size_t siz)311 strlcpy(char *dst, const char *src, size_t siz)
312 {
313 	char *d = dst;
314 	const char *s = src;
315 	size_t n = siz;
316 
317 	/* Copy as many bytes as will fit */
318 	if (n != 0 && --n != 0) {
319 		do {
320 			if ((*d++ = *s++) == 0)
321 				break;
322 		} while (--n != 0);
323 	}
324 
325 	/* Not enough room in dst, add NUL and traverse rest of src */
326 	if (n == 0) {
327 		if (siz != 0)
328 			*d = '\0';		/* NUL-terminate dst */
329 		while (*s++)
330 			;
331 	}
332 
333 	return(s - src - 1);	/* count does not include NUL */
334 }
335 #endif
336 
337 /*
338  * Copyright (c) 1987, 1993, 1994
339  *	The Regents of the University of California.  All rights reserved.
340  *
341  * Redistribution and use in source and binary forms, with or without
342  * modification, are permitted provided that the following conditions
343  * are met:
344  * 1. Redistributions of source code must retain the above copyright
345  *    notice, this list of conditions and the following disclaimer.
346  * 2. Redistributions in binary form must reproduce the above copyright
347  *    notice, this list of conditions and the following disclaimer in the
348  *    documentation and/or other materials provided with the distribution.
349  * 3. All advertising materials mentioning features or use of this software
350  *    must display the following acknowledgement:
351  *	This product includes software developed by the University of
352  *	California, Berkeley and its contributors.
353  * 4. Neither the name of the University nor the names of its contributors
354  *    may be used to endorse or promote products derived from this software
355  *    without specific prior written permission.
356  *
357  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
358  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
359  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
360  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
361  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
362  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
363  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
364  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
365  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
366  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
367  * SUCH DAMAGE.
368  */
369 
370 #ifndef HAVE_GETOPT
371 
372 int	opterr = 1,		/* if error message should be printed */
373 	optind = 1,		/* index into parent argv vector */
374 	optopt,			/* character checked for validity */
375 	optreset;		/* reset getopt */
376 char	*optarg;		/* argument associated with option */
377 
378 #define	BADCH	(int)'?'
379 #define	BADARG	(int)':'
380 #define	EMSG	""
381 
_getprogname(void)382 char *_getprogname(void) {
383 	return "tlswrap";
384 }
385 
386 /*
387  * getopt --
388  *	Parse argc/argv argument vector.
389  */
390 int
getopt(int nargc,char * const nargv[],const char * ostr)391 getopt(int nargc, char * const nargv[], const char *ostr) {
392 
393 	static char *place = EMSG;		/* option letter processing */
394 	char *oli;				/* option letter list index */
395 
396 	if (optreset || *place == 0) {		/* update scanning pointer */
397 		optreset = 0;
398 		place = nargv[optind];
399 		if (optind >= nargc || *place++ != '-') {
400 			/* Argument is absent or is not an option */
401 			place = EMSG;
402 			return (-1);
403 		}
404 		optopt = *place++;
405 		if (optopt == '-' && *place == 0) {
406 			/* "--" => end of options */
407 			++optind;
408 			place = EMSG;
409 			return (-1);
410 		}
411 		if (optopt == 0) {
412 			/* Solitary '-', treat as a '-' option
413 			   if the program (eg su) is looking for it. */
414 			place = EMSG;
415 			if (strchr(ostr, '-') == NULL)
416 				return (-1);
417 			optopt = '-';
418 		}
419 	} else
420 		optopt = *place++;
421 
422 	/* See if option letter is one the caller wanted... */
423 	if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
424 		if (*place == 0)
425 			++optind;
426 		if (opterr && *ostr != ':')
427 			(void)fprintf(stderr,
428 			    "%s: illegal option -- %c\n", _getprogname(),
429 			    optopt);
430 		return (BADCH);
431 	}
432 
433 	/* Does this option need an argument? */
434 	if (oli[1] != ':') {
435 		/* don't need argument */
436 		optarg = NULL;
437 		if (*place == 0)
438 			++optind;
439 	} else {
440 		/* Option-argument is either the rest of this argument or the
441 		   entire next argument. */
442 		if (*place)
443 			optarg = place;
444 		else if (nargc > ++optind)
445 			optarg = nargv[optind];
446 		else {
447 			/* option-argument absent */
448 			place = EMSG;
449 			if (*ostr == ':')
450 				return (BADARG);
451 			if (opterr)
452 				(void)fprintf(stderr,
453 				    "%s: option requires an argument -- %c\n",
454 				    _getprogname(), optopt);
455 			return (BADCH);
456 		}
457 		place = EMSG;
458 		++optind;
459 	}
460 	return (optopt);			/* return option letter */
461 }
462 #endif /* !HAVE_GETOPT */
463 
464 #ifdef WIN32
465 #ifndef WIN98
service_main(DWORD argc,LPTSTR * argv)466 void service_main(DWORD argc, LPTSTR *argv)
467 {
468 
469 	BOOL success;
470 
471 	nServiceStatusHandle = RegisterServiceCtrlHandler(srv_name,
472 		(LPHANDLER_FUNCTION)service_ctrl_handler);
473 	if (!nServiceStatusHandle)
474 		return;
475 	success = update_service_status(SERVICE_START_PENDING,NO_ERROR,0,1,3000);
476 	if (!success)
477 		return;
478 	killServiceEvent = CreateEvent(0,TRUE,FALSE,0);
479 	if (killServiceEvent == NULL)
480 		return;
481 	success = update_service_status(SERVICE_START_PENDING,NO_ERROR,0,2,1000);
482 	if(!success)
483 		return;
484 	success = start_service_thread();
485 	if (!success)
486 		return;
487 	nServiceCurrentStatus = SERVICE_RUNNING;
488 	success = update_service_status(SERVICE_RUNNING,NO_ERROR,0,0,0);
489 	if (!success)
490 		return;
491 	WaitForSingleObject(killServiceEvent,INFINITE);
492 	CloseHandle(killServiceEvent);
493 	_endthread();
494 }
495 
update_service_status(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwServiceSpecificExitCode,DWORD dwCheckPoint,DWORD dwWaitHint)496 BOOL update_service_status(DWORD dwCurrentState, DWORD dwWin32ExitCode,
497 					 DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
498 					 DWORD dwWaitHint)
499 {
500 	BOOL success;
501 	SERVICE_STATUS nServiceStatus;
502 	nServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
503 	nServiceStatus.dwCurrentState = dwCurrentState;
504 	if(dwCurrentState == SERVICE_START_PENDING)
505 		nServiceStatus.dwControlsAccepted = 0;
506 	else
507 		nServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP
508 			|SERVICE_ACCEPT_SHUTDOWN;
509 	if (dwServiceSpecificExitCode == 0)
510 		nServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
511 	else
512 		nServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
513 	nServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
514 	nServiceStatus.dwCheckPoint = dwCheckPoint;
515 	nServiceStatus.dwWaitHint = dwWaitHint;
516 
517 	success = SetServiceStatus(nServiceStatusHandle,&nServiceStatus);
518 
519 	if (!success) {
520 		kill_service();
521 		return success;
522 	}
523 	else
524 		return success;
525 }
526 
start_service_thread()527 BOOL start_service_thread()
528 {
529 	DWORD id;
530 	hServiceThread = CreateThread(0,0,
531 		(LPTHREAD_START_ROUTINE)service_execution_thread,
532 		NULL,0,&id);
533 	if (hServiceThread == 0)
534 		return false;
535 	else
536 		return true;
537 }
538 
kill_service()539 void kill_service()
540 {
541 //	closesocket(pipe01[0]);
542 	closesocket(pipe01[1]);
543 //	closesocket(pipe02[0]);
544 //	closesocket(pipe02[1]);
545 	SetEvent(killServiceEvent);
546 	update_service_status(SERVICE_STOPPED,NO_ERROR,0,0,0);
547 }
548 
service_ctrl_handler(DWORD nControlCode)549 void service_ctrl_handler(DWORD nControlCode)
550 {
551 
552 	switch (nControlCode) {
553 	case SERVICE_CONTROL_SHUTDOWN:
554 	case SERVICE_CONTROL_STOP:
555 		nServiceCurrentStatus = SERVICE_STOP_PENDING;
556 		update_service_status(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);
557 		kill_service();
558 		return;
559 	default:
560 		break;
561 	}
562 	update_service_status(nServiceCurrentStatus,NO_ERROR,0,0,0);
563 }
564 
install_service(char * serv,char * serv_opt,int key_wait)565 void install_service(char *serv, char *serv_opt, int key_wait)
566 {
567 	SC_HANDLE tlswrap_srv, scm;
568 	SERVICE_DESCRIPTION info[] =
569 	{
570 		{srv_desc},
571 		{NULL},
572 	};
573 
574 	scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
575 
576 	if(!scm) {
577 		printf("Could not access the service control manager.\n");
578 		if (key_wait) {
579 			printf("Press any key.");
580 			_getch();
581 		}
582 		exit(0);
583 	}
584 
585 	strcat(serv, "\\tlswrap.exe -S ");
586 	strcat(serv, serv_opt);
587 
588 	tlswrap_srv = CreateService(scm,
589 		srv_name, srv_name2,
590 		SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
591 		SERVICE_ERROR_NORMAL,
592 		serv,
593 		0,0,0,0,0);
594 
595 	if (!tlswrap_srv) {
596 		CloseServiceHandle(scm);
597 		printf("CreateService failed.\n");
598 		if (key_wait) {
599 			printf("Press any key.");
600 			_getch();
601 		}
602 		exit(1);
603 	}
604 
605 	if (!ChangeServiceConfig2(tlswrap_srv, SERVICE_CONFIG_DESCRIPTION,
606 		&info))
607 		printf("Could not set service description\n");
608 
609 	printf("TLSWrap service installed.\n");
610 	if (StartService(tlswrap_srv, 0, NULL))
611 		printf("Started TLSWrap service.\n");
612 	else
613 		printf("Could not start TLSWrap service.\n");
614 	CloseServiceHandle(tlswrap_srv);
615 	CloseServiceHandle(scm);
616 	if (key_wait) {
617 		printf("Press any key.");
618 		_getch();
619 	}
620 	exit(0);
621 
622 }
623 
remove_service(int key_wait)624 void remove_service(int key_wait)
625 {
626 	SC_HANDLE		tlswrap_srv, scm;
627 	SERVICE_STATUS	tlswrap_status;
628 	HANDLE			hpipe;
629 
630 	hpipe = CreateFile(
631          "\\\\.\\pipe\\tlswrap_tray",   // pipe name
632          GENERIC_WRITE,
633          0,              // no sharing
634          NULL,           // no security attributes
635          OPEN_EXISTING,  // opens existing pipe
636          0,              // default attributes
637          NULL);          // no template file
638 
639 
640 	if (hpipe != INVALID_HANDLE_VALUE) {
641 		CloseHandle(hpipe);
642 		printf("Killed the TLSWrap Tray Monitor.\n");
643 	} else
644 		printf("Could not find the TLSWrap Tray Monitor running.\n");
645 
646 	scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE);
647 
648 	if(!scm) {
649 		printf("Could not access the service control manager.\n");
650 		if (key_wait) {
651 			printf("Press any key.");
652 			_getch();
653 		}
654 		exit(0);
655 	}
656 	if (!(tlswrap_srv = OpenService(scm, srv_name, SERVICE_ALL_ACCESS))) {
657 		printf("No TLSWrap service to remove.\n");
658 		if (key_wait) {
659 			printf("Press any key.\n");
660 			getch();
661 		}
662 		exit(0);
663 	}
664 
665 	if (ControlService(tlswrap_srv, SERVICE_CONTROL_STOP, &tlswrap_status)) {
666 		printf("Stopping TLSWrap Service");
667 		Sleep(1000);
668 		while (QueryServiceStatus(tlswrap_srv, &tlswrap_status)) {
669 			if (tlswrap_status.dwCurrentState == SERVICE_STOP_PENDING) {
670 				printf(".");
671 				Sleep(1000);
672 			} else
673 				break;
674 		}
675 
676 		if (tlswrap_status.dwCurrentState == SERVICE_STOPPED)
677                     printf("\nTLSWrap service stopped.\n");
678                 else
679                     printf("\nFailed to stop TLSWrap service.\n");
680 	}
681 
682 	if (DeleteService(tlswrap_srv))
683 			printf("Removed TLSWrap service.\n");
684 	else
685 			printf("Could not remove TLSWrap service.\n");
686 	CloseServiceHandle(tlswrap_srv);
687 	CloseServiceHandle(scm);
688 	if (key_wait) {
689 		printf("Press any key.\n");
690 		getch();
691 	}
692 	exit(0);
693 }
694 
695 #endif /* !not WIN98 */
696 
697 /* Control handler */
698 
CtrlHandler(DWORD fdwCtrlType)699 BOOL CtrlHandler(DWORD fdwCtrlType) {
700 
701 	switch(fdwCtrlType)  {
702 		// Handle all signals
703 		default:
704 			closesocket(pipe01[1]);
705 //			closesocket(pipe01[0]);
706 //			closesocket(pipe02[0]);
707 //			closesocket(pipe02[1]);
708 			return TRUE;
709 	}
710 }
711 
712 #endif /* !WIN32 */
713