diff -cr stunnel-3.8/Makefile.in stunnel-3.8~/Makefile.in *** stunnel-3.8/Makefile.in Tue Feb 22 04:08:16 2000 --- stunnel-3.8~/Makefile.in Fri Jun 2 10:46:49 2000 *************** *** 7,13 **** sbindir=@sbindir@ libdir=@libdir@ man8dir=@mandir@/man8 ! piddir=@localstatedir@/stunnel ssldir=@ssldir@ certdir=$(ssldir)/certs @SET_MAKE@ --- 7,13 ---- sbindir=@sbindir@ libdir=@libdir@ man8dir=@mandir@/man8 ! piddir=@localstatedir@/stunnel/ ssldir=@ssldir@ certdir=$(ssldir)/certs @SET_MAKE@ *************** *** 15,21 **** RANDOM_OPT=@RANDOM_OPT@ CC=@CC@ INSTALL=@INSTALL@ ! CFLAGS=@CFLAGS@ @DEFS@ -Dcertdir=\"$(certdir)\" -Dlibdir=\"$(libdir)\" -Dpiddir=\"$(piddir)\" LIBS=@LIBS@ OBJS=stunnel.o ssl.o protocol.o sthreads.o pty.o log.o DESTFILES=$(sbindir)/stunnel $(libdir)/stunnel.so $(man8dir)/stunnel.8 $(certdir)/stunnel.pem --- 15,21 ---- RANDOM_OPT=@RANDOM_OPT@ CC=@CC@ INSTALL=@INSTALL@ ! CFLAGS=@CFLAGS@ @DEFS@ -Dcertdir=\"$(certdir)\" -Dlibdir=\"$(libdir)\" -DPIDDIR=\"$(piddir)\" LIBS=@LIBS@ OBJS=stunnel.o ssl.o protocol.o sthreads.o pty.o log.o DESTFILES=$(sbindir)/stunnel $(libdir)/stunnel.so $(man8dir)/stunnel.8 $(certdir)/stunnel.pem diff -cr stunnel-3.8/common.h stunnel-3.8~/common.h *** stunnel-3.8/common.h Thu Feb 24 03:35:00 2000 --- stunnel-3.8~/common.h Fri Jun 2 08:46:01 2000 *************** *** 153,158 **** --- 153,159 ---- char *protocol; char *setuid_user; char *setgid_group; + char *pid_dir; } server_options; /* Prototypes for stunnel.c */ diff -cr stunnel-3.8/stunnel.8.in stunnel-3.8~/stunnel.8.in *** stunnel-3.8/stunnel.8.in Tue Feb 15 09:13:15 2000 --- stunnel-3.8~/stunnel.8.in Fri Jun 2 11:48:15 2000 *************** *** 5,15 **** --- 5,17 ---- .B stunnel [-T] [-p pemfile] [-v level] [-a directory] [-t timeout] [-u username] [-n protocol] + [-P { dir/ | filename | none } ] [-d [ip:]port [-f]] [ -l program | -r [ip:]port | -L program [-- args] ] .PP .B stunnel {-c} [-p pemfile] [-v level] [-a directory] [-t timeout] [-u username] [-n protocol] + [-P { dir/ | filename | none } ] -r [ip:]port [ -d [ip:]port [-f] | -l program | -L program [-- args] ] .SH DESCRIPTION The \fBstunnel\fR program is designed to work as \fISSL\fR encryption wrapper *************** *** 103,108 **** --- 105,121 ---- .B -g groupname .RS setgid() to groupname in daemon mode. Clears all other groups. + .RE + .PP + .B -P { dir/ | file | none } + Pid file location + .RS + If the argument is a pathname ending in a slash, then a pid file + named "\fIstunnel.\fRservicename\fI.pid\fR" will be created in + the specified directory. If the argument is a filename (no + trailing slash), then that filename will be used for the pid. + If + the argument is 'none', then no pid file will be created. .RE .PP .B -r [ip:]port diff -cr stunnel-3.8/stunnel.c stunnel-3.8~/stunnel.c *** stunnel-3.8/stunnel.c Thu Feb 24 03:32:27 2000 --- stunnel-3.8~/stunnel.c Fri Jun 2 15:31:23 2000 *************** *** 216,223 **** options.protocol=NULL; options.setuid_user=NULL; options.setgid_group=NULL; opterr=0; ! while ((c = getopt(argc, argv, "a:cp:v:d:fTl:L:r:s:g:t:u:n:hC:D:V")) != EOF) switch (c) { case 'a': safecopy(options.clientdir, optarg); --- 216,224 ---- options.protocol=NULL; options.setuid_user=NULL; options.setgid_group=NULL; + options.pid_dir=PIDDIR; opterr=0; ! while ((c = getopt(argc, argv, "a:cp:v:d:fTl:L:r:s:g:t:u:n:hC:D:VP:")) != EOF) switch (c) { case 'a': safecopy(options.clientdir, optarg); *************** *** 321,326 **** --- 322,330 ---- case 'V': fprintf(stderr, "\n" STUNNEL_INFO "\n\n"); exit(0); + case 'P': + options.pid_dir=optarg; + break; case '?': log(LOG_ERR, "Illegal option: '%c'", optopt); case 'h': *************** *** 432,461 **** static void create_pid() { ! FILE *pf; ! int oldumask; options.dpid=(unsigned long)getpid(); ! #ifdef HAVE_SNPRINTF ! snprintf(options.pidfile, STRLEN, #else ! sprintf(options.pidfile, #endif ! "%s/stunnel.%s.pid", piddir, options.servname); ! oldumask=umask(022); ! pf=fopen(options.pidfile, "w"); ! umask(oldumask); ! if(!pf) { ! ioerror(options.pidfile); ! return; /* not critical */ } ! fprintf(pf, "%lu", options.dpid); ! fclose(pf); atexit(delete_pid); } static void delete_pid() { if((unsigned long)getpid()!=options.dpid) return; /* Current process is not main deamon process */ if(unlink(options.pidfile)<0) --- 436,490 ---- static void create_pid() { ! int pf; ! char pid[STRLEN]; + if ( strcmp(options.pid_dir, "none") == 0 ) { + log(LOG_DEBUG, "No pid file being created."); + options.pidfile[0]='\0'; + return; + } + if ( ! strchr(options.pid_dir, '/') ) { + log(LOG_ERR, "Argument to -P (%s) must be full path name.", + options.pid_dir); + /* Why? Because we don't want to confuse by + allowing '.', which would be '/' after + daemonizing) */ + exit(1); + } options.dpid=(unsigned long)getpid(); ! ! /* determine if they specified a pid dir or pid file, ! and set our options.pidfile appropriately */ ! if ( options.pid_dir[ strlen(options.pid_dir)-1 ] == '/' ) { ! #ifdef HAVE_SNPRINTF ! snprintf(options.pidfile, STRLEN, ! "%sstunnel.%s.pid", options.pid_dir, options.servname); #else ! safecopy(options.pidfile, options.pid_dir); ! safeconcat(options.pidfile, "stunnel."); ! safeconcat(options.pidfile, options.servname); ! safeconcat(options.pidfile, ".pid"); #endif ! } else { ! safecopy(options.pidfile, options.pid_dir); } ! ! if (-1==(pf=open(options.pidfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0644))) { ! log(LOG_ERR, "Cannot create pid file %s", options.pidfile); ! ioerror("Create"); ! exit(1); ! } ! sprintf(pid, "%lu", options.dpid); ! write( pf, pid, strlen(pid) ); ! close(pf); ! log(LOG_DEBUG, "Created pid file %s", options.pidfile); atexit(delete_pid); } static void delete_pid() { + log(LOG_DEBUG, "removing pid file %s", options.pidfile); if((unsigned long)getpid()!=options.dpid) return; /* Current process is not main deamon process */ if(unlink(options.pidfile)<0) *************** *** 522,527 **** --- 551,562 ---- options.setuid_user); exit(1); } + #ifndef USE_WIN32 + /* gotta chown that pid file, or we can't remove it. */ + if ( options.pidfile[0] && chown( options.pidfile, pw->pw_uid, -1) ) { + log(LOG_ERR, "Failed to chown pidfile %s", options.pidfile); + } + #endif if(setuid(pw->pw_uid)) { sockerror("setuid"); exit(1); *************** *** 916,921 **** --- 951,957 ---- "\n -L program\topen local pty and execute program" "\n -s username\tsetuid() to username in daemon mode" "\n -g groupname\tsetgid() to groupname in daemon mode" + "\n -P arg\tSpecify pid file. { dir/ | filename | none }" #endif "\n -r [ip:]port\tconnect to remote service" " (ip defaults to INADDR_LOOPBACK)"