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