Пример #1
0
int MaOpenSslSocket::initConnection()
{
	BIO		*bioSSL, *bioSock;

	if (bio) {
		return 0;
	}
	bio = BIO_new(BIO_f_buffer());
	if (bio == 0) {
		return MPR_ERR_CANT_INITIALIZE;
	}

	BIO_set_write_buffer_size(bio, 128);
	ssl = (SSL*) SSL_new(context);
	mprAssert(ssl);
	if (ssl == 0) {
		return MPR_ERR_CANT_INITIALIZE;
	}
    SSL_set_app_data(ssl, (void*) this);

	SSL_set_session(ssl, 0);
	bioSSL = BIO_new(BIO_f_ssl());
	mprAssert(bioSSL);

	bioSock = BIO_new_socket(sock, BIO_NOCLOSE);
	mprAssert(bioSock);

	SSL_set_bio(ssl, bioSock, bioSock);
	SSL_set_accept_state(ssl);

	BIO_set_ssl(bioSSL, ssl, BIO_CLOSE);
	BIO_push(bio, bioSSL);
	return 0;
}
Пример #2
0
BIO* BIO_new_rdp_tls(SSL_CTX* ctx, int client)
{
	BIO* bio;
	SSL* ssl;
	bio = BIO_new(BIO_s_rdp_tls());

	if (!bio)
		return NULL;

	ssl = SSL_new(ctx);

	if (!ssl)
	{
		BIO_free(bio);
		return NULL;
	}

	if (client)
		SSL_set_connect_state(ssl);
	else
		SSL_set_accept_state(ssl);

	BIO_set_ssl(bio, ssl, BIO_CLOSE);
	return bio;
}
Пример #3
0
void
key_state_ssl_init(struct key_state_ssl *ks_ssl, const struct tls_root_ctx *ssl_ctx, bool is_server, struct tls_session *session)
{
  ASSERT(NULL != ssl_ctx);
  ASSERT(ks_ssl);
  CLEAR (*ks_ssl);

  ks_ssl->ssl = SSL_new (ssl_ctx->ctx);
  if (!ks_ssl->ssl)
    msg (M_SSLERR, "SSL_new failed");

  /* put session * in ssl object so we can access it
     from verify callback*/
  SSL_set_ex_data (ks_ssl->ssl, mydata_index, session);

  ks_ssl->ssl_bio = getbio (BIO_f_ssl (), "ssl_bio");
  ks_ssl->ct_in = getbio (BIO_s_mem (), "ct_in");
  ks_ssl->ct_out = getbio (BIO_s_mem (), "ct_out");

#ifdef BIO_DEBUG
  bio_debug_oc ("open ssl_bio", ks_ssl->ssl_bio);
  bio_debug_oc ("open ct_in", ks_ssl->ct_in);
  bio_debug_oc ("open ct_out", ks_ssl->ct_out);
#endif

  if (is_server)
    SSL_set_accept_state (ks_ssl->ssl);
  else
    SSL_set_connect_state (ks_ssl->ssl);

  SSL_set_bio (ks_ssl->ssl, ks_ssl->ct_in, ks_ssl->ct_out);
  BIO_set_ssl (ks_ssl->ssl_bio, ks_ssl->ssl, BIO_NOCLOSE);
}
Пример #4
0
bool SSLClient::connection(const string& host, const int& port)
{
	if(host=="localhost")
	{
		return connectionUnresolv(host, port);
	}

	struct sockaddr_in *remote;
	int tmpres;
	char *ip;

	sockfd = create_tcp_socket();
	ip = get_ip((char*)host.c_str());
	fprintf(stderr, "IP is %s\n", ip);
	remote = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *));
	remote->sin_family = AF_INET;
	tmpres = inet_pton(AF_INET, ip, (void *)(&(remote->sin_addr.s_addr)));
	if( tmpres < 0)
	{
		perror("Can't set remote->sin_addr.s_addr");
		return false;
	}
	else if(tmpres == 0)
	{
		fprintf(stderr, "%s is not a valid IP address\n", ip);
		return false;
	}
	remote->sin_port = htons(port);

	if(connect(sockfd, (struct sockaddr *)remote, sizeof(struct sockaddr)) < 0){
		perror("Could not connect");
		connected = false;
	} else {
		connected = true;
	}

	free(remote);
	free(ip);

	/* Build our SSL context*/
	init();

	/* Connect the SSL socket */
	ssl=SSL_new(ctx);
	sbio=BIO_new_socket(sockfd,BIO_CLOSE);
	SSL_set_bio(ssl,sbio,sbio);
	io=BIO_new(BIO_f_buffer());
	ssl_bio=BIO_new(BIO_f_ssl());
	BIO_set_ssl(ssl_bio,ssl,BIO_NOCLOSE);
	BIO_push(io,ssl_bio);

	if(SSL_connect(ssl)<=0)
	{
		logger << "SSL connect error";
		return false;
	}
	ERR_clear_error();
	connected = true;
	return true;
}
Пример #5
0
static int init_ssl_socket( pn_ssl_t *ssl )
{
  if (ssl->ssl) return 0;
  if (!ssl->domain) return -1;

  ssl->ssl = SSL_new(ssl->domain->ctx);
  if (!ssl->ssl) {
    _log_error( "SSL socket setup failure.\n" );
    return -1;
  }

  // store backpointer to pn_ssl_t in SSL object:
  SSL_set_ex_data(ssl->ssl, ssl_ex_data_index, ssl);

#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  if (ssl->peer_hostname && ssl->domain->mode == PN_SSL_MODE_CLIENT) {
    SSL_set_tlsext_host_name(ssl->ssl, ssl->peer_hostname);
  }
