Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Encrypted/Authenticated Listeners #2129

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions llarp/config/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "definition.hpp"
#include "ini.hpp"

#include <oxenmq/address.h>
#include <oxenmq/oxenmq.h>
#include <llarp/constants/files.hpp>
#include <llarp/constants/platform.hpp>
#include <llarp/constants/version.hpp>
Expand Down Expand Up @@ -1152,10 +1154,46 @@ namespace llarp
"Recommend localhost-only for security purposes.",
});

conf.defineOption<std::string>("api", "authkey", Deprecated);
conf.defineOption<std::string>(
"api",
"bind_curve",
Default{""},
MultiValue,
[this](std::string arg) mutable {
if (arg.empty())
return;

auto pipe = arg.find("|");

if (pipe == arg.npos)
dr7ana marked this conversation as resolved.
Show resolved Hide resolved
throw std::invalid_argument(
"Addresses and whitelisted pubkeys must be pipe-delimited key:value pairs");

auto key = arg.substr(0, pipe), values = arg.substr(pipe + 1, arg.npos);

// TODO: this was from pre-refactor:
// TODO: add pubkey to whitelist
if (not starts_with(key, "tcp://"))
key = "tcp://" + key;

auto pubkeys = split(values, ",", true);
oxenmq::address key_addr{key};

for (auto& pk : pubkeys)
m_rpcEncryptedAddresses[key_addr].emplace(pk);
},
Comment{
"Specify encrypted listener addresses and comma-delimited public keys to be accepted ",
"by exposed encrypted listener. Keys must be attached to a listener address.",
"",
"Example: ",
" bind_curve=tcp://0.0.0.0:1234|pubkeyA,pubkeyB",
" bind_curve=tcp://0.0.0.0:5678|pubkeyC,pubkeyD",
"",
"In the given example above, port 1234 is only accessible by whitelisted ",
"pubkeys A and B, while 5678 is accessible by C and D.",
"",
"Note: tcp addresses passed without \"tcp://\" prefix will have it prepended"});

conf.defineOption<std::string>("api", "authkey", Deprecated);
}

void
Expand Down
4 changes: 3 additions & 1 deletion llarp/config/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#include "ini.hpp"
#include "definition.hpp"

#include <oxenmq/auth.h>
#include <chrono>

#include <llarp/bootstrap.hpp>
#include <llarp/crypto/types.hpp>
#include <llarp/router_contact.hpp>
Expand All @@ -26,6 +26,7 @@
#include <utility>
#include <vector>
#include <unordered_set>
#include <unordered_map>

#include <oxenmq/address.h>

Expand Down Expand Up @@ -190,6 +191,7 @@ namespace llarp
{
bool m_enableRPCServer = false;
std::vector<oxenmq::address> m_rpcBindAddresses;
std::unordered_map<oxenmq::address, std::unordered_set<std::string>> m_rpcEncryptedAddresses;

void
defineConfigOptions(ConfigDefinition& conf, const ConfigGenParameters& params);
Expand Down
19 changes: 18 additions & 1 deletion llarp/rpc/rpc_server.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "rpc_server.hpp"
#include "llarp/rpc/rpc_request_definitions.hpp"
#include "llarp/util/logging.hpp"
#include "oxen/log.hpp"
#include "rpc_request.hpp"
#include "llarp/service/address.hpp"
#include <cmath>
Expand Down Expand Up @@ -106,7 +108,22 @@ namespace llarp::rpc
for (const auto& addr : r.GetConfig()->api.m_rpcBindAddresses)
{
m_LMQ->listen_plain(addr.zmq_address());
LogInfo("Bound RPC server to ", addr.full_address());
log::info(logcat, "Bound RPC server to {}", addr.full_address());
}

for (const auto& [address, allowed_keys] : r.GetConfig()->api.m_rpcEncryptedAddresses)
{
m_LMQ->listen_curve(
address.zmq_address(), [allowed_keys = allowed_keys](auto addr, auto pk, ...) {
if (allowed_keys.count(std::string{pk}))
return oxenmq::AuthLevel::admin;

log::warning(
logcat,
"Curve pubkey not in whitelist, denying incoming RPC connection from {}",
addr);
return oxenmq::AuthLevel::denied;
});
}

AddCategories();
Expand Down