From eac5817fe5ed5052599bbfb1ab3f6ade426010d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Felix=20D=C3=B6rre?= Date: Wed, 11 Nov 2015 16:28:42 +0100 Subject: [PATCH] upd: use central position to do line buffering --- src/crypto/remoteSigner.cpp | 27 +++------------------------ src/io/opensslBIO.cpp | 32 +++++++++++++++++++++++++++++++- src/io/opensslBIO.h | 9 +++++++++ src/io/record.cpp | 14 +++++++++++++- src/io/recordHandler.cpp | 18 ++++++------------ src/io/slipBio.cpp | 4 ++-- 6 files changed, 64 insertions(+), 40 deletions(-) diff --git a/src/crypto/remoteSigner.cpp b/src/crypto/remoteSigner.cpp index 6db3973..f4680d6 100644 --- a/src/crypto/remoteSigner.cpp +++ b/src/crypto/remoteSigner.cpp @@ -69,20 +69,11 @@ std::shared_ptr RemoteSigner::sign( std::shared_ptr(); - std::vector buffer( 2048 * 4 ); for( int i = 0; i < 3; i++ ) { try { - int length = conn->read( buffer.data(), buffer.size() ); - - if( length <= 0 ) { - logger::error( "Error, no response data" ); - result = nullptr; - break; - } - RecordHeader head; - std::string payload = parseCommand( head, std::string( buffer.data(), length ) ); + std::string payload = parseCommand( head, conn->readLine() ); switch( static_cast( head.command )) { case RecordHeader::SignerResult::CERTIFICATE: @@ -171,14 +162,7 @@ std::pair, std::string> RemoteSigner::revoke( std::shared_p std::string payload = ca->name; send( conn, head, RecordHeader::SignerCommand::REVOKE, payload ); - std::vector buffer( 2048 * 4 ); - int length = conn->read( buffer.data(), buffer.size() ); - - if( length <= 0 ) { - throw "Error, no response data"; - } - - payload = parseCommand( head, std::string( buffer.data(), length ) ); + payload = parseCommand( head, conn->readLine() ); auto crl = std::make_shared( ca->path + std::string( "/ca.crl" ) ); std::string date; @@ -207,13 +191,8 @@ std::pair, std::string> RemoteSigner::revoke( std::shared_p } else { logger::warn( "CRL is broken, trying to recover" ); send( conn, head, RecordHeader::SignerCommand::GET_FULL_CRL, ca->name ); - length = conn->read( buffer.data(), buffer.size() ); - - if( length <= 0 ) { - throw "Error, no response data"; - } - payload = parseCommand( head, std::string( buffer.data(), length ) ); + payload = parseCommand( head, conn->readLine() ); if( static_cast( head.command ) != RecordHeader::SignerResult::FULL_CRL ) { throw "Protocol violation"; diff --git a/src/io/opensslBIO.cpp b/src/io/opensslBIO.cpp index 03122db..056c291 100644 --- a/src/io/opensslBIO.cpp +++ b/src/io/opensslBIO.cpp @@ -1,6 +1,6 @@ #include "opensslBIO.h" -OpensslBIOWrapper::OpensslBIOWrapper( std::shared_ptr b ) : b( b ) { +OpensslBIOWrapper::OpensslBIOWrapper( std::shared_ptr _b ) : b( _b ), buffer( 2*0xFFFF+20, 0 ), pos(0) { } OpensslBIOWrapper::~OpensslBIOWrapper() { @@ -29,3 +29,33 @@ int OpensslBIOWrapper::gets( char* str, int size ) { const char* OpensslBIOWrapper::getName() { return "OpenSSLWrapper"; } +#include +std::string OpensslBIOWrapper::readLine(){ + int target = 0; + while(1){ + logger::warn("doing data"); + while(target < pos){ + if(buffer[target] == '\n'){ + target++; + std::string res(buffer.data(), 0, target); + std::copy(buffer.data() + target, buffer.data() + pos, buffer.data() ); + pos -= target; + logger::warn("emit"); + return res; + } + target++; + } + std::stringstream ss; + ss << "target: " << target << ", pos:" << pos; + logger::warn(ss.str()); + int dlen = read(buffer.data() + pos, buffer.size() - pos); + if ( dlen <= 0 ){ + logger::warn(" error! "); + throw EOFException(); + } + std::stringstream ss2; + ss2 << "done: " << dlen; + logger::warn(ss2.str()); + pos += dlen; + } +} diff --git a/src/io/opensslBIO.h b/src/io/opensslBIO.h index a3d7188..092fa9c 100644 --- a/src/io/opensslBIO.h +++ b/src/io/opensslBIO.h @@ -2,10 +2,14 @@ #include #include "bios.h" +#include +#include class OpensslBIOWrapper : public OpensslBIO { private: std::shared_ptr b; + std::vector buffer; + int pos = 0; public: OpensslBIOWrapper( std::shared_ptr b ); virtual ~OpensslBIOWrapper(); @@ -18,4 +22,9 @@ public: int gets( char* str, int size ); static const char* getName(); + + std::string readLine(); +}; + +class EOFException : public std::exception{ }; diff --git a/src/io/record.cpp b/src/io/record.cpp index 1332a0f..97e6015 100644 --- a/src/io/record.cpp +++ b/src/io/record.cpp @@ -25,6 +25,12 @@ std::string toHexAndChecksum( const std::string& src ) { } void sendCommand( RecordHeader& head, const std::string& data, std::shared_ptr bio ) { + std::stringstream ss; + ss << data.size(); + logger::debugf( "Record payload length: %s", ss.str() ); + if(data.size() > 0xFFFF){ + logger::warn( "Data too big, need chunking" ); + } head.payloadLength = data.size(); std::string s; s += head.packToString(); @@ -79,7 +85,13 @@ std::string parseCommand( RecordHeader& head, const std::string& input) { uint32_t expectedTotalLength = ( RECORD_HEADER_SIZE + len + 1 /*checksum*/ ) * 2 + 2; std::string data = str.substr( RECORD_HEADER_SIZE, str.size() - RECORD_HEADER_SIZE ); - if( checksum != -1 || expectedTotalLength != input.size() || error || dlen < RECORD_HEADER_SIZE ) { + if( expectedTotalLength != input.size() ) { + std::stringstream ss; + ss << "Expected: " << expectedTotalLength << ", Got: " << input.size(); + logger::error( ss.str() ); + throw "Error, invalid length"; + } + if( checksum != -1 || error || dlen < RECORD_HEADER_SIZE ) { throw "Error, invalid checksum"; } diff --git a/src/io/recordHandler.cpp b/src/io/recordHandler.cpp index b2fe82c..2d58be0 100644 --- a/src/io/recordHandler.cpp +++ b/src/io/recordHandler.cpp @@ -72,16 +72,7 @@ public: } void work() { - std::vector buffer( 2048 ); - int res = io->read( buffer.data(), buffer.size() ); - - if( res <= 0 ) { - logger::error( "Stream error, resetting SSL" ); - parent->reset(); - return; - } - - std::string content( buffer.data(), res ); + std::string content = io->readLine(); try { RecordHeader head; @@ -242,6 +233,9 @@ void DefaultRecordHandler::handle() { logger::note( "New session allocated." ); currentSession = std::make_shared( this, signer, ctx, bio ); } - - currentSession->work(); + try { + currentSession->work(); + } catch( EOFException e ){ + reset(); + } } diff --git a/src/io/slipBio.cpp b/src/io/slipBio.cpp index f3db820..a9100b3 100644 --- a/src/io/slipBio.cpp +++ b/src/io/slipBio.cpp @@ -6,7 +6,7 @@ #include "log/logger.hpp" -static constexpr std::size_t buffer_size = 8192; +static constexpr std::size_t buffer_size = 2 * 0xFFFF + 20;//8192; #define SLIP_ESCAPE_CHAR ( (char) 0xDB) #define SLIP_CONNECTION ( (char) 0xC0) @@ -44,7 +44,7 @@ std::string toHex( const char* buf, int len ) { return data; } -SlipBIO::SlipBIO() : buffer( std::vector( buffer_size ) ), decodeTarget( 0 ), decodePos( 0 ), rawPos( 0 ) { +SlipBIO::SlipBIO() : buffer( buffer_size ), decodeTarget( 0 ), decodePos( 0 ), rawPos( 0 ) { } void SlipBIO::setTarget( std::shared_ptr target, bool server ) { -- 2.39.2