#endif

  // restore session, if available
  if (ssl->session_id) {
    pn_ssl_session_t *ssn = ssn_cache_find( ssl->domain, ssl->session_id );
    if (ssn) {
      _log( ssl, "Restoring previous session id=%s\n", ssn->id );
      int rc = SSL_set_session( ssl->ssl, ssn->session );
      if (rc != 1) {
        _log( ssl, "Session restore failed, id=%s\n", ssn->id );
      }
      LL_REMOVE( ssl->domain, ssn_cache, ssn );
      ssl_session_free( ssn );
    }
  }

  // now layer a BIO over the SSL socket
  ssl->bio_ssl = BIO_new(BIO_f_ssl());
  if (!ssl->bio_ssl) {
    _log_error( "BIO setup failure.\n" );
    return -1;
  }
  (void)BIO_set_ssl(ssl->bio_ssl, ssl->ssl, BIO_NOCLOSE);

  // create the "lower" BIO "pipe", and attach it below the SSL layer
  if (!BIO_new_bio_pair(&ssl->bio_ssl_io, 0, &ssl->bio_net_io, 0)) {
    _log_error( "BIO setup failure.\n" );
    return -1;
  }
  SSL_set_bio(ssl->ssl, ssl->bio_ssl_io, ssl->bio_ssl_io);

  if (ssl->domain->mode == PN_SSL_MODE_SERVER) {
    SSL_set_accept_state(ssl->ssl);
    BIO_set_ssl_mode(ssl->bio_ssl, 0);  // server mode
    _log( ssl, "Server SSL socket created.\n" );
  } else {      // client mode
    SSL_set_connect_state(ssl->ssl);
    BIO_set_ssl_mode(ssl->bio_ssl, 1);  // client mode
    _log( ssl, "Client SSL socket created.\n" );
  }
  return 0;
}
Пример #6
0
R_API RSocket *r_socket_accept(RSocket *s) {
	RSocket *sock;
	if (!s) return NULL;
	sock = R_NEW (RSocket);
	if (!sock) return NULL;
	sock->is_ssl = s->is_ssl;
	sock->fd = accept (s->fd, NULL, NULL);
	if (sock->fd == -1) {
		free (sock);
		return NULL;
	}
#if HAVE_LIB_SSL
	if (sock->is_ssl) {
		sock->sfd = NULL;
		sock->ctx = NULL;
		sock->bio = NULL;
		BIO *sbio = BIO_new_socket (sock->fd, BIO_NOCLOSE);
		sock->sfd = SSL_new (s->ctx);
		SSL_set_bio (sock->sfd, sbio, sbio);
		if (SSL_accept (sock->sfd) <= 0) {
			r_socket_free (sock);
			return NULL;
		}
		sock->bio = BIO_new (BIO_f_buffer ());
		sbio = BIO_new (BIO_f_ssl ());
		BIO_set_ssl (sbio, sock->sfd, BIO_CLOSE);
		BIO_push (sock->bio, sbio);
	}
#endif
	return sock;
}
Пример #7
0
R_API RSocket *r_socket_accept(RSocket *s) {
	RSocket *sock;
	socklen_t salen = sizeof (s->sa);
	if (!s) return NULL;
	sock = R_NEW (RSocket);
	if (!sock) return NULL;
	//signal (SIGPIPE, SIG_DFL);
	sock->fd = accept (s->fd, (struct sockaddr *)&s->sa, &salen);
	if (sock->fd == -1) {
		free (sock);
		return NULL;
	}
#if HAVE_LIB_SSL
	sock->is_ssl = s->is_ssl;
	if (sock->is_ssl) {
		sock->sfd = NULL;
		sock->ctx = NULL;
		sock->bio = NULL;
		BIO *sbio = BIO_new_socket (sock->fd, BIO_NOCLOSE);
		sock->sfd = SSL_new (s->ctx);
		SSL_set_bio (sock->sfd, sbio, sbio);
		if (SSL_accept (sock->sfd) <= 0) {
			r_socket_free (sock);
			return NULL;
		}
		sock->bio = BIO_new (BIO_f_buffer ());
		sbio = BIO_new (BIO_f_ssl ());
		BIO_set_ssl (sbio, sock->sfd, BIO_CLOSE);
		BIO_push (sock->bio, sbio);
	}
#else
	sock->is_ssl = 0;
#endif
	return sock;
}
Пример #8
0
void* conn_handler(void *arg)
{
        long err;
        SSL *ssl;
        struct conn_ctx *ctx = (struct conn_ctx *)arg;
        struct freeq_ctx *freeqctx = ctx->srvctx->freeqctx;
        struct freeqd_state *fst = ctx->srvctx->fst;
        BIO *client = ctx->client;

        pthread_detach(pthread_self());

        ssl = freeq_ssl_new(freeqctx);
        SSL_set_bio(ssl, client, client);
        if (SSL_accept(ssl) <= 0)
        {
                int_error("Error accepting SSL connection");
                return NULL;
        }

        if ((err = post_connection_check(freeqctx, ssl, "localhost")) != X509_V_OK)
        {
                err(freeqctx, "error: peer certificate: %s\n", X509_verify_cert_error_string(err));
                int_error("Error checking SSL object after connection");
        }

        BIO  *buf_io, *ssl_bio;
        buf_io = BIO_new(BIO_f_buffer());
        ssl_bio = BIO_new(BIO_f_ssl());
        BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
        BIO_push(buf_io, ssl_bio);

        dbg(freeqctx, "ssl client connection opened\n");
        if (generation_table_merge(freeqctx, fst, buf_io))
        {
                err(freeqctx, "table merge failed\n");
                SSL_shutdown(ssl);
        }
        else
        {
                dbg(freeqctx, "table merged ok\n");
                SSL_clear(ssl);
        }

        dbg(freeqctx, "ssl client connection closed\n");
        SSL_free(ssl);

        ERR_remove_state(0);
        return 0;
}
Пример #9
0
HybridSslConnection*
hybrid_ssl_connect(const gchar *hostname, gint port, ssl_callback func,
                   gpointer user_data)
{
    BIO                 *buf_io;
    BIO                 *ssl_bio;
    HybridSslConnection *conn;

    g_return_val_if_fail(hostname != NULL, NULL);
    g_return_val_if_fail(port != 0, NULL);
    g_return_val_if_fail(func != NULL, NULL);

    SSLeay_add_all_algorithms();
    SSL_load_error_strings();
    SSL_library_init();

    conn = g_new0(HybridSslConnection, 1);

    if (!(conn->ssl_ctx = SSL_CTX_new(SSLv23_client_method()))) {
        hybrid_debug_error("ssl", "initialize SSL CTX: %s",
                           ERR_reason_error_string(ERR_get_error()));
        hybrid_ssl_connection_destory(conn);
        return NULL;
    }

    if (!(conn->ssl = ssl_new_with_certs(conn->ssl_ctx))) {
        hybrid_ssl_connection_destory(conn);
        return NULL;
    }

    SSL_set_mode(conn->ssl, SSL_MODE_AUTO_RETRY);

    buf_io  = BIO_new(BIO_f_buffer());
    ssl_bio = BIO_new(BIO_f_ssl());

    BIO_set_ssl(ssl_bio, conn->ssl, BIO_NOCLOSE);
    BIO_push(buf_io, ssl_bio);

    conn->conn_cb   = func;
    conn->conn_data = user_data;
    conn->rbio      = buf_io;

    conn->conn = hybrid_proxy_connect(hostname, port, ssl_connect_cb, conn);

    return conn;
}
Пример #10
0
BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
{
    BIO *ret;
    SSL *ssl;

    if ((ret = BIO_new(BIO_f_ssl())) == NULL)
        return NULL;
    if ((ssl = SSL_new(ctx)) == NULL) {
        BIO_free(ret);
        return NULL;
    }
    if (client)
        SSL_set_connect_state(ssl);
    else
        SSL_set_accept_state(ssl);

    BIO_set_ssl(ret, ssl, BIO_CLOSE);
    return ret;
}
Пример #11
0
void handle_table(struct freeq_ctx *ctx, SSL *ssl)
{
        BIO  *buf_io, *ssl_bio;
        //char rbuf[1024];
        //char wbuf[1024];

        buf_io = BIO_new(BIO_f_buffer());         /* create a buffer BIO */
        ssl_bio = BIO_new(BIO_f_ssl());           /* create an ssl BIO */
        BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);     /* assign the ssl BIO to SSL */
        BIO_push(buf_io, ssl_bio);                /* add ssl_bio to buf_io */

        /* ret = BIO_puts(buf_io, wbuf); */
        /* Write contents of wbuf[] into buf_io */
        /* ret = BIO_write(buf_io, wbuf, wlen); */
        /* Write wlen-byte contents of wbuf[] into buf_io */

        /* ret = BIO_gets(buf_io, rbuf, READBUF_SIZE);  */
        /* Read data from buf_io and store in rbuf[] */
        /* ret = BIO_read(buf_io, rbuf, rlen);            */
        /* Read rlen-byte data from buf_io and store rbuf[] */
}
Пример #12
0
void ServiceTask::run()
{
	//logger << dlib << endl;
	string ip = "invalid session";
	string alldatlg = "\ngot fd from parent";
	SSL *ssl=NULL;
	BIO *sbio=NULL;
	BIO *io=NULL,*ssl_bio=NULL;
	try
	{
		int cntlen = 0;
		char buf[MAXBUFLENM];
		strVec results;
		stringstream ss;
		string temp;
		//int bytes = -1;
		if(isSSLEnabled)
		{
			sbio=BIO_new_socket(fd,BIO_NOCLOSE);
			ssl=SSL_new(ctx);
			SSL_set_bio(ssl,sbio,sbio);

			io=BIO_new(BIO_f_buffer());
			ssl_bio=BIO_new(BIO_f_ssl());
			BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
			BIO_push(io,ssl_bio);

			int r = SSL_accept(ssl);
			cout << r << endl;
			int bser = SSL_get_error(ssl,r);
			cout << bser << endl;
			if(r<=0)
			{
				sslHandler.error_occurred((char*)"SSL accept error",fd,ssl);
				return;
			}


			int er=-1;
			bool flag = true;
			while(flag)
			{
				er = BIO_gets(io,buf,BUFSIZZ-1);
				cout << er << endl;
				int bser = SSL_get_error(ssl,er);
				cout << bser << endl;
				switch(bser)
				{
					case SSL_ERROR_WANT_READ:
					{
						logger << "more to read error" << endl;
						break;
					}
					case SSL_ERROR_WANT_WRITE:
					{
						logger << "more to write error" << endl;
						break;
					}
					case SSL_ERROR_NONE:
					{
						break;
					}
					case SSL_ERROR_ZERO_RETURN:
					{
						sslHandler.error_occurred((char*)"SSL error problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
					default:
					{
						sslHandler.error_occurred((char*)"SSL read problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
				}
				ss << buf;
				//logger <<buf <<endl;
				if(!strcmp(buf,"\r\n") || !strcmp(buf,"\n"))
					break;
				string temp(buf);
				if(temp=="")continue;
				temp = temp.substr(0,temp.length()-1);
				results.push_back(temp);
				//logger << temp <<endl;
				if(temp.find("Content-Length:")!=string::npos)
				{
					std::string cntle = temp.substr(temp.find(": ")+2);
					cntle = cntle.substr(0,cntle.length()-1);
					//logger << "contne-length="<<cntle <<endl;
					try
					{
						cntlen = CastUtil::lexical_cast<int>(cntle);
					}
					catch(const char* ex)
					{
						logger << "bad lexical cast" <<endl;
					}
				}
				memset(&buf[0], 0, sizeof(buf));
			}
		}
		else
		{
			int er=-1;
			bool flag = true;
			sbio=BIO_new_socket(fd,BIO_CLOSE);
			io=BIO_new(BIO_f_buffer());
			BIO_push(io,sbio);
			logger << "into run method" << endl;
			while(flag)
			{
				er = BIO_gets(io,buf,BUFSIZZ-1);
				if(er==0)
				{
					close(fd);
					logger << "\nsocket closed before being serviced" <<flush;
					return;
				}
				ss << buf;
				if(!strcmp(buf,"\r\n") || !strcmp(buf,"\n") || er<0)
					break;
				string temp(buf);
				temp = temp.substr(0,temp.length()-1);
				results.push_back(temp);
				//logger << temp <<endl;
				if(temp.find("Content-Length:")!=string::npos)
				{
					std::string cntle = temp.substr(temp.find(": ")+2);
					cntle = cntle.substr(0,cntle.length()-1);
					//logger << "contne-length="<<cntle <<endl;
					try
					{
						cntlen = CastUtil::lexical_cast<int>(cntle);
					}
					catch(const char* ex)
					{
						logger << "bad lexical cast" <<endl;
					}
				}
				memset(&buf[0], 0, sizeof(buf));
			}
		}

		ss.clear();
		if(isSSLEnabled && cntlen>0)
		{
			int er=-1;
			if(cntlen>0)
			{
				//logger << "reading conetnt " << cntlen << endl;
				er = BIO_read(io,buf,cntlen);
				switch(SSL_get_error(ssl,er))
				{
					case SSL_ERROR_NONE:
						cntlen -= er;
						break;
					case SSL_ERROR_ZERO_RETURN:
					{
						sslHandler.error_occurred((char*)"SSL error problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
					default:
					{
						sslHandler.error_occurred((char*)"SSL read problem",fd,ssl);
						if(io!=NULL)BIO_free(io);
						return;
					}
				}
				string temp(buf);
				results.push_back("\r");
				results.push_back(temp);
				//logger <<buf <<endl;
				memset(&buf[0], 0, sizeof(buf));
			}
		}
		else if(cntlen>0)
		{
			int er=-1;
			if(cntlen>0)
			{
				//logger << "reading conetnt " << cntlen << endl;
				er = BIO_read(io,buf,cntlen);
				if(er==0)
				{
					close(fd);
					logger << "\nsocket closed before being serviced" <<flush;
					return;
				}
				else if(er>0)
				{
					string temp(buf);
					results.push_back("\r");
					results.push_back(temp);
					//logger << temp <<endl;
					memset(&buf[0], 0, sizeof(buf));
				}
			}
		}
		alldatlg += "--read data";
		map<string,string> params1 = *params;
		string webpath = serverRootDirectory + "web/";
		HttpRequest* req= new HttpRequest(results,webpath);
		//logger << req->toString() << endl;

		if(req->getFile()=="")
		{
			logger << req->getFile() << endl;
			req->setFile("index.html");
		}
		if(req->hasCookie())
		{
			logger << "has the session id" << endl;
			if(!configData.sessatserv)
				req->getSession()->setSessionAttributes(req->getCookieInfo());
			else
			{
				string id = req->getCookieInfoAttribute("FFEADID");
				logger << id << endl;
				map<string,string> values = readFromSharedMemeory(id);
				req->getSession()->setSessionAttributes(values);
			}
		}

		if(configData.cntMap[req->getCntxt_name()]!="true")
		{
			req->setCntxt_name("default");
			req->setCntxt_root(webpath+"default");
			req->setUrl(webpath+"default"+req->getActUrl());
		}
		//logger << req->getCntxt_name() << req->getCntxt_root() << req->getUrl() << endl;

		if(configData.appMap[req->getCntxt_name()]!="false")
		{
			if(dlib == NULL)
			{
				cerr << dlerror() << endl;
				exit(-1);
			}
			string meth1 = (req->getCntxt_name()+"checkRules");
			string path1;
			void *mkr1 = dlsym(dlib, meth1.c_str());
			if(mkr1!=NULL)
			{
				typedef string (*DCPPtr1) (string,HttpSession);
				DCPPtr1 f =  (DCPPtr1)mkr1;
				path1 = f(req->getUrl(),*(req->getSession()));
				//logger << path1 << flush;
				if(path1=="FAILED")
				{
					req->setUrl("");
				}
				else if(path1!="" && path1!=req->getUrl())
				{
					req->setUrl(path1);
				}
			}
		}

		HttpResponse res;
		string ext = getFileExtension(req->getUrl());
		vector<unsigned char> test;
		string content;
		string claz;
		bool isoAuthRes = false;
		long sessionTimeoutVar = configData.sessionTimeout;
		bool isContrl = securityHandler.handle(configData.ip_address, req, res, configData.securityObjectMap, sessionTimeoutVar, dlib, configData.cntMap);

		filterHandler.handleIn(req, res, configData.filterMap, dlib, ext);

		if(!isContrl)
		{
			isContrl = authHandler.handle(configData.autMap, configData.autpattMap, req, res, configData.filterMap, dlib, ext);
		}
		string pthwofile = req->getCntxt_name()+req->getActUrl();
		if(req->getCntxt_name()!="default" && configData.cntMap[req->getCntxt_name()]=="true")
		{
			pthwofile = req->getActUrl();
		}
		if(!isContrl)
		{
			isContrl = controllerHandler.handle(req, res, configData.urlpattMap, configData.mappattMap, dlib, ext,
					configData.rstCntMap, configData.mapMap, configData.urlMap, pthwofile);
		}

		/*After going through the controller the response might be blank, just set the HTTP version*/
		res.setHttpVersion(req->getHttpVersion());
		//logger << req->toString() << endl;
		if(req->getMethod()!="TRACE")
		{
			if(isContrl)
			{

			}
			else if(ext==".form")
			{
				formHandler.handle(req, res, configData.formMap, dlib);
			}
			else if((req->getContent_type().find("application/soap+xml")!=string::npos || req->getContent_type().find("text/xml")!=string::npos)
					&& (req->getContent().find("<soap:Envelope")!=string::npos || req->getContent().find("<soapenv:Envelope")!=string::npos)
					&& configData.wsdlmap[req->getFile()]==req->getCntxt_name())
			{
				soapHandler.handle(req, res, dlib, configData.props[".xml"]);
			}
			else
			{
				bool cntrlit = scriptHandler.handle(req, res, configData.handoffs, dlib, ext, configData.props);
				logger << "html page requested" <<endl;
				if(cntrlit)
				{

				}
				else
				{
					cntrlit = extHandler.handle(req, res, dlib, configData.resourcePath, configData.tmplMap, configData.vwMap, ext, configData.props);
				}
				if(!cntrlit && ext==".fview")
				{
					content = fviewHandler.handle(req, res, configData.fviewmap);
				}
				else
				{
					if(res.getContent_str()=="")
						content = getContentStr(req->getUrl(),configData.lprops[req->getDefaultLocale()],ext);
					else
						content = res.getContent_str();
				}
				if(content.length()==0)
				{
					res.setStatusCode("404");
					res.setStatusMsg("Not Found");
					//res.setContent_len(CastUtil::lexical_cast<string>(0));
				}
				else
				{
					res.setStatusCode("200");
					res.setStatusMsg("OK");
					if(res.getContent_type()=="")res.setContent_type(configData.props[ext]);
					res.setContent_str(content);
					//res.setContent_len(CastUtil::lexical_cast<string>(content.length()));
					//sess.setAttribute("CURR",req->getUrl());
				}
			}

			filterHandler.handleOut(req, res, configData.filterMap, dlib, ext);
		}

		alldatlg += "--processed data";
		string h1;
		bool sessionchanged = !req->hasCookie();
		sessionchanged |= req->getSession()->isDirty();
		if(req->getConnection()!="")
			res.setConnection("close");
		createResponse(res,sessionchanged,req->getSession()->getSessionAttributes(),req->getCookieInfoAttribute("FFEADID"), sessionTimeoutVar, configData.sessatserv);
		//Head should behave exactly as Get but there should be no entity body
		if(req->getMethod()=="HEAD")
		{
			h1 = res.generateHeadResponse();
		}
		else if(req->getMethod()=="OPTIONS")
		{
			h1 = res.generateOptionsResponse();
		}
		else if(req->getMethod()=="TRACE")
		{
			h1 = res.generateTraceResponse(req);
		}
		else
		{
			h1 = res.generateResponse();
		}
		//logger << h1 << endl;
		if(isSSLEnabled)
		{
			int r;
			/* Now perform renegotiation if requested */
			if(configData.client_auth==CLIENT_AUTH_REHANDSHAKE){
			  SSL_set_verify(ssl,SSL_VERIFY_PEER |
				SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);

			  /* Stop the client from just resuming the
				 un-authenticated session */
			  SSL_set_session_id_context(ssl,
				(const unsigned char*)&SSLHandler::s_server_auth_session_id_context,
				sizeof(SSLHandler::s_server_auth_session_id_context));

			  if(SSL_renegotiate(ssl)<=0)
			  {
				  sslHandler.error_occurred((char*)"SSL renegotiation error",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			  }
			  if(SSL_do_handshake(ssl)<=0)
			  {
				  sslHandler.error_occurred((char*)"SSL renegotiation error",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			  }
			  ssl->state=SSL_ST_ACCEPT;
			  if(SSL_do_handshake(ssl)<=0)
			  {
				  sslHandler.error_occurred((char*)"SSL renegotiation error",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			  }
			}
			if((r=BIO_puts(io,h1.c_str()))<=0)
			{
				  sslHandler.error_occurred((char*)"send failed",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			}
			if((r=BIO_flush(io))<0)
			{
				  sslHandler.error_occurred((char*)"Error flushing BIO",fd,ssl);
				  if(io!=NULL)BIO_free(io);
				  return;
			}
			sslHandler.closeSSL(fd,ssl,io);
		}
		else
		{
			int size;
			if ((size=send(fd,&h1[0] , h1.length(), 0)) == -1)
				logger << "send failed" << flush;
			else if(size==0)
			{
				close(fd);
				memset(&buf[0], 0, sizeof(buf));
				logger << "socket closed for writing" << flush;
				return;
			}

			if(io!=NULL)BIO_free_all(io);
		}
		close(fd);
		memset(&buf[0], 0, sizeof(buf));
		ss.clear();

		//Logger::info("got new connection to process\n"+req->getFile()+" :: " + res.getStatusCode() + "\n"+req->getCntxt_name() + "\n"+req->getCntxt_root() + "\n"+req->getUrl());
		delete req;
		logger << alldatlg << "--sent data--DONE" << flush;
		//sessionMap[sessId] = sess;
	}
	catch(...)
	{
		logger << "Standard exception: " << endl;
	}
}
Пример #13
0
static LUA_FUNCTION(openssl_bio_new_filter)
{
  /* 0         1        2      3      4    5 */
  static const char* sType[] = {"base64", "buffer", "cipher", "md", "ssl", NULL};
  int type = luaL_checkoption(L, 1, NULL, sType);
  BIO* bio = NULL;
  int ret = 1;
  int closeflag = 0;
  switch (type)
  {
  case 0:
    bio = BIO_new(BIO_f_base64());
    break;
  case 1:
    bio = BIO_new(BIO_f_buffer());
    break;
  case 2:
  {
    const EVP_CIPHER* c = get_cipher(L, 2, NULL);
    size_t kl, il;
    const char* k = luaL_checklstring(L, 3, &kl);
    const char* v = luaL_checklstring(L, 4, &il);
    int encrypt = auxiliar_checkboolean(L, 5);

    bio = BIO_new(BIO_f_cipher());
    BIO_set_cipher(bio, c, (const unsigned char*)k, (const unsigned char*)v, encrypt);
  }
  break;
  case 3:
  {
    const EVP_MD* md = get_digest(L, 2);
    bio = BIO_new(BIO_f_md());
    ret = BIO_set_md(bio, md);
  }
  case 4:
  {
    SSL* ssl = CHECK_OBJECT(2, SSL, "openssl.ssl");
    closeflag = luaL_checkoption(L, 3, "noclose", close_flags);
    bio = BIO_new(BIO_f_ssl());
    ret = BIO_set_ssl(bio, ssl, closeflag);
  }
  break;
  default:
    ret = 0;
  }
  if (ret == 1 && bio)
  {
    PUSH_OBJECT(bio, "openssl.bio");
    if (closeflag)
    {
      openssl_newvalue(L, bio);

      lua_pushboolean(L, 1);
      openssl_setvalue(L, bio, "free_all");
    }
    return 1;
  }
  else
  {
    if (bio)
      BIO_free(bio);
    return openssl_pushresult(L, ret);
  }
  return 0;
}
Пример #14
0
int main(int argc, char *argv[])
{
    const char *hostport = HOSTPORT;
    const char *CAfile = CAFILE;
    char *hostname;
    char *cp;
    BIO *out = NULL;
    char buf[1024 * 10], *p;
    SSL_CTX *ssl_ctx = NULL;
    SSL *ssl;
    BIO *ssl_bio;
    int i, len, off, ret = EXIT_FAILURE;

    if (argc > 1)
        hostport = argv[1];
    if (argc > 2)
        CAfile = argv[2];

    hostname = OPENSSL_strdup(hostport);
    if ((cp = strchr(hostname, ':')) != NULL)
        *cp = 0;

#ifdef WATT32
    dbug_init();
    sock_init();
#endif

    ssl_ctx = SSL_CTX_new(TLS_client_method());

    /* Enable trust chain verification */
    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
    SSL_CTX_load_verify_locations(ssl_ctx, CAfile, NULL);

    /* Lets make a SSL structure */
    ssl = SSL_new(ssl_ctx);
    SSL_set_connect_state(ssl);

    /* Enable peername verification */
    if (SSL_set1_host(ssl, hostname) <= 0)
        goto err;

    /* Use it inside an SSL BIO */
    ssl_bio = BIO_new(BIO_f_ssl());
    BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);

    /* Lets use a connect BIO under the SSL BIO */
    out = BIO_new(BIO_s_connect());
    BIO_set_conn_hostname(out, hostport);
    BIO_set_nbio(out, 1);
    out = BIO_push(ssl_bio, out);

    p = "GET / HTTP/1.0\r\n\r\n";
    len = strlen(p);

    off = 0;
    for (;;) {
        i = BIO_write(out, &(p[off]), len);
        if (i <= 0) {
            if (BIO_should_retry(out)) {
                fprintf(stderr, "write DELAY\n");
                sleep(1);
                continue;
            } else {
                goto err;
            }
        }
        off += i;
        len -= i;
        if (len <= 0)
            break;
    }

    for (;;) {
        i = BIO_read(out, buf, sizeof(buf));
        if (i == 0)
            break;
        if (i < 0) {
            if (BIO_should_retry(out)) {
                fprintf(stderr, "read DELAY\n");
                sleep(1);
                continue;
            }
            goto err;
        }
        fwrite(buf, 1, i, stdout);
    }

    ret = EXIT_SUCCESS;
    goto done;

 err:
    if (ERR_peek_error() == 0) { /* system call error */
        fprintf(stderr, "errno=%d ", errno);
        perror("error");
    } else {
        ERR_print_errors_fp(stderr);
    }
 done:
    BIO_free_all(out);
    SSL_CTX_free(ssl_ctx);
    return ret;
}
Пример #15
0
static int http_serve(SSL *ssl, int s)
{
	char buf[BUFSIZZ];
	int r,len;
	BIO *io,*ssl_bio;

	io=BIO_new(BIO_f_buffer());
	ssl_bio=BIO_new(BIO_f_ssl());
	BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
	BIO_push(io,ssl_bio);

	while(1){
		r=BIO_gets(io,buf,BUFSIZZ-1);

		switch(SSL_get_error(ssl,r)){
		case SSL_ERROR_NONE:
			len=r;
			break;
		case SSL_ERROR_ZERO_RETURN:
			goto shutdown;
			break;
		default:
			berr_exit("SSL read problem");
		}

		/* Look for the blank line that signals
		   the end of the HTTP headers */
		if(!strcmp(buf,"\r\n") ||
			!strcmp(buf,"\n"))
			break;
	}

	/* Now perform renegotiation if requested */
	if(client_auth==CLIENT_AUTH_REHANDSHAKE){
		SSL_set_verify(ssl,SSL_VERIFY_PEER |
			SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);

		/* Stop the client from just resuming the
		   un-authenticated session */
		SSL_set_session_id_context(ssl,
			(void *)&s_server_auth_session_id_context,
			sizeof(s_server_auth_session_id_context));

		if(SSL_renegotiate(ssl)<=0)
			berr_exit("SSL renegotiation error");
		if(SSL_do_handshake(ssl)<=0)
			berr_exit("SSL renegotiation error");
		ssl->state=SSL_ST_ACCEPT;
		if(SSL_do_handshake(ssl)<=0)
			berr_exit("SSL renegotiation error");
	}

	if((r=BIO_puts
			(io,"HTTP/1.0 200 OK\r\n"))<=0)
		err_exit("Write error");
	if((r=BIO_puts
			(io,"Server: EKRServer\r\n\r\n"))<=0)
		err_exit("Write error");
	if((r=BIO_puts
			(io,"Server test page\r\n"))<=0)
		err_exit("Write error");

	if((r=BIO_flush(io))<0)
		err_exit("Error flushing BIO");


shutdown:
	r=SSL_shutdown(ssl);
	if(!r){
		/* If we called SSL_shutdown() first then
		   we always get return value of '0'. In
		   this case, try again, but first send a
		   TCP FIN to trigger the other side's
		   close_notify*/
		shutdown(s,1);
		r=SSL_shutdown(ssl);
	}

	switch(r){  
	case 1:
		break; /* Success */
	case 0:
	case -1:
	default:
		berr_exit("Shutdown failed");
	}

	SSL_free(ssl);
	close(s);

	return(0);
}
Пример #16
0
HybridSslConnection*
hybrid_ssl_connect_with_fd(gint sk,    ssl_callback func, gpointer user_data)
{
    gint                 l;
    SSL                 *ssl;
    BIO                 *sbio;
    BIO                 *buf_io;
    BIO                 *ssl_bio;
    SSL_CTX             *ssl_ctx;
    HybridSslConnection *ssl_conn;

    SSL_load_error_strings();
    SSL_library_init();

    if (!(ssl_ctx = SSL_CTX_new(TLSv1_client_method()))) {

        hybrid_debug_error("ssl", "initialize SSL CTX: %s",
                           ERR_reason_error_string(ERR_get_error()));
        return NULL;
    }

    if (!(ssl = ssl_new_with_certs(ssl_ctx))) {
        return NULL;
    }

    if (!SSL_set_fd(ssl, sk)) {
        hybrid_debug_error("ssl", "add ssl to tcp socket:%s",
                           ERR_reason_error_string(ERR_get_error()));
        return NULL;
    }

    sbio = BIO_new(BIO_s_socket());
    BIO_set_fd(sbio, sk, BIO_NOCLOSE);
    SSL_set_bio(ssl, sbio, sbio);

    SSL_set_connect_state(ssl);

 reconnect:
    l = SSL_connect(ssl);

    switch (SSL_get_error(ssl, l)) {
    case SSL_ERROR_NONE:
        goto ssl_conn_sk_ok;
    case SSL_ERROR_WANT_WRITE:
    case SSL_ERROR_WANT_READ:
        usleep(100);
        goto reconnect;
    case SSL_ERROR_SYSCALL:
    case SSL_ERROR_WANT_X509_LOOKUP:
    case SSL_ERROR_ZERO_RETURN:
    case SSL_ERROR_SSL:
    default:
        hybrid_debug_error("ssl", "ssl hand-shake error:%s",
                           ERR_reason_error_string(ERR_get_error()));
        return NULL;
    }

ssl_conn_sk_ok:

    if (HYBRID_OK != ssl_verify_certs(ssl)) {
        return NULL;
    }

    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    buf_io = BIO_new(BIO_f_buffer());
    ssl_bio = BIO_new(BIO_f_ssl());

    BIO_set_ssl(ssl_bio, ssl, BIO_NOCLOSE);
    BIO_push(buf_io, ssl_bio);

    ssl_conn = g_new0(HybridSslConnection, 1);

    ssl_conn->sk        = sk;
    ssl_conn->ssl       = ssl;
    ssl_conn->ssl_ctx   = ssl_ctx;
    ssl_conn->conn_cb   = func;
    ssl_conn->conn_data = user_data;
    ssl_conn->rbio      = buf_io;
    ssl_conn->wbio      = sbio;

    if (func) {
        func(ssl_conn, user_data);
    }

    return ssl_conn;
}
Пример #17
0
bool SSLClient::connectionUnresolv(const string& host, const int& port)
{
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	memset(s, 0, sizeof(s));
	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	string sport = CastUtil::lexical_cast<string>(port);
	if ((rv = getaddrinfo(host.c_str(), sport.c_str(), &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return false;
	}

	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
				p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}

		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			closesocket(sockfd);
			perror("client: connect");
			connected = false;
			continue;
		} else {
			connected = true;
		}
		break;
	}

	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return false;
	}

	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			s, sizeof s);
	//printf("client: connecting to %s\n", s);

	freeaddrinfo(servinfo); // all done with this structure

	/* Build our SSL context*/
	init();

	/* Connect the SSL socket */
	ssl=SSL_new(ctx);
	sbio=BIO_new_socket(sockfd,BIO_CLOSE);
	SSL_set_bio(ssl,sbio,sbio);
	io=BIO_new(BIO_f_buffer());
	ssl_bio=BIO_new(BIO_f_ssl());
	BIO_set_ssl(ssl_bio,ssl,BIO_NOCLOSE);
	BIO_push(io,ssl_bio);

	if(SSL_connect(ssl)<=0)
	{
		logger << "SSL connect error";
		return false;
	}
	ERR_clear_error();
	return connected;
}
Пример #18
0
static int execute_test_ssl_bio(SSL_BIO_TEST_FIXTURE fix)
{
    BIO *sslbio = NULL, *membio1 = NULL, *membio2 = NULL;
    SSL_CTX *ctx = SSL_CTX_new(TLS_method());
    SSL *ssl = NULL;
    int testresult = 0;

    if (ctx == NULL) {
        printf("Failed to allocate SSL_CTX\n");
        return 0;
    }

    ssl = SSL_new(ctx);
    if (ssl == NULL) {
        printf("Failed to allocate SSL object\n");
        goto end;
    }

    sslbio = BIO_new(BIO_f_ssl());
    membio1 = BIO_new(BIO_s_mem());

    if (sslbio == NULL || membio1 == NULL) {
        printf("Malloc failure creating BIOs\n");
        goto end;
    }

    BIO_set_ssl(sslbio, ssl, BIO_CLOSE);

    /*
     * If anything goes wrong here then we could leak memory, so this will
     * be caught in a crypto-mdebug build
     */
    BIO_push(sslbio, membio1);

    /* Verify changing the rbio/wbio directly does not cause leaks */
    if (fix.change_bio != NO_BIO_CHANGE) {
        membio2 = BIO_new(BIO_s_mem());
        if (membio2 == NULL) {
            printf("Malloc failure creating membio2\n");
            goto end;
        }
        if (fix.change_bio == CHANGE_RBIO)
            SSL_set0_rbio(ssl, membio2);
        else
            SSL_set0_wbio(ssl, membio2);
    }
    ssl = NULL;

    if (fix.pop_ssl)
        BIO_pop(sslbio);
    else
        BIO_pop(membio1);

    testresult = 1;
 end:
    BIO_free(membio1);
    BIO_free(sslbio);
    SSL_free(ssl);
    SSL_CTX_free(ctx);

    return testresult;
}
Пример #19
0
void* sqlhandler(void *arg) {
        char sql[MAX_MSG];
        int ret, err;
        SSL *ssl;
        sqlite4_stmt *pStmt;

        struct conn_ctx *conn = (struct conn_ctx *)arg;
        struct freeq_ctx *freeqctx = conn->srvctx->freeqctx;
        BIO *client = conn->client;

        if (!(ssl = freeq_ssl_new(freeqctx)))
        {
                err(freeqctx, "couldn't allocate new ssl instance");
                BIO_free_all(client);
                free(conn);
                pthread_exit(NULL);
        }

        SSL_set_bio(ssl, client, client);
        if (SSL_accept(ssl) <= 0)
        {
                int_error("Error accepting SSL connection");
                BIO_free_all(client);
                free(conn);
                pthread_exit(NULL);
        }

        if ((err = post_connection_check(freeqctx, ssl, "localhost")) != X509_V_OK)
        {
                err(freeqctx, "error: peer certificate: %s\n", X509_verify_cert_error_string(err));
                BIO_free_all(client);
                free(conn);
                pthread_exit(NULL);
        }

        BIO *b, *ssl_bio;
        b = BIO_new(BIO_f_buffer());
        ssl_bio = BIO_new(BIO_f_ssl());
        BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
        BIO_push(b, ssl_bio);

        memset(sql, 0, MAX_MSG);
        ret = BIO_gets(b, sql, MAX_MSG);

        ret = sqlite4_prepare(pDb, sql, strlen(sql), &pStmt, 0);
        if (ret != SQLITE4_OK)
        {
                dbg(freeqctx, "prepare failed for %s sending error, ret was %d\n", sql, ret);
                //freeq_error_write_sock(freeqctx, sqlite4_errmsg(pDb), b);
                dbg(freeqctx, sqlite4_errmsg(pDb));
                //BIO_printf(b, "error: %s\n", sqlite4_errmsg(pDb));
                sqlite4_finalize(pStmt);
                //pthread_exit(FREEQ_ERR);
        }

        freeq_sqlite_to_bio(freeqctx, b, pStmt);

        SSL_shutdown(ssl);
        SSL_free(ssl);

        BIO_free_all(client);
        free(conn);
        pthread_exit(FREEQ_OK);

}
Пример #20
0
int doit(char *ctx[4])
{
    SSL_CTX *s_ctx, *c_ctx;
    static char cbuf[200], sbuf[200];
    SSL *c_ssl = NULL;
    SSL *s_ssl = NULL;
    BIO *c_to_s = NULL;
    BIO *s_to_c = NULL;
    BIO *c_bio = NULL;
    BIO *s_bio = NULL;
    int c_r, c_w, s_r, s_w;
    int c_want, s_want;
    int i;
    int done = 0;
    int c_write, s_write;
    int do_server = 0, do_client = 0;

    s_ctx = (SSL_CTX *)ctx[0];
    c_ctx = (SSL_CTX *)ctx[1];

    if (ctx[2] != NULL)
        s_ssl = (SSL *)ctx[2];
    else
        s_ssl = SSL_new(s_ctx);

    if (ctx[3] != NULL)
        c_ssl = (SSL *)ctx[3];
    else
        c_ssl = SSL_new(c_ctx);

    if ((s_ssl == NULL) || (c_ssl == NULL))
        goto err;

    c_to_s = BIO_new(BIO_s_mem());
    s_to_c = BIO_new(BIO_s_mem());
    if ((s_to_c == NULL) || (c_to_s == NULL))
        goto err;

    c_bio = BIO_new(BIO_f_ssl());
    s_bio = BIO_new(BIO_f_ssl());
    if ((c_bio == NULL) || (s_bio == NULL))
        goto err;

    SSL_set_connect_state(c_ssl);
    SSL_set_bio(c_ssl, s_to_c, c_to_s);
    BIO_set_ssl(c_bio, c_ssl, (ctx[2] == NULL) ? BIO_CLOSE : BIO_NOCLOSE);

    SSL_set_accept_state(s_ssl);
    SSL_set_bio(s_ssl, c_to_s, s_to_c);
    BIO_set_ssl(s_bio, s_ssl, (ctx[3] == NULL) ? BIO_CLOSE : BIO_NOCLOSE);

    c_r = 0;
    s_r = 1;
    c_w = 1;
    s_w = 0;
    c_want = W_WRITE;
    s_want = 0;
    c_write = 1, s_write = 0;

    /* We can always do writes */
    for (;;) {
        do_server = 0;
        do_client = 0;

        i = (int)BIO_pending(s_bio);
        if ((i && s_r) || s_w)
            do_server = 1;

        i = (int)BIO_pending(c_bio);
        if ((i && c_r) || c_w)
            do_client = 1;

        if (do_server && verbose) {
            if (SSL_in_init(s_ssl))
                printf("server waiting in SSL_accept - %s\n",
                       SSL_state_string_long(s_ssl));
            else if (s_write)
                printf("server:SSL_write()\n");
            else
                printf("server:SSL_read()\n");
        }

        if (do_client && verbose) {
            if (SSL_in_init(c_ssl))
                printf("client waiting in SSL_connect - %s\n",
                       SSL_state_string_long(c_ssl));
            else if (c_write)
                printf("client:SSL_write()\n");
            else
                printf("client:SSL_read()\n");
        }

        if (!do_client && !do_server) {
            fprintf(stdout, "ERROR IN STARTUP\n");
            break;
        }
        if (do_client && !(done & C_DONE)) {
            if (c_write) {
                i = BIO_write(c_bio, "hello from client\n", 18);
                if (i < 0) {
                    c_r = 0;
                    c_w = 0;
                    if (BIO_should_retry(c_bio)) {
                        if (BIO_should_read(c_bio))
                            c_r = 1;
                        if (BIO_should_write(c_bio))
                            c_w = 1;
                    } else {
                        fprintf(stderr, "ERROR in CLIENT\n");
                        ERR_print_errors_fp(stderr);
                        return (1);
                    }
                } else if (i == 0) {
                    fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
                    return (1);
                } else {
                    /* ok */
                    c_write = 0;
                }
            } else {
                i = BIO_read(c_bio, cbuf, 100);
                if (i < 0) {
                    c_r = 0;
                    c_w = 0;
                    if (BIO_should_retry(c_bio)) {
                        if (BIO_should_read(c_bio))
                            c_r = 1;
                        if (BIO_should_write(c_bio))
                            c_w = 1;
                    } else {
                        fprintf(stderr, "ERROR in CLIENT\n");
                        ERR_print_errors_fp(stderr);
                        return (1);
                    }
                } else if (i == 0) {
                    fprintf(stderr, "SSL CLIENT STARTUP FAILED\n");
                    return (1);
                } else {
                    done |= C_DONE;
#ifdef undef
                    fprintf(stdout, "CLIENT:from server:");
                    fwrite(cbuf, 1, i, stdout);
                    fflush(stdout);
#endif
                }
            }
        }

        if (do_server && !(done & S_DONE)) {
            if (!s_write) {
                i = BIO_read(s_bio, sbuf, 100);
                if (i < 0) {
                    s_r = 0;
                    s_w = 0;
                    if (BIO_should_retry(s_bio)) {
                        if (BIO_should_read(s_bio))
                            s_r = 1;
                        if (BIO_should_write(s_bio))
                            s_w = 1;
                    } else {
                        fprintf(stderr, "ERROR in SERVER\n");
                        ERR_print_errors_fp(stderr);
                        return (1);
                    }
                } else if (i == 0) {
                    fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
                    return (1);
                } else {
                    s_write = 1;
                    s_w = 1;
#ifdef undef
                    fprintf(stdout, "SERVER:from client:");
                    fwrite(sbuf, 1, i, stdout);
                    fflush(stdout);
#endif
                }
            } else {
                i = BIO_write(s_bio, "hello from server\n", 18);
                if (i < 0) {
                    s_r = 0;
                    s_w = 0;
                    if (BIO_should_retry(s_bio)) {
                        if (BIO_should_read(s_bio))
                            s_r = 1;
                        if (BIO_should_write(s_bio))
                            s_w = 1;
                    } else {
                        fprintf(stderr, "ERROR in SERVER\n");
                        ERR_print_errors_fp(stderr);
                        return (1);
                    }
                } else if (i == 0) {
                    fprintf(stderr, "SSL SERVER STARTUP FAILED\n");
                    return (1);
                } else {
                    s_write = 0;
                    s_r = 1;
                    done |= S_DONE;
                }
            }
        }

        if ((done & S_DONE) && (done & C_DONE))
            break;
#if defined(OPENSSL_SYS_NETWARE)
        ThreadSwitchWithDelay();
#endif
    }

    SSL_set_shutdown(c_ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
    SSL_set_shutdown(s_ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);

#ifdef undef
    fprintf(stdout, "DONE\n");
#endif
 err:
    /*
     * We have to set the BIO's to NULL otherwise they will be free()ed
     * twice.  Once when th s_ssl is SSL_free()ed and again when c_ssl is
     * SSL_free()ed. This is a hack required because s_ssl and c_ssl are
     * sharing the same BIO structure and SSL_set_bio() and SSL_free()
     * automatically BIO_free non NULL entries. You should not normally do
     * this or be required to do this
     */

    if (s_ssl != NULL) {
        s_ssl->rbio = NULL;
        s_ssl->wbio = NULL;
    }
    if (c_ssl != NULL) {
        c_ssl->rbio = NULL;
        c_ssl->wbio = NULL;
    }

    /* The SSL's are optionally freed in the following calls */
    if (c_to_s != NULL)
        BIO_free(c_to_s);
    if (s_to_c != NULL)
        BIO_free(s_to_c);

    if (c_bio != NULL)
        BIO_free(c_bio);
    if (s_bio != NULL)
        BIO_free(s_bio);
    return (0);
}
Пример #21
0
int doit(io_channel chan, SSL_CTX *s_ctx )
{
    int status, length, link_state;
     struct rpc_msg msg;
	static char cbuf[200],sbuf[200];
	SSL *s_ssl=NULL;
	BIO *c_to_s=NULL;
	BIO *s_to_c=NULL;
	BIO *c_bio=NULL;
	BIO *s_bio=NULL;
	int i;
	int done=0;

	s_ssl=SSL_new(s_ctx);
	if (s_ssl == NULL) goto err;

	c_to_s=BIO_new(BIO_s_rtcp());
	s_to_c=BIO_new(BIO_s_rtcp());
	if ((s_to_c == NULL) || (c_to_s == NULL)) goto err;
/* original, DRM 24-SEP-1997
	BIO_set_fd ( c_to_s, "", chan );
	BIO_set_fd ( s_to_c, "", chan );
*/
	BIO_set_fd ( c_to_s, 0, chan );
	BIO_set_fd ( s_to_c, 0, chan );

	c_bio=BIO_new(BIO_f_ssl());
	s_bio=BIO_new(BIO_f_ssl());
	if ((c_bio == NULL) || (s_bio == NULL)) goto err;

	SSL_set_accept_state(s_ssl);
	SSL_set_bio(s_ssl,c_to_s,s_to_c);
	BIO_set_ssl(s_bio,s_ssl,BIO_CLOSE);

	/* We can always do writes */
	printf("Begin doit main loop\n");
	/*
	 * Link states: 0-idle, 1-read pending, 2-write pending, 3-closed.
	 */
	for (link_state = 0; link_state < 3; ) {
	    /*
	     * Wait for remote end to request data action on A channel.
	     */
	    while ( link_state == 0 ) {
		status = get ( chan, (char *) &msg, sizeof(msg), &length );
		if ( (status&1) == 0 ) {
		    printf("Error in main loop get: %d\n", status );
		    link_state = 3;
		    break;
		}
	   	if ( length < RPC_HDR_SIZE ) {
		    printf("Error in main loop get size: %d\n", length );
		    break;
		    link_state = 3;
		}
	   	if ( msg.channel != 'A' ) {
		    printf("Error in main loop, unexpected channel: %c\n", 
			msg.channel );
		    break;
		    link_state = 3;
		}
		if ( msg.function == 'G' ) {
		    link_state = 1;
		} else if ( msg.function == 'P' ) {
		    link_state = 2;	/* write pending */
		} else if ( msg.function == 'X' ) {
		    link_state = 3;
		} else {
		    link_state = 3;
		}
	    }
	    if ( link_state == 1 ) {
		i = BIO_read ( s_bio, msg.data, msg.length );
		if ( i < 0 ) link_state = 3;
		else {
		    msg.channel = 'A';
		    msg.function = 'C';		/* confirm */
		    msg.length = i;
		    status = put ( chan, (char *) &msg, i+RPC_HDR_SIZE );
		    if ( (status&1) == 0 ) break;
		    link_state = 0;
		}
	    } else if ( link_state == 2 ) {
		i = BIO_write ( s_bio, msg.data, msg.length );
		if ( i < 0 ) link_state = 3;
		else {
		    msg.channel = 'A';
		    msg.function = 'C';		/* confirm */
		    msg.length = 0;
		    status = put ( chan, (char *) &msg, RPC_HDR_SIZE );
		    if ( (status&1) == 0 ) break;
		    link_state = 0;
		}
	    }
	}
	fprintf(stdout,"DONE\n");
err:
	/* We have to set the BIO's to NULL otherwise they will be
	 * free()ed twice.  Once when th s_ssl is SSL_free()ed and
	 * again when c_ssl is SSL_free()ed.
	 * This is a hack required because s_ssl and c_ssl are sharing the same
	 * BIO structure and SSL_set_bio() and SSL_free() automatically
	 * BIO_free non NULL entries.
	 * You should not normally do this or be required to do this */
	s_ssl->rbio=NULL;
	s_ssl->wbio=NULL;

	if (c_to_s != NULL) BIO_free(c_to_s);
	if (s_to_c != NULL) BIO_free(s_to_c);
	if (c_bio != NULL) BIO_free(c_bio);
	if (s_bio != NULL) BIO_free(s_bio);
	return(0);
}
Пример #22
0
int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
	clock_t *s_time, clock_t *c_time)
	{
	long cw_num = count, cr_num = count, sw_num = count, sr_num = count;
	BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL;
	BIO *server = NULL, *server_io = NULL, *client = NULL, *client_io = NULL;
	int ret = 1;
	
	size_t bufsiz = 256; /* small buffer for testing */

	if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz))
		goto err;
	if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz))
		goto err;
	
	s_ssl_bio = BIO_new(BIO_f_ssl());
	if (!s_ssl_bio)
		goto err;

	c_ssl_bio = BIO_new(BIO_f_ssl());
	if (!c_ssl_bio)
		goto err;

	SSL_set_connect_state(c_ssl);
	SSL_set_bio(c_ssl, client, client);
	(void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE);

	SSL_set_accept_state(s_ssl);
	SSL_set_bio(s_ssl, server, server);
	(void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE);

	do
		{
		/* c_ssl_bio:          SSL filter BIO
		 *
		 * client:             pseudo-I/O for SSL library
		 *
		 * client_io:          client's SSL communication; usually to be
		 *                     relayed over some I/O facility, but in this
		 *                     test program, we're the server, too:
		 *
		 * server_io:          server's SSL communication
		 *
		 * server:             pseudo-I/O for SSL library
		 *
		 * s_ssl_bio:          SSL filter BIO
		 *
		 * The client and the server each employ a "BIO pair":
		 * client + client_io, server + server_io.
		 * BIO pairs are symmetric.  A BIO pair behaves similar
		 * to a non-blocking socketpair (but both endpoints must
		 * be handled by the same thread).
		 * [Here we could connect client and server to the ends
		 * of a single BIO pair, but then this code would be less
		 * suitable as an example for BIO pairs in general.]
		 *
		 * Useful functions for querying the state of BIO pair endpoints:
		 *
		 * BIO_ctrl_pending(bio)              number of bytes we can read now
		 * BIO_ctrl_get_read_request(bio)     number of bytes needed to fulfil
		 *                                      other side's read attempt
		 * BIO_ctrl_get_write_guarantee(bio)   number of bytes we can write now
		 *
		 * ..._read_request is never more than ..._write_guarantee;
		 * it depends on the application which one you should use.
		 */

		/* We have non-blocking behaviour throughout this test program, but
		 * can be sure that there is *some* progress in each iteration; so
		 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE
		 * -- we just try everything in each iteration
		 */

			{
			/* CLIENT */
		
			MS_STATIC char cbuf[1024*8];
			int i, r;
			clock_t c_clock = clock();

			memset(cbuf, 0, sizeof(cbuf));

			if (debug)
				if (SSL_in_init(c_ssl))
					printf("client waiting in SSL_connect - %s\n",
						SSL_state_string_long(c_ssl));

			if (cw_num > 0)
				{
				/* Write to server. */
				
				if (cw_num > (long)sizeof cbuf)
					i = sizeof cbuf;
				else
					i = (int)cw_num;
				r = BIO_write(c_ssl_bio, cbuf, i);
				if (r < 0)
					{
					if (!BIO_should_retry(c_ssl_bio))
						{
						fprintf(stderr,"ERROR in CLIENT\n");
						goto err;
						}
					/* BIO_should_retry(...) can just be ignored here.
					 * The library expects us to call BIO_write with
					 * the same arguments again, and that's what we will
					 * do in the next iteration. */
					}
				else if (r == 0)
					{
					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("client wrote %d\n", r);
					cw_num -= r;				
					}
				}

			if (cr_num > 0)
				{
				/* Read from server. */

				r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf));
				if (r < 0)
					{
					if (!BIO_should_retry(c_ssl_bio))
						{
						fprintf(stderr,"ERROR in CLIENT\n");
						goto err;
						}
					/* Again, "BIO_should_retry" can be ignored. */
					}
				else if (r == 0)
					{
					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("client read %d\n", r);
					cr_num -= r;
					}
				}

			/* c_time and s_time increments will typically be very small
			 * (depending on machine speed and clock tick intervals),
			 * but sampling over a large number of connections should
			 * result in fairly accurate figures.  We cannot guarantee
			 * a lot, however -- if each connection lasts for exactly
			 * one clock tick, it will be counted only for the client
			 * or only for the server or even not at all.
			 */
			*c_time += (clock() - c_clock);
			}

			{
			/* SERVER */
		
			MS_STATIC char sbuf[1024*8];
			int i, r;
			clock_t s_clock = clock();

			memset(sbuf, 0, sizeof(sbuf));

			if (debug)
				if (SSL_in_init(s_ssl))
					printf("server waiting in SSL_accept - %s\n",
						SSL_state_string_long(s_ssl));

			if (sw_num > 0)
				{
				/* Write to client. */
				
				if (sw_num > (long)sizeof sbuf)
					i = sizeof sbuf;
				else
					i = (int)sw_num;
				r = BIO_write(s_ssl_bio, sbuf, i);
				if (r < 0)
					{
					if (!BIO_should_retry(s_ssl_bio))
						{
						fprintf(stderr,"ERROR in SERVER\n");
						goto err;
						}
					/* Ignore "BIO_should_retry". */
					}
				else if (r == 0)
					{
					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("server wrote %d\n", r);
					sw_num -= r;				
					}
				}

			if (sr_num > 0)
				{
				/* Read from client. */

				r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf));
				if (r < 0)
					{
					if (!BIO_should_retry(s_ssl_bio))
						{
						fprintf(stderr,"ERROR in SERVER\n");
						goto err;
						}
					/* blah, blah */
					}
				else if (r == 0)
					{
					fprintf(stderr,"SSL SERVER STARTUP FAILED\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("server read %d\n", r);
					sr_num -= r;
					}
				}

			*s_time += (clock() - s_clock);
			}
			
			{
			/* "I/O" BETWEEN CLIENT AND SERVER. */

			size_t r1, r2;
			BIO *io1 = server_io, *io2 = client_io;
			/* we use the non-copying interface for io1
			 * and the standard BIO_write/BIO_read interface for io2
			 */
			
			static int prev_progress = 1;
			int progress = 0;
			
			/* io1 to io2 */
			do
				{
				size_t num;
				int r;

				r1 = BIO_ctrl_pending(io1);
				r2 = BIO_ctrl_get_write_guarantee(io2);

				num = r1;
				if (r2 < num)
					num = r2;
				if (num)
					{
					char *dataptr;

					if (INT_MAX < num) /* yeah, right */
						num = INT_MAX;
					
					r = BIO_nread(io1, &dataptr, (int)num);
					assert(r > 0);
					assert(r <= (int)num);
					/* possibly r < num (non-contiguous data) */
					num = r;
					r = BIO_write(io2, dataptr, (int)num);
					if (r != (int)num) /* can't happen */
						{
						fprintf(stderr, "ERROR: BIO_write could not write "
							"BIO_ctrl_get_write_guarantee() bytes");
						goto err;
						}
					progress = 1;

					if (debug)
						printf((io1 == client_io) ?
							"C->S relaying: %d bytes\n" :
							"S->C relaying: %d bytes\n",
							(int)num);
					}
				}
			while (r1 && r2);

			/* io2 to io1 */
			{
				size_t num;
				int r;

				r1 = BIO_ctrl_pending(io2);
				r2 = BIO_ctrl_get_read_request(io1);
				/* here we could use ..._get_write_guarantee instead of
				 * ..._get_read_request, but by using the latter
				 * we test restartability of the SSL implementation
				 * more thoroughly */
				num = r1;
				if (r2 < num)
					num = r2;
				if (num)
					{
					char *dataptr;
					
					if (INT_MAX < num)
						num = INT_MAX;

					if (num > 1)
						--num; /* test restartability even more thoroughly */
					
					r = BIO_nwrite0(io1, &dataptr);
					assert(r > 0);
					if (r < (int)num)
						num = r;
					r = BIO_read(io2, dataptr, (int)num);
					if (r != (int)num) /* can't happen */
						{
						fprintf(stderr, "ERROR: BIO_read could not read "
							"BIO_ctrl_pending() bytes");
						goto err;
						}
					progress = 1;
					r = BIO_nwrite(io1, &dataptr, (int)num);
					if (r != (int)num) /* can't happen */
						{
						fprintf(stderr, "ERROR: BIO_nwrite() did not accept "
							"BIO_nwrite0() bytes");
						goto err;
						}
					
					if (debug)
						printf((io2 == client_io) ?
							"C->S relaying: %d bytes\n" :
							"S->C relaying: %d bytes\n",
							(int)num);
					}
			} /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */

			if (!progress && !prev_progress)
				if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0)
					{
					fprintf(stderr, "ERROR: got stuck\n");
					if (strcmp("SSLv2", SSL_get_version(c_ssl)) == 0)
						{
						fprintf(stderr, "This can happen for SSL2 because "
							"CLIENT-FINISHED and SERVER-VERIFY are written \n"
							"concurrently ...");
						if (strncmp("2SCF", SSL_state_string(c_ssl), 4) == 0
							&& strncmp("2SSV", SSL_state_string(s_ssl), 4) == 0)
							{
							fprintf(stderr, " ok.\n");
							goto end;
							}
						}
					fprintf(stderr, " ERROR.\n");
					goto err;
					}
			prev_progress = progress;
			}
		}
	while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0);

	if (verbose)
		print_details(c_ssl, "DONE via BIO pair: ");
end:
	ret = 0;

 err:
	ERR_print_errors(bio_err);
	
	if (server)
		BIO_free(server);
	if (server_io)
		BIO_free(server_io);
	if (client)
		BIO_free(client);
	if (client_io)
		BIO_free(client_io);
	if (s_ssl_bio)
		BIO_free(s_ssl_bio);
	if (c_ssl_bio)
		BIO_free(c_ssl_bio);

	return ret;
	}
Пример #23
0
/**
 * oh_ssl_connect
 * @hostname:   Name of target host.  Format:
 *                  "hostname:port" or "IPaddress:port"
 * @ctx:        pointer to SSL_CTX as returned by oh_ssl_ctx_init()
 * @timeout:    maximum number of seconds to wait for a connection to
 *              hostname, or zero to wait forever
 *
 * Create and open a new ssl conection to the specified host.
 *
 * Return value: pointer to BIO, or NULL for failure
 **/
BIO             *oh_ssl_connect(char *hostname, SSL_CTX *ctx, long timeout)
{
        BIO             *bio;
        SSL             *ssl;
        int             err;
        int len, retval = 0;
        int RetVal, socket_desc = 0;
        char *Server = NULL;
        char *Port = NULL;
        struct addrinfo Hints, *AddrInfo = NULL, *ai = NULL;

        memset(&Hints, 0, sizeof(Hints));
        Hints.ai_family = AF_UNSPEC;
        Hints.ai_socktype = SOCK_STREAM;
        len = strlen(hostname);

        if (hostname == NULL) {
                CRIT("NULL hostname in oh_ssl_connect()");
                return(NULL);
        }
        if (ctx == NULL) {
                CRIT("NULL ctx in oh_ssl_connect()");
                return(NULL);
        }
        if (timeout < 0) {
                CRIT("inappropriate timeout in oh_ssl_connect()");
                return(NULL);
        }

        /* Allocate memory to a char pointer "Server" */
        Server = (char *) g_malloc0(sizeof(char) * len);
        if (Server == NULL){
                CRIT("out of memory");
                return NULL;
        }
        memset(Server, 0, len);
        /* hostname contains "Port" along with "IP Address". As, only
         * "IP Address" is needed for some of the below operations, so copy
         * "IP Address" from hostname to "Server".
         */
        strncpy(Server, hostname, (len - 4));

        /* Allocate memory to a char pointer "Port" */
        Port = (char *) g_malloc0(sizeof(char) * 4);
        if (Port == NULL){
                CRIT("out of memory");
                g_free(Server);
                return NULL;
        }
        /* As Port number is needed separately for some of the below
         * operations, so copy port number from hostname to "Port".
         */
        strncpy(Port, hostname + (len - 3), 3);
        
        /* Create socket address structure to prepare client socket */
        RetVal = getaddrinfo(Server, Port, &Hints, &AddrInfo);
        if (RetVal != 0) {
                CRIT("Cannot resolve address [%s] and port [%s],"
                     " error %d: %s",
                       Server, Port, RetVal, gai_strerror(RetVal));
                g_free(Server);
                g_free(Port);
                return NULL;
        }
        
        ai = AddrInfo;
        /* Create a socket point */
        socket_desc = socket(ai->ai_family, ai->ai_socktype,
                                            ai->ai_protocol);
        if (socket_desc == -1) {
                CRIT("Socket failed with error: %s", 
                      strerror(errno));
                g_free(Server);
                g_free(Port);
                freeaddrinfo(AddrInfo);	
                return NULL;
        }

        /* Now connect to target IP Address */
        retval = connect(socket_desc, ai->ai_addr, ai->ai_addrlen);
        if (retval != 0) {
                CRIT("Socket connect failed with error: %s",
                      strerror(errno));
                g_free(Server);
                g_free(Port);
                freeaddrinfo(AddrInfo);	
                close(socket_desc);
                return NULL;
        }

        /* Create new SSL structure for connection */
        ssl = SSL_new(ctx);

        /* Connect ssl object with a socket descriptor */
        SSL_set_fd(ssl, socket_desc);

        /* Initiate SSL connection */
        err = SSL_connect(ssl);
        if (err != 1) {
                CRIT("SSL connection failed");
                g_free(Server);
                g_free(Port);
                freeaddrinfo(AddrInfo);	
                close(socket_desc);
                return (NULL);
        }

        bio = BIO_new(BIO_f_ssl());             /* create an ssl BIO */
        BIO_set_ssl(bio, ssl, BIO_CLOSE);       /* assign the ssl BIO to SSL */

        /* TODO: Do I need to set the client or server mode here?  I don't
         * think so.
         */

        g_free(Server);
        g_free(Port);
        freeaddrinfo(AddrInfo);	
        return(bio);
}
Пример #24
0
static int http_serve(SSL *ssl, int s)
{
	char buf[BUFSIZZ];
	int r,len;
	BIO *io,*ssl_bio;

	io=BIO_new(BIO_f_buffer());
	ssl_bio=BIO_new(BIO_f_ssl());
	BIO_set_ssl(ssl_bio,ssl,BIO_CLOSE);
	BIO_push(io,ssl_bio);

	r=BIO_gets(io,buf,BUFSIZZ-1);

	switch(SSL_get_error(ssl,r)){
	case SSL_ERROR_NONE:
		len=r;
		break;
	default:
		berr_exit("SSL read problem");
	}

	char *saveptr;
	char resource[512] = {'\0'};
	char *token = strtok_r(buf, " ", &saveptr);
	if (token && strcasecmp(token, "GET") == 0)
	{
		token = strtok_r(NULL, " ", &saveptr);
		if (token)
		{
			strncpy(resource, token, sizeof(resource));
		}
	}

	if (resource[0])
	{
		while(1){
			r=BIO_gets(io,buf,BUFSIZZ-1);

			switch(SSL_get_error(ssl,r)){
			case SSL_ERROR_NONE:
				len=r;
				break;
			default:
				berr_exit("SSL read problem");
			}

			/* Look for the blank line that signals
			   the end of the HTTP headers */
			if(!strcmp(buf,"\r\n") || !strcmp(buf,"\n"))
				break;
		}
	}

	if (strcasecmp(resource, "/ciphersuites.txt") == 0)
	{
		http_serve_headers(io, 200, "OK", "text/plain");
		print_ciphersuite_data(io, ssl, 0);
	}
	else if (strcasecmp(resource, "/ciphersuites.js") == 0)
	{
		long protocol = SSL_version(ssl);
		http_serve_headers(io, 200, "OK", "text/javascript");
		if(BIO_printf(io, "$(function() {\n  insert_text('%s', '", get_protocol_name(protocol)) <= 0)
			err_exit("Write error");
		print_ciphersuite_data(io, ssl, 1);
		if(BIO_printf(io, "');\n});") <= 0)
			err_exit("Write error");
	}
	else
	{
		http_serve_headers(io, 404, "Not Found", "text/plain");
		if(BIO_puts(io, "Not found.") <= 0)
			err_exit("Write error");
	}

	if((r=BIO_flush(io))<0)
		err_exit("Error flushing BIO");

	r=SSL_shutdown(ssl);
	if(!r){
		/* If we called SSL_shutdown() first then
		   we always get return value of '0'. In
		   this case, try again, but first send a
		   TCP FIN to trigger the other side's
		   close_notify*/
		shutdown(s,1);
		r=SSL_shutdown(ssl);
	}

	switch(r){  
	case 1:
		break; /* Success */
	case 0:
	case -1:
	default:
		berr_exit("Shutdown failed");
	}

	SSL_free(ssl);
	close(s);

	return(0);
}
Пример #25
0
int doit(SSL *s_ssl, SSL *c_ssl, long count)
	{
	MS_STATIC char cbuf[1024*8],sbuf[1024*8];
	long cw_num=count,cr_num=count;
	long sw_num=count,sr_num=count;
	int ret=1;
	BIO *c_to_s=NULL;
	BIO *s_to_c=NULL;
	BIO *c_bio=NULL;
	BIO *s_bio=NULL;
	int c_r,c_w,s_r,s_w;
	int c_want,s_want;
	int i,j;
	int done=0;
	int c_write,s_write;
	int do_server=0,do_client=0;

	memset(cbuf,0,sizeof(cbuf));
	memset(sbuf,0,sizeof(sbuf));

	c_to_s=BIO_new(BIO_s_mem());
	s_to_c=BIO_new(BIO_s_mem());
	if ((s_to_c == NULL) || (c_to_s == NULL))
		{
		ERR_print_errors(bio_err);
		goto err;
		}

	c_bio=BIO_new(BIO_f_ssl());
	s_bio=BIO_new(BIO_f_ssl());
	if ((c_bio == NULL) || (s_bio == NULL))
		{
		ERR_print_errors(bio_err);
		goto err;
		}

	SSL_set_connect_state(c_ssl);
	SSL_set_bio(c_ssl,s_to_c,c_to_s);
	BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE);

	SSL_set_accept_state(s_ssl);
	SSL_set_bio(s_ssl,c_to_s,s_to_c);
	BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE);

	c_r=0; s_r=1;
	c_w=1; s_w=0;
	c_want=W_WRITE;
	s_want=0;
	c_write=1,s_write=0;

	/* We can always do writes */
	for (;;)
		{
		do_server=0;
		do_client=0;

		i=(int)BIO_pending(s_bio);
		if ((i && s_r) || s_w) do_server=1;

		i=(int)BIO_pending(c_bio);
		if ((i && c_r) || c_w) do_client=1;

		if (do_server && debug)
			{
			if (SSL_in_init(s_ssl))
				printf("server waiting in SSL_accept - %s\n",
					SSL_state_string_long(s_ssl));
/*			else if (s_write)
				printf("server:SSL_write()\n");
			else
				printf("server:SSL_read()\n"); */
			}

		if (do_client && debug)
			{
			if (SSL_in_init(c_ssl))
				printf("client waiting in SSL_connect - %s\n",
					SSL_state_string_long(c_ssl));
/*			else if (c_write)
				printf("client:SSL_write()\n");
			else
				printf("client:SSL_read()\n"); */
			}

		if (!do_client && !do_server)
			{
			fprintf(stdout,"ERROR IN STARTUP\n");
			ERR_print_errors(bio_err);
			break;
			}
		if (do_client && !(done & C_DONE))
			{
			if (c_write)
				{
				j=(cw_num > (long)sizeof(cbuf))
					?sizeof(cbuf):(int)cw_num;
				i=BIO_write(c_bio,cbuf,j);
				if (i < 0)
					{
					c_r=0;
					c_w=0;
					if (BIO_should_retry(c_bio))
						{
						if (BIO_should_read(c_bio))
							c_r=1;
						if (BIO_should_write(c_bio))
							c_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in CLIENT\n");
						ERR_print_errors(bio_err);
						goto err;
						}
					}
				else if (i == 0)
					{
					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("client wrote %d\n",i);
					/* ok */
					s_r=1;
					c_write=0;
					cw_num-=i;
					}
				}
			else
				{
				i=BIO_read(c_bio,cbuf,sizeof(cbuf));
				if (i < 0)
					{
					c_r=0;
					c_w=0;
					if (BIO_should_retry(c_bio))
						{
						if (BIO_should_read(c_bio))
							c_r=1;
						if (BIO_should_write(c_bio))
							c_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in CLIENT\n");
						ERR_print_errors(bio_err);
						goto err;
						}
					}
				else if (i == 0)
					{
					fprintf(stderr,"SSL CLIENT STARTUP FAILED\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("client read %d\n",i);
					cr_num-=i;
					if (sw_num > 0)
						{
						s_write=1;
						s_w=1;
						}
					if (cr_num <= 0)
						{
						s_write=1;
						s_w=1;
						done=S_DONE|C_DONE;
						}
					}
				}
			}

		if (do_server && !(done & S_DONE))
			{
			if (!s_write)
				{
				i=BIO_read(s_bio,sbuf,sizeof(cbuf));
				if (i < 0)
					{
					s_r=0;
					s_w=0;
					if (BIO_should_retry(s_bio))
						{
						if (BIO_should_read(s_bio))
							s_r=1;
						if (BIO_should_write(s_bio))
							s_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in SERVER\n");
						ERR_print_errors(bio_err);
						goto err;
						}
					}
				else if (i == 0)
					{
					ERR_print_errors(bio_err);
					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_read\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("server read %d\n",i);
					sr_num-=i;
					if (cw_num > 0)
						{
						c_write=1;
						c_w=1;
						}
					if (sr_num <= 0)
						{
						s_write=1;
						s_w=1;
						c_write=0;
						}
					}
				}
			else
				{
				j=(sw_num > (long)sizeof(sbuf))?
					sizeof(sbuf):(int)sw_num;
				i=BIO_write(s_bio,sbuf,j);
				if (i < 0)
					{
					s_r=0;
					s_w=0;
					if (BIO_should_retry(s_bio))
						{
						if (BIO_should_read(s_bio))
							s_r=1;
						if (BIO_should_write(s_bio))
							s_w=1;
						}
					else
						{
						fprintf(stderr,"ERROR in SERVER\n");
						ERR_print_errors(bio_err);
						goto err;
						}
					}
				else if (i == 0)
					{
					ERR_print_errors(bio_err);
					fprintf(stderr,"SSL SERVER STARTUP FAILED in SSL_write\n");
					goto err;
					}
				else
					{
					if (debug)
						printf("server wrote %d\n",i);
					sw_num-=i;
					s_write=0;
					c_r=1;
					if (sw_num <= 0)
						done|=S_DONE;
					}
				}
			}

		if ((done & S_DONE) && (done & C_DONE)) break;
		}

	if (verbose)
		print_details(c_ssl, "DONE: ");
	ret=0;
err:
	/* We have to set the BIO's to NULL otherwise they will be
	 * OPENSSL_free()ed twice.  Once when th s_ssl is SSL_free()ed and
	 * again when c_ssl is SSL_free()ed.
	 * This is a hack required because s_ssl and c_ssl are sharing the same
	 * BIO structure and SSL_set_bio() and SSL_free() automatically
	 * BIO_free non NULL entries.
	 * You should not normally do this or be required to do this */
	if (s_ssl != NULL)
		{
		s_ssl->rbio=NULL;
		s_ssl->wbio=NULL;
		}
	if (c_ssl != NULL)
		{
		c_ssl->rbio=NULL;
		c_ssl->wbio=NULL;
		}

	if (c_to_s != NULL) BIO_free(c_to_s);
	if (s_to_c != NULL) BIO_free(s_to_c);
	if (c_bio != NULL) BIO_free_all(c_bio);
	if (s_bio != NULL) BIO_free_all(s_bio);
	return(ret);
	}