]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Misc fixes to r6708.
authorJames Yonan <james@openvpn.net>
Mon, 13 Dec 2010 09:27:08 +0000 (09:27 +0000)
committerDavid Sommerseth <davids@redhat.com>
Fri, 25 Mar 2011 08:38:48 +0000 (09:38 +0100)
Fixed issue where "signal SIGTERM" entered from the management
interface might get subsequently downgraded to a SIGUSR1.

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@6716 e7ae566f-a301-0410-adde-c780ea21d3b5

base64.c
forward.c
init.c
manage.c
manage.h
sig.c
sig.h
ssl.c

index 8f0fb6c04f382552af528ef085cbd0a96a99a2d2..26ca7d711d09fad9f5ddd6e7004c55f587c312fc 100644 (file)
--- a/base64.c
+++ b/base64.c
@@ -50,6 +50,8 @@ base64_encode(const void *data, int size, char **str)
     int c;
     const unsigned char *q;
 
+    if (size < 0)
+       return -1;
     p = s = (char *) malloc(size * 4 / 3 + 4);
     if (p == NULL)
        return -1;
index 87d05cccda7ddd078484ee206a44ad0e773f965c..254d827f09f88fa7f300f42973a3160a659f6a7c 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -98,8 +98,7 @@ check_tls_dowork (struct context *c)
        }
       else if (tmp_status == TLSMP_KILL)
        {
-         c->sig->signal_received = SIGTERM;
-         c->sig->signal_text = "auth-control-exit";
+         register_signal (c, SIGTERM, "auth-control-exit");
        }
 
       interval_future_trigger (&c->c2.tmp_int, wakeup);
@@ -118,15 +117,13 @@ void
 check_tls_errors_co (struct context *c)
 {
   msg (D_STREAM_ERRORS, "Fatal TLS error (check_tls_errors_co), restarting");
-  c->sig->signal_received = c->c2.tls_exit_signal; /* SOFT-SIGUSR1 -- TLS error */
-  c->sig->signal_text = "tls-error";
+  register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */
 }
 
 void
 check_tls_errors_nco (struct context *c)
 {
-  c->sig->signal_received = c->c2.tls_exit_signal; /* SOFT-SIGUSR1 -- TLS error */
-  c->sig->signal_text = "tls-error";
+  register_signal (c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */
 }
 
 #endif
@@ -287,8 +284,7 @@ check_add_routes_dowork (struct context *c)
        {
          if (!tun_standby (c->c1.tuntap))
            {
-             c->sig->signal_received = SIGHUP;
-             c->sig->signal_text = "ip-fail";
+             register_signal (c, SIGHUP, "ip-fail");
              c->persist.restart_sleep_seconds = 10;
 #ifdef WIN32
              show_routes (M_INFO|M_NOPREFIX);
@@ -310,8 +306,7 @@ void
 check_inactivity_timeout_dowork (struct context *c)
 {
   msg (M_INFO, "Inactivity timeout (--inactive), exiting");
-  c->sig->signal_received = SIGTERM;
-  c->sig->signal_text = "inactive";
+  register_signal (c, SIGTERM, "inactive");
 }
 
 #if P2MP
@@ -323,8 +318,7 @@ check_server_poll_timeout_dowork (struct context *c)
   if (!tls_initial_packet_received (c->c2.tls_multi))
     {
       msg (M_INFO, "Server poll timeout, restarting");
-      c->sig->signal_received = SIGUSR1;
-      c->sig->signal_text = "server_poll";
+      register_signal (c, SIGUSR1, "server_poll");
       c->persist.restart_sleep_seconds = -1;
     }
 }
@@ -349,8 +343,7 @@ schedule_exit (struct context *c, const int n_seconds, const int signal)
 void
 check_scheduled_exit_dowork (struct context *c)
 {
-  c->sig->signal_received = c->c2.scheduled_exit_signal;
-  c->sig->signal_text = "delayed-exit";
+  register_signal (c, c->c2.scheduled_exit_signal, "delayed-exit");
 }
 
 #endif
@@ -675,8 +668,7 @@ read_incoming_link (struct context *c)
          const struct buffer *fbuf = socket_foreign_protocol_head (c->c2.link_socket);
          const int sd = socket_foreign_protocol_sd (c->c2.link_socket);
          port_share_redirect (port_share, fbuf, sd);
-         c->sig->signal_received = SIGTERM;
-         c->sig->signal_text = "port-share-redirect";
+         register_signal (c, SIGTERM, "port-share-redirect");
        }
       else
 #endif
@@ -684,8 +676,7 @@ read_incoming_link (struct context *c)
        /* received a disconnect from a connection-oriented protocol */
        if (c->options.inetd)
          {
-           c->sig->signal_received = SIGTERM;
-           c->sig->signal_text = "connection-reset-inetd";
+           register_signal (c, SIGTERM, "connection-reset-inetd");
            msg (D_STREAM_ERRORS, "Connection reset, inetd/xinetd exit [%d]", status);
          }
        else
@@ -699,8 +690,7 @@ read_incoming_link (struct context *c)
            else
 #endif
              {
-               c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- TCP connection reset */
-               c->sig->signal_text = "connection-reset";
+               register_signal (c, SIGUSR1, "connection-reset"); /* SOFT-SIGUSR1 -- TCP connection reset */
                msg (D_STREAM_ERRORS, "Connection reset, restarting [%d]", status);
              }
          }
