Exemple #1
0
	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;
}
Exemple #3
0
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);
}
Exemple #4
0
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";
  }
}
Exemple #6
0
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;
        }
    }
}