void delivery() { std::vector<char> buf(BUFF_SIZE); while(src_sock.available()){ src_sock.read_some(boost::asio::buffer(buf)); dest_sock.write_some(boost::asio::buffer(buf)); } while(dest_sock.available()){ dest_sock.read_some(boost::asio::buffer(buf)); src_sock.write_some(boost::asio::buffer(buf)); } return; }
bool recvFile(tcp::socket &socket, std::string filepath) { std::fstream file; file.open(filepath, std::ios::out | std::ios::binary); if(!file.is_open()) return false; size_t file_size = 0; boost::asio::read(socket, boost::asio::buffer(&file_size, sizeof(file_size))); size_t file_count = 0; while(file_count < file_size) { char buffer[1024]; memset(buffer, 0, sizeof(buffer)); boost::system::error_code ecode; size_t buffer_size = socket.read_some(boost::asio::buffer(buffer, 1024), ecode); if(ecode == boost::asio::error::eof) break; else if(ecode) throw boost::system::system_error(ecode); file.write(buffer,buffer_size); file_count += buffer_size; std::cout << "."; /* boost::array<char, 128> ar; boost::system::error_code ecode; size_t len = socket.read_some(boost::asio::buffer(ar), ecode); if(ecode == boost::asio::error::eof) break; else if(ecode) throw boost::system::system_error(ecode); file.write(ar.data(), len); */ } file.close(); return true; }
TextRconPacket getResponse(tcp::socket & socket) { boost::array<char, 16384> buf; uint8_t responseHeaderBuf[BinaryRconPacketHeader::Size]; size_t len = socket.read_some(boost::asio::buffer(buf)); for(uint8_t pos = 0; pos < BinaryRconPacketHeader::Size; pos++) responseHeaderBuf[pos] = buf[pos]; BinaryRconPacketHeader binaryRconPacketHeader(responseHeaderBuf); if(!binaryRconPacketHeader.isValid()) throw string("Invalid Binary Packet Header"); uint32_t binaryRconResponsePacketSize = binaryRconPacketHeader.getPacketSize(); uint32_t binaryRconResponseBodySize = binaryRconResponsePacketSize - BinaryRconPacketHeader::Size; uint8_t* responseBodyBuf = new uint8_t[binaryRconResponseBodySize]; for(uint32_t pos = 0; pos < binaryRconResponseBodySize; pos++) responseBodyBuf[pos] = buf[pos + BinaryRconPacketHeader::Size]; BinaryRconPacket binaryResponse(binaryRconPacketHeader, responseBodyBuf); if(!binaryResponse.isValid()) throw string("Invalid Binary Packet"); return TextRconPacket(binaryResponse); }
void TcpBase::receiveMessages(tcp::socket& s) { mutex::scoped_lock lock(mutex_); boost::system::error_code error; char data[MAX_LEN]; size_t length = s.read_some(asio::buffer(data), error); if (length == 0 && error == asio::error::would_block) { boost::this_thread::sleep(boost::posix_time::milliseconds(1)); return; } if (error) { throw boost::system::system_error(error); } data[length] = '\0'; logTrace(name_ + " TcpServer new message"); std::string messagesStr(data); std::vector<std::string> messages; split(messages, messagesStr, is_any_of("\r\n")); for_each(messages.begin(), messages.end(), [this](std::string& message) { logTrace("RX: " + message); inQueue_.push(message); }); }
void session(tcp::socket sock) { try { for (;;) { char data[max_length]; asio::error_code error; size_t length = sock.read_some(asio::buffer(data), error); if (error == asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw asio::system_error(error); // Some other error. asio::write(sock, asio::buffer(data, length)); } } catch (std::exception& e) { std::cerr << "Exception in thread: " << e.what() << "\n"; } }
void session_thread(tcp::socket sock) { std::stringstream threadName; threadName << sock.remote_endpoint(); loguru::set_thread_name(threadName.str().c_str()); auto db = Storage::Mongo::MongoBackend{ "mongodb://localhost", "directory", "rootdn", "dc=mongodb,dc=com" }; bool noAuthentication = false; // Put this into its own scope so the YAML nodes get cleaned up. { auto check = config["noAuthentication"]; if (check && check.as<bool>() == true) noAuthentication = true; } bool userBound = false; std::string userBoundDN; for (;;) { std::vector<uint8_t> header(2);; size_t length; asio::error_code error; length = sock.read_some(asio::buffer(header), error); if (error) { if (error == asio::error::eof) break; else throw asio::system_error(error); } if (length != header.size()) { LOG_F(ERROR, "Client sent malformed BER header"); break; } std::vector<uint8_t> reqBuffer; reqBuffer.reserve(1024); if ((header[1] & 128) != 0) { header[1] -= 128; reqBuffer.resize(header[1]); length = sock.read_some(asio::buffer(reqBuffer), error); if (length != reqBuffer.size()) { LOG_F(ERROR, "Client sent mal-formed BER size header"); break; } auto decodedReqSize = Ber::decodeInteger(reqBuffer.cbegin(), reqBuffer.cend()); reqBuffer.resize(decodedReqSize, 0); } else { reqBuffer.resize(header[1], 0); } length = sock.read_some(asio::buffer(reqBuffer), error); if (length != reqBuffer.size()) { LOG_F(ERROR, "Client sent fewer bytes than expected"); break; } auto ber = Ber::Packet::decode(header[0], reqBuffer); auto messageId = static_cast<uint64_t>(ber.children[0]); auto messageType = Ldap::MessageTag { static_cast<Ldap::MessageTag>(ber.children[1].tag) }; Ldap::MessageTag errorResponseType; switch (messageType) { case Ldap::MessageTag::SearchRequest: errorResponseType = Ldap::MessageTag::SearchResDone; break; default: errorResponseType = static_cast<Ldap::MessageTag>(static_cast<uint8_t>(messageType) + 1); break; } try { if (messageType == Ldap::MessageTag::BindRequest) { Ldap::Bind::Request bindReq(ber.children[1]); if (bindReq.type == Ldap::Bind::Request::Type::Sasl) { // TODO SUPPORT SASL BINDS! throw Ldap::Exception(Ldap::ErrorCode::authMethodNotSupported); } bool passOkay = false; if (noAuthentication) { LOG_S(INFO) << "Authentication is disabled, sending bogus bind for " << bindReq.dn; passOkay = true; } else { LOG_S(INFO) << "Authenticating " << bindReq.dn; try { auto entry = db.findEntry(bindReq.dn); for (const auto& pass: entry->attributes.at("userPassword")) { passOkay = Password::checkPassword(bindReq.simple, pass); if (passOkay) break; } } catch (Ldap::Exception e) { LOG_S(ERROR) << "Error during authentication " << e.what(); if (e == Ldap::ErrorCode::noSuchObject) { throw Ldap::Exception(Ldap::ErrorCode::invalidCredentials); } throw; } } Ldap::ErrorCode respCode; if (passOkay) { respCode = Ldap::ErrorCode::success; userBound = true; userBoundDN = bindReq.dn; } else { respCode = Ldap::ErrorCode::invalidCredentials; userBound = false; userBoundDN = ""; } Ldap::Bind::Response bindResp(Ldap::buildLdapResult(respCode, bindReq.dn, "", Ldap::MessageTag::BindResponse)); sendResponse(sock, messageId, bindResp.response); } else if (messageType == Ldap::MessageTag::SearchRequest) { Ldap::Search::Request searchReq(ber.children[1]); auto cursor = db.findEntries(searchReq); for (const auto& entry: *cursor) { sendResponse(sock, messageId, Ldap::Search::generateResult(entry)); } sendResponse(sock, messageId, Ldap::buildLdapResult(Ldap::ErrorCode::success, "", "", Ldap::MessageTag::SearchResDone)); } else if (messageType == Ldap::MessageTag::AddRequest) { Ldap::Entry entry = Ldap::Add::parseRequest(ber.children[1]); db.saveEntry(entry, true); sendResponse(sock, messageId, Ldap::buildLdapResult(Ldap::ErrorCode::success, "", "", Ldap::MessageTag::AddResponse)); } else if (messageType == Ldap::MessageTag::ModifyRequest) { Ldap::Modify::Request req(ber.children[1]); auto entry = db.findEntry(req.dn); if (entry == nullptr) { throw Ldap::Exception(Ldap::ErrorCode::noSuchObject); } for (const auto& mod: req.mods) { using ModType = Ldap::Modify::Modification::Type; switch(mod.type) { case ModType::Add: for (const auto& v: mod.values) { entry->appendValue(mod.name, v); } break; case ModType::Delete: if (mod.values.size() == 0) { if (entry->attributes.erase(mod.name) == 0) { throw Ldap::Exception(Ldap::ErrorCode::noSuchAttribute); } } else { try { auto curVals = entry->attributes.at(mod.name); std::set<std::string> finalVals(curVals.begin(), curVals.end()); for (const auto& v: mod.values) { if (finalVals.erase(v) == 0) { throw Ldap::Exception(Ldap::ErrorCode::noSuchAttribute); } } curVals.clear(); std::copy(finalVals.begin(), finalVals.end(), std::back_inserter(curVals)); } catch(std::out_of_range) { throw Ldap::Exception(Ldap::ErrorCode::noSuchAttribute); } } break; case ModType::Replace: if (mod.values.size() == 0) { entry->attributes.erase(mod.name); } else { entry->attributes[mod.name] = mod.values; } break; } } db.saveEntry(*entry, false); sendResponse(sock, messageId, Ldap::buildLdapResult(Ldap::ErrorCode::success, "", "", Ldap::MessageTag::ModifyResponse)); } else if (messageType == Ldap::MessageTag::DelRequest) { std::string dn = Ldap::Delete::parseRequest(ber.children[1]); db.deleteEntry(dn); sendResponse(sock, messageId, Ldap::buildLdapResult(Ldap::ErrorCode::success, "", "", Ldap::MessageTag::DelResponse)); } } catch (const Ldap::Exception& e) { auto resPacket = Ldap::buildLdapResult(e, "", e.what(), errorResponseType); sendResponse(sock, messageId, resPacket); break; } catch (const std::exception& e) { auto resPacket = Ldap::buildLdapResult(Ldap::ErrorCode::other, "", e.what(), errorResponseType); sendResponse(sock, messageId, resPacket); break; } catch (...) { auto resPacket = Ldap::buildLdapResult(Ldap::ErrorCode::other, "", "Unknown error occurred", errorResponseType); sendResponse(sock, messageId, resPacket); break; } } }