@@ -824,8 +814,7 @@ process_incoming_link (struct context *c)
       if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket))
        {
          /* decryption errors are fatal in TCP mode */
-         c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- decryption error in TCP mode */
-         c->sig->signal_text = "decryption-error";
+         register_signal (c, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */
          msg (D_STREAM_ERRORS, "Fatal decryption error (process_incoming_link), restarting");
          goto done;
        }
@@ -937,8 +926,7 @@ read_incoming_tun (struct context *c)
   /* Was TUN/TAP interface stopped? */
   if (tuntap_stop (c->c2.buf.len))
     {
-      c->sig->signal_received = SIGTERM;
-      c->sig->signal_text = "tun-stop";
+      register_signal (c, SIGTERM, "tun-stop");
       msg (M_INFO, "TUN/TAP interface has been stopped, exiting");
       perf_pop ();
       return;            
diff --git a/init.c b/init.c
index d47a4ef20cb4dc693e5ad45752afac6fbbbd5f3c..a7c4b2be69690ca6731de88f3e51c21a92a0d627 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1162,7 +1162,6 @@ initialization_sequence_completed (struct context *c, const unsigned int flags)
        management_post_tunnel_open (management, tun_local);
     }
 #endif
-
 }
 
 /*
index 0c99d0fc5a890881a3c6bfef0cbdd9721eab3837..310a70ebbe82a297b910beed0a42e0dff2fdb566 100644 (file)
--- a/manage.c
+++ b/manage.c
@@ -776,12 +776,11 @@ man_hold (struct management *man, const char *cmd)
 
 #define IER_RESET      0
 #define IER_NEW        1
-#define IER_CONDRESET  2
 
 static void
 in_extra_reset (struct man_connection *mc, const int mode)
 {
-  if (mc && (mc->in_extra_cmd < IEC_STATEFUL_BASE || mode != IER_CONDRESET))
+  if (mc)
     {
       if (mode != IER_NEW)
        {
@@ -860,7 +859,10 @@ in_extra_dispatch (struct management *man)
 #endif
 #ifdef MANAGMENT_EXTERNAL_KEY
     case IEC_RSA_SIGN:
-      man->connection.in_extra_cmd = IEC_RSA_SIGN_FINAL;
+      man->connection.ext_key_state = EKS_READY;
+      buffer_list_free (man->connection.ext_key_input);
+      man->connection.ext_key_input = man->connection.in_extra;
+      man->connection.in_extra = NULL;
       return;
 #endif
     }
@@ -1014,10 +1016,11 @@ static void
 man_rsa_sig (struct management *man)
 {
   struct man_connection *mc = &man->connection;
-  if (mc->in_extra_cmd == IEC_RSA_SIGN_PRE)
+  if (mc->ext_key_state == EKS_SOLICIT)
     {
-      in_extra_reset (&man->connection, IER_NEW);
+      mc->ext_key_state = EKS_INPUT;
       mc->in_extra_cmd = IEC_RSA_SIGN;
+      in_extra_reset (mc, IER_NEW);
     }
   else
     msg (M_CLIENT, "ERROR: The rsa-sig command is not currently available");
@@ -1711,7 +1714,7 @@ man_process_command (struct management *man, const char *line)
   CLEAR (parms);
   so = status_open (NULL, 0, -1, &man->persist.vout, 0);
 #ifdef MANAGEMENT_IN_EXTRA
-  in_extra_reset (&man->connection, IER_CONDRESET);
+  in_extra_reset (&man->connection, IER_RESET);
 #endif
 
   if (man_password_needed (man))
@@ -2104,6 +2107,9 @@ man_connection_close (struct management *man)
     buffer_list_free (mc->out);
 #ifdef MANAGEMENT_IN_EXTRA
   in_extra_reset (&man->connection, IER_RESET);
+#endif
+#ifdef MANAGMENT_EXTERNAL_KEY
+  buffer_list_free (mc->ext_key_input);
 #endif
   man_connection_clear (mc);
 }
@@ -2927,14 +2933,14 @@ management_query_rsa_sig (struct management *man,
   struct buffer alert_msg = clear_buf();
   struct buffer *buf;
   const bool standalone_disabled_save = man->persist.standalone_disabled;
+  struct man_connection *mc = &man->connection;
 
   if (man_standalone_ok (man))
     {
       man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
       man->persist.special_state_msg = NULL;
 
-      in_extra_reset (&man->connection, IER_RESET);
-      man->connection.in_extra_cmd = IEC_RSA_SIGN_PRE;
+      mc->ext_key_state = EKS_SOLICIT;
 
       alert_msg = alloc_buf_gc (strlen(b64_data)+64, &gc);
       buf_printf (&alert_msg, ">RSA_SIGN:%s", b64_data);
@@ -2955,12 +2961,12 @@ management_query_rsa_sig (struct management *man,
            man_check_for_signals (&signal_received);
          if (signal_received)
            goto done;
-       } while (man->connection.in_extra_cmd != IEC_RSA_SIGN_FINAL);
+       } while (mc->ext_key_state != EKS_READY);
 
-      if (buffer_list_defined(man->connection.in_extra))
+      if (buffer_list_defined(mc->ext_key_input))
        {
-         buffer_list_aggregate (man->connection.in_extra, 2000);
-         buf = buffer_list_peek (man->connection.in_extra);
+         buffer_list_aggregate (mc->ext_key_input, 2048);
+         buf = buffer_list_peek (mc->ext_key_input);
          if (buf && BLEN(buf) > 0)
            {
              ret = (char *) malloc(BLEN(buf)+1);
@@ -2972,10 +2978,18 @@ management_query_rsa_sig (struct management *man,
     }
 
  done:
+  if (mc->ext_key_state == EKS_READY && ret)
+    msg (M_CLIENT, "SUCCESS: rsa-sig command succeeded");
+  else if (mc->ext_key_state == EKS_INPUT || mc->ext_key_state == EKS_READY)
+    msg (M_CLIENT, "ERROR: rsa-sig command failed");
+
   /* revert state */
   man->persist.standalone_disabled = standalone_disabled_save;
   man->persist.special_state_msg = NULL;
-  in_extra_reset (&man->connection, IER_RESET);
+  in_extra_reset (mc, IER_RESET);
+  mc->ext_key_state = EKS_UNDEF;
+  buffer_list_free (mc->ext_key_input);
+  mc->ext_key_input = NULL;
 
   gc_free (&gc);
   return ret;
index 697ddf87d1f86eff24bfd3a9ef1f8a97d47d7a2e..a8f971b8c38d7818b554f2f9159a7730c25e7cfe 100644 (file)
--- a/manage.h
+++ b/manage.h
@@ -268,11 +268,7 @@ struct man_connection {
 # define IEC_UNDEF       0
 # define IEC_CLIENT_AUTH 1
 # define IEC_CLIENT_PF   2
-
-# define IEC_STATEFUL_BASE  16
-# define IEC_RSA_SIGN_PRE   16
-# define IEC_RSA_SIGN       17
-# define IEC_RSA_SIGN_FINAL 18
+# define IEC_RSA_SIGN    3
   int in_extra_cmd;
   struct buffer_list *in_extra;
 #ifdef MANAGEMENT_DEF_AUTH
@@ -280,6 +276,14 @@ struct man_connection {
   unsigned int in_extra_kid;
   int env_filter_level;
 #endif
+#ifdef MANAGMENT_EXTERNAL_KEY
+# define EKS_UNDEF   0
+# define EKS_SOLICIT 1
+# define EKS_INPUT   2
+# define EKS_READY   3
+  int ext_key_state;
+  struct buffer_list *ext_key_input;
+#endif
 #endif
   struct event_set *es;
 
diff --git a/sig.c b/sig.c
index 631a3a86671b87e2d810bb848e20efed9d6eb8aa..d73525f59ed47c139c96b7b3b1e7190e6ed9ba16 100644 (file)
--- a/sig.c
+++ b/sig.c
@@ -366,3 +366,11 @@ process_signal (struct context *c)
     }
   return ret;
 }
+
+void
+register_signal (struct context *c, int sig, const char *text)
+{
+  if (c->sig->signal_received != SIGTERM)
+    c->sig->signal_received = sig;
+  c->sig->signal_text = text;
+}
diff --git a/sig.h b/sig.h
index be87fe490de378ecdba91aad4a779b6ef865d4fa..987efef564c8c3530e56955f74817a2a4cdfbb90 100644 (file)
--- a/sig.h
+++ b/sig.h
@@ -64,6 +64,8 @@ void signal_restart_status (const struct signal_info *si);
 
 bool process_signal (struct context *c);
 
+void register_signal (struct context *c, int sig, const char *text);
+
 #ifdef ENABLE_OCC
 void process_explicit_exit_notification_timer_wakeup (struct context *c);
 #endif
diff --git a/ssl.c b/ssl.c
index 66ee14d0f514079e59015a787ad40b7d4b348f68..9eec74ec824ce9567ee67e7d5381c5f2d6d051e5 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -1667,6 +1667,8 @@ use_certificate_file(SSL_CTX *ctx, const char *file, int type, X509 **x509)
     BIO_free(in);
   if (x509)
     *x509 = x;
+  else if (x)
+    X509_free (x);
   return(ret);
 }
 
@@ -1799,12 +1801,12 @@ use_inline_certificate_file (SSL_CTX *ctx, const char *cert_string, X509 **x509)
   ret = SSL_CTX_use_certificate(ctx, x);
 
  end:
-  if (x)
-    X509_free (x);
   if (in)
     BIO_free (in);
   if (x509)
     *x509 = x;
+  else if (x)
+    X509_free (x);
   return ret;
 }
 
@@ -2167,17 +2169,19 @@ init_ssl (const struct options *options)
        msg (M_SSLERR, "Problem with cipher list: %s", options->cipher_list);
     }
 
+ done:
   ERR_clear_error ();
-
+  if (my_cert)
+    X509_free(my_cert);
   return ctx;
 
  err:
-  ERR_clear_error ();
-  if (my_cert)
-    X509_free(my_cert);
   if (ctx)
-    SSL_CTX_free (ctx);
-  return NULL;
+    {
+      SSL_CTX_free (ctx);
+      ctx = NULL;
+    }
+  goto done;
 }
 
 /*