repo: tlswrap
action: commit
revision: 
path_from: 
revision_from: bf76a8bacc84d7179602089ab06e8f6dc7cae64d:
path_to: 
revision_to: 
git.thebackupbox.net
tlswrap
git clone git://git.thebackupbox.net/tlswrap
commit bf76a8bacc84d7179602089ab06e8f6dc7cae64d
Author: epoch 
Date:   Mon Jul 28 23:31:27 2025 +0000

    two different attempts at trying to keep tlswrap from getting stuck on SSL_accept. at once. why not?

diff --git a/tlswrap.c b/tlswrap.c
index f5d1b93a0069a7ab122461be4da7a55ba746c777..
index ..5f84c7551ff2ce3b6a0cb61035b7a6ed540cab0e 100644
--- a/tlswrap.c
+++ b/tlswrap.c
@@ -235,6 +235,9 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) {
 void signal_handler(int sig) {
   if(sig == SIGTERM) { // closing these fds should make it break out of the select loop and cleanup
     syslog(LOG_DEBUG,"received signal: %d closing([0,1,2])",sig);
+  }
+  if(sig == SIGALRM) {
+    syslog(LOG_ERR,"SIGALRM received! the SSL_accept got stuck I guess. closing files.");
     close(0);
     close(1);
     close(2);
@@ -248,6 +251,7 @@ int main(int argc,char *argv[]) {
   setvbuf(stdout, NULL, _IONBF, 0);
   setvbuf(stderr, NULL, _IONBF, 0);
   signal(SIGTERM,signal_handler);
+  signal(SIGALRM,signal_handler);
   openlog(NULL,LOG_PID,LOG_DAEMON);
   syslog(LOG_DEBUG,"started");
   struct sockaddr_in6 sa6;
@@ -353,6 +357,17 @@ int main(int argc,char *argv[]) {
   pipe(b);
   pipe(c);

+  struct timeval orig_timeout;
+  struct timeval timeout;
+  orig_timeout.tv_sec=60;// we give it a WHOLE MINUTE to get done with stuff...
+  orig_timeout.tv_usec=0;// 1/100th of a second. (10ms) sound good?
+  fd_set master;
+  fd_set readfs;
+  fd_set errorfs;
+  FD_ZERO(&master);
+  FD_ZERO(&readfs);
+  FD_ZERO(&errorfs);
+
 #ifndef NONTLS
   SSL_CTX_set_verify(ctx, verify_mode, verify_callback);
   SSL_CTX_set_ecdh_auto(ctx, 1);
@@ -381,6 +396,24 @@ int main(int argc,char *argv[]) {
   int ssl_err;
   int err_err;
   //fprintf(stderr,"made it here\n");
+  // !!! it is possible that the read() inside of SSL_accept gets stuck because stdin is still open, but there's nothing to read...
+  // closing the file descriptor in gdb causes the program to exit here.
+
+  // select is failing to prevent getting stuck in an interruptible sleep in SSL_accept.
+  // so we're gonna use an alarm I guess.
+  alarm(120);// give them two minutes...
+
+  FD_SET(0,&master);//SSL is ready to be read from
+  readfs=master;
+  errorfs=master;
+  timeout=orig_timeout;
+  select(1,&readfs,0,&errorfs,&timeout);
+  // anything except ready to read is an exitable situation
+  if(!FD_ISSET(0,&readfs)) {
+    syslog(LOG_ERR,"%s -> %s select timeout or error or something before SSL_accept()",ru,su);
+    return 1;
+  }
+
   if((err=SSL_accept(ssl)) <= 0) {
     ssl_err = SSL_get_error(ssl,err); //this value should NOT get passed to ERR_error_string.
     if(ssl_err == SSL_ERROR_SYSCALL) {
@@ -420,6 +453,7 @@ int main(int argc,char *argv[]) {
     //fprintf(stderr,"SSL_accept() failed. %s\n",ERR_lib_error_string(SSL_get_error(ssl,err)));
     return 1;
   }
+  alarm(0);// disable the alarm since we got passed SSL_accept.
 #ifdef JA3
   tlswrap_SSL_client_features(&ja3,ssl);
   ja3_shit(&ja3);
@@ -479,20 +513,10 @@ int main(int argc,char *argv[]) {
   int r2;
   int r3;
   int fdmax=0;
-  fd_set master;
-  fd_set readfs;
-  fd_set errorfs;
-  FD_ZERO(&master);
-  FD_ZERO(&readfs);
-  FD_ZERO(&errorfs);
   FD_SET(0,&master);//SSL is ready to be read from
   FD_SET(b[0],&master);//subprocess's stdout is ready to be read from
   FD_SET(c[0],&master);//subprocess's stderr
   fdmax=b[0]>c[0]?b[0]:c[0];
-  struct timeval orig_timeout;
-  struct timeval timeout;
-  orig_timeout.tv_sec=60;// we give it a WHOLE MINUTE to get done with stuff...
-  orig_timeout.tv_usec=0;// 1/100th of a second. (10ms) sound good?
   close(a[0]);
   close(b[1]);
   close(c[1]);
@@ -636,9 +660,12 @@ int main(int argc,char *argv[]) {
     // loop while we have descendent processes that have exited and clean them up.
     syslog(LOG_DEBUG,"<%s> waitpid() for -%d ...",url,child);
     while((pid=waitpid(-child,&status,WNOHANG)) > 0) { // and if they exit normally, that's good...
-      syslog(LOG_DEBUG,"<%s> a descendent process %d exited. exitstatus: %d",url,pid,WEXITSTATUS(status));
+      syslog(LOG_DEBUG,"<%s> a descendent process %d %s exited. exitstatus: %d",url,pid,command_line,WEXITSTATUS(status));
       if(WEXITSTATUS(status) != 0) {
-        syslog(LOG_ERR,"<%s> a descendent process %d exited, but with 'error' exitstatus: %d",url,pid,WEXITSTATUS(status));
+        syslog(LOG_ERR,"<%s> a descendent process %d %s exited, but with 'error' exitstatus: %d",url,pid,command_line,WEXITSTATUS(status));
+        if(WEXITSTATUS(status) == 141) {
+          syslog(LOG_ERR,"<%s> exit status 141 is likely a SIGPIPE caused by tlswrap closing subprocess's file descriptors.",url);
+        }
       }
     }
     syslog(LOG_DEBUG,"<%s> out of waitpid() for -%d loop",url,child);

-----END OF PAGE-----