Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • develop
  • v2021.a
  • v2020.a
  • v2019.a
  • v2018.b
6 results

RedstartRunCirculatingSourceDialog.h

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    VioSSL.cc 5.88 KiB
    /* 
    **  Virtual I/O library for SSL wrapper
    **  Written by Andrei Errapart <andreie@no.spam.ee>
    */
    
    /*
     * This file has some huge DBUG_ statements. Boy, this is silly...
     */
    
    #include	"vio-global.h"
    #ifdef	VIO_HAVE_OPENSSL
    #include	<assert.h>
    #include	<netinet/in.h>
    #include	<openssl/x509.h>
    #include	<openssl/ssl.h>
    #include	<openssl/err.h>
    #include	<openssl/pem.h>
    
    #ifdef __GNUC__
    #pragma implementation				// gcc: Class implementation
    #endif
    
    VIO_NS_BEGIN
    
    #define this_ssl_con	my_static_cast(SSL*)(this->ssl_con_)
    #define this_bio	my_static_cast(BIO*)(this->bio_)
    typedef char*		dataptr_t;
    
    static void
    report_errors()
    {
      unsigned long	l;
      const char*	file;
      const char*	data;
      int		line,flags;
      DBUG_ENTER("VioSSLConnectorFd::report_errors");
    
      while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
      {
        char buf[200];
        DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
    			 file,line,(flags&ERR_TXT_STRING)?data:"")) ;
      }
      DBUG_VOID_RETURN;
    }
    
    //FIXME: duplicate code!
    VioSSL::VioSSL(int fd,
    	       vio_ptr	ssl_context,
    	       int state)
      : bio_(0), ssl_con_(0), open_(FALSE), sd_(new VioSocket(fd))
    {
      DBUG_ENTER("VioSSL::VioSSL");
      DBUG_PRINT("enter", ("this=%p, fd=%d, ssl_context=%p, state=%d",
    		       this, fd, ssl_context, state));
      assert(fd!=0);
      assert(ssl_context!=0);
      assert(state==state_connect || state==state_accept);
    
      if (!init_bio_(fd, ssl_context, state, BIO_NOCLOSE))
        open_ = true;
      DBUG_VOID_RETURN;
    }
    
    
    VioSSL::VioSSL(VioSocket* sd,
    	       vio_ptr	 ssl_context,
    	       int state)
      :bio_(0), ssl_con_(0), open_(FALSE), sd_(sd)
    {
      DBUG_ENTER("VioSSL::VioSSL");
      DBUG_PRINT("enter",
    	     ("this=%p, sd=%s, ssl_context=%p, state=%d",
    	      this, sd ? sd->description() : "0", ssl_context, state));
      assert(sd != 0);
      assert(ssl_context != 0);
      assert(state == state_connect || state==state_accept);
    
      if (!init_bio_(sd->sd_, ssl_context, state, BIO_NOCLOSE))
        open_ = true;
      DBUG_VOID_RETURN;
    }
    
    VioSSL::~VioSSL()
    {
      DBUG_ENTER("VioSSL::~VioSSL");
      DBUG_PRINT("enter", ("this=%p", this));
      if (ssl_con_!=0)
      {
        SSL_shutdown(this_ssl_con);
        SSL_free(this_ssl_con);
      }
      if (sd_!=0)
        delete sd_;
      /* FIXME: no need to close bio? */
      /*
        if (bio_!=0)
        BIO_free(this_bio);
      */
      DBUG_VOID_RETURN;
    }
    
    bool
    VioSSL::is_open() const
    {
      return open_;
    }
    
    int
    VioSSL::read(vio_ptr buf, int size)
    {
      int r;
      DBUG_ENTER("VioSSL::read");
      DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
      assert(this_ssl_con != 0);
      r = SSL_read(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
      if ( r< 0)
        report_errors();
      DBUG_PRINT("exit", ("r=%d", r));
      DBUG_RETURN(r);
    }
    
    int
    VioSSL::write(const vio_ptr buf, int size)
    {
      int r;
      DBUG_ENTER("VioSSL::write");
      DBUG_PRINT("enter", ("this=%p, buf=%p, size=%d", this, buf, size));
      assert(this_ssl_con!=0);
      r = SSL_write(this_ssl_con, my_static_cast(dataptr_t)(buf), size);
      if (r<0)
        report_errors();
      DBUG_PRINT("exit", ("r=%d", r));
      DBUG_RETURN(r);
    }
    
    int
    VioSSL::blocking(bool onoff)
    {
      int r;
      DBUG_ENTER("VioSSL::blocking");
      DBUG_PRINT("enter", ("this=%p, onoff=%s", this, onoff?"true":"false"));
      r = sd_->blocking(onoff);
      DBUG_PRINT("exit", ("r=%d", (int)r ));
      DBUG_RETURN(r);
    }
    
    bool 
    VioSSL::blocking() const
    {
      bool r;
      DBUG_ENTER("VioSSL::blocking");
      DBUG_PRINT("enter", ("this=%p", this));
      r = sd_->blocking();
      DBUG_PRINT("exit", ("r=%d", (int)r ));
      DBUG_RETURN(r);
    }
    
    int
    VioSSL::fastsend(bool onoff)
    {
      int r;
      DBUG_ENTER("VioSSL::fastsend");
      DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
      r = sd_->fastsend(onoff);
      DBUG_PRINT("exit", ("r=%d", (int)r ));
      DBUG_RETURN(r);
    }
    
    int VioSSL::keepalive(bool onoff)
    {
      int r;
      DBUG_ENTER("VioSSL::keepalive");
      DBUG_PRINT("enter", ("this=%p, onoff=%d", this, (int) onoff));
      r = sd_->keepalive(onoff);
      DBUG_PRINT("exit", ("r=%d", int(r) ));
      DBUG_RETURN(r);
    }
    
    bool
    VioSSL::fcntl() const
    {
      bool	r;
      DBUG_ENTER("VioSSL::fcntl");
      DBUG_PRINT("enter", ("this=%p", this));
      r = sd_->fcntl();
      DBUG_PRINT("exit", ("r=%d", (int)r ));
      DBUG_RETURN(r);
    }
    
    bool
    VioSSL::should_retry() const
    {
      bool r;
      DBUG_ENTER("VioSSL::should_retry");
      DBUG_PRINT("enter", ("this=%p", this));
      r = sd_->should_retry();
      DBUG_PRINT("exit", ("r=%d", (int)r ));
      DBUG_RETURN(r);
    }
    
    int
    VioSSL::close()
    {
      int r= -2;
      DBUG_ENTER("VioSSL::close");
      DBUG_PRINT("enter", ("this=%p", this));
      if (ssl_con)
      {
        r = SSL_shutdown(this_ssl_con);
        SSL_free(this_ssl_con);
        ssl_con_ = 0;
        BIO_free(this_bio);
        bio_ = 0;
      }
      DBUG_PRINT("exit", ("r=%d", r));
      DBUG_RETURN(r);
    }
    
    const char*
    VioSSL::description() const
    {
      return desc_;
    }
    
    const char*
    VioSSL::peer_addr() const
    {
      if (sd_!=0)
        return sd != 0 ? sd_->peer_addr() : "";
    }
    
    const char*
    VioSSL::peer_name() const
    {
      return sd != 0 ? sd_->peer_name() : "";
    }
    
    const char*
    VioSSL::cipher_description() const
    {
      return SSL_get_cipher_name(this_ssl_con);
    }
    
    
    int
    VioSSL::init_bio_(int fd,
    		  vio_ptr ssl_context,
    		  int state,
    		  int bio_flags)
    {
      DBUG_ENTER("VioSSL::init_bio_");
      DBUG_PRINT("enter",
    	     ("this=%p, fd=%p, ssl_context=%p, state=%d, bio_flags=%d",
    	      this, fd, ssl_context, state, bio_flags));
    
      
      if (!(ssl_con_ = SSL_new(my_static_cast(SSL_CTX*)(ssl_context))))
     {
        DBUG_PRINT("error", ("SSL_new failure"));
        report_errors();
        DBUG_RETURN(-1);
      }
      if (!(bio_ = BIO_new_socket(fd, bio_flags)))
      {
        DBUG_PRINT("error", ("BIO_new_socket failure"));
        report_errors();
        SSL_free(ssl_con_);
        ssl_con_ =0;
        DBUG_RETURN(-1);
      }
      SSL_set_bio(this_ssl_con, this_bio, this_bio);
      switch(state) {
      case state_connect:
        SSL_set_connect_state(this_ssl_con);
        break;
      case state_accept:
        SSL_set_accept_state(this_ssl_con);
        break;
      default:
        assert(0);
      }
      sprintf(desc_, "VioSSL(%d)", fd);
      ssl_cip_ = new SSL_CIPHER ;
      DBUG_RETURN(0);
    }
    
    
    VIO_NS_END
    
    #endif /* VIO_HAVE_OPENSSL */