mirror of https://github.com/oxen-io/lokinet
address feedback.
* use exceptions when fetching identity key instead of std::optional, will throw on fail * fix up config options for endpoint auth and add better docs * add llarp::serive::AuthType enum for controlling what kind of endpoint auth to use
This commit is contained in:
parent
a7c42ab2bd
commit
80919a3b76
|
@ -165,12 +165,16 @@ namespace llarp
|
|||
|
||||
conf.defineOption<std::string>("network", "keyfile", false, "", AssignmentAcceptor(m_keyfile));
|
||||
|
||||
conf.defineOption<bool>("network", "auth", false, false, AssignmentAcceptor(m_AuthEnabled));
|
||||
conf.defineOption<std::string>("network", "auth", false, "", [this](std::string arg) {
|
||||
if (arg.empty())
|
||||
return;
|
||||
m_AuthType = service::ParseAuthType(arg);
|
||||
});
|
||||
|
||||
conf.defineOption<std::string>("network", "auth-url", false, "", AssignmentAcceptor(m_AuthUrl));
|
||||
conf.defineOption<std::string>("network", "auth-lmq", false, "", AssignmentAcceptor(m_AuthUrl));
|
||||
|
||||
conf.defineOption<std::string>(
|
||||
"network", "auth-method", false, "llarp.auth", [this](std::string arg) {
|
||||
"network", "auth-lmq-method", false, "llarp.auth", [this](std::string arg) {
|
||||
if (arg.empty())
|
||||
return;
|
||||
m_AuthMethod = std::move(arg);
|
||||
|
@ -877,7 +881,10 @@ namespace llarp
|
|||
"network",
|
||||
"exit-node",
|
||||
{
|
||||
"Specify a `.loki` address to use as an exit broker.",
|
||||
"Specify a `.loki` address and an optional ip range to use as an exit broker.",
|
||||
"Example:",
|
||||
"exit-node=whatever.loki # maps all exit traffic to whatever.loki",
|
||||
"exit-node=stuff.loki:100.0.0.0/24 # maps 100.0.0.0/24 to stuff.loki",
|
||||
});
|
||||
|
||||
def.addOptionComments(
|
||||
|
@ -901,21 +908,22 @@ namespace llarp
|
|||
"network",
|
||||
"auth",
|
||||
{
|
||||
"authenticate remote sessions against a whitelist or an external lmq server",
|
||||
"true/false",
|
||||
"Set the endpoint authentication mechanism.",
|
||||
"none/whitelist/lmq",
|
||||
});
|
||||
|
||||
def.addOptionComments(
|
||||
"network",
|
||||
"auth-url",
|
||||
"auth-lmq",
|
||||
{
|
||||
"lmq endpoint to talk to for authenticating new sessions",
|
||||
"ipc:///var/lib/lokinet/auth.socket",
|
||||
"tcp://127.0.0.1:5555",
|
||||
});
|
||||
|
||||
def.addOptionComments(
|
||||
"network",
|
||||
"auth-method",
|
||||
"auth-lmq-method",
|
||||
{
|
||||
"lmq function to call for authenticating new sessions",
|
||||
"llarp.auth",
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <net/net_int.hpp>
|
||||
#include <net/ip_range_map.hpp>
|
||||
#include <service/address.hpp>
|
||||
#include <service/auth.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
|
@ -83,7 +84,7 @@ namespace llarp
|
|||
net::IPRangeMap<service::Address> m_ExitMap;
|
||||
std::unordered_map<huint128_t, service::Address> m_mapAddrs;
|
||||
|
||||
bool m_AuthEnabled = false;
|
||||
service::AuthType m_AuthType = service::AuthType::eAuthTypeNone;
|
||||
std::optional<std::string> m_AuthUrl;
|
||||
std::optional<std::string> m_AuthMethod;
|
||||
std::unordered_set<service::Address, service::Address::Hash> m_AuthWhitelist;
|
||||
|
|
|
@ -93,8 +93,7 @@ namespace llarp
|
|||
router = std::make_unique<Router>(mainloop, logic);
|
||||
|
||||
nodedb = std::make_unique<llarp_nodedb>(
|
||||
nodedb_dir,
|
||||
[r = router.get()](std::function<void(void)> call) { r->QueueDiskIO(std::move(call)); });
|
||||
nodedb_dir, [r = router.get()](auto call) { r->QueueDiskIO(std::move(call)); });
|
||||
|
||||
if (!router->Configure(config.get(), opts.isRouter, nodedb.get()))
|
||||
throw std::runtime_error("Failed to configure router");
|
||||
|
|
|
@ -117,14 +117,16 @@ namespace llarp
|
|||
LogInfo(Name(), " setting to be not reachable by default");
|
||||
}
|
||||
|
||||
if (conf.m_AuthUrl.has_value() and conf.m_AuthMethod.has_value())
|
||||
if (conf.m_AuthType != service::AuthType::eAuthTypeNone)
|
||||
{
|
||||
std::string url, method;
|
||||
if (conf.m_AuthUrl.has_value() and conf.m_AuthMethod.has_value())
|
||||
{
|
||||
url = *conf.m_AuthUrl;
|
||||
method = *conf.m_AuthMethod;
|
||||
}
|
||||
auto auth = std::make_shared<rpc::EndpointAuthRPC>(
|
||||
*conf.m_AuthUrl,
|
||||
*conf.m_AuthMethod,
|
||||
conf.m_AuthWhitelist,
|
||||
Router()->lmq(),
|
||||
shared_from_this());
|
||||
url, method, conf.m_AuthWhitelist, Router()->lmq(), shared_from_this());
|
||||
auth->Start();
|
||||
m_AuthPolicy = std::move(auth);
|
||||
}
|
||||
|
|
|
@ -212,9 +212,7 @@ namespace llarp
|
|||
return false;
|
||||
#endif
|
||||
#endif
|
||||
const auto maybe = RpcClient()->ObtainIdentityKey();
|
||||
if (maybe.has_value())
|
||||
_identity = *maybe;
|
||||
_identity = RpcClient()->ObtainIdentityKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -287,7 +285,7 @@ namespace llarp
|
|||
LogError("RC is invalid, not saving");
|
||||
return false;
|
||||
}
|
||||
QueueDiskIO(std::bind(&Router::HandleSaveRC, this));
|
||||
QueueDiskIO([&]() { HandleSaveRC(); });
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,44 +158,42 @@ namespace llarp
|
|||
LogicCall(m_Router->logic(), [r = m_Router, nodeList]() { r->SetRouterWhitelist(nodeList); });
|
||||
}
|
||||
|
||||
std::optional<SecretKey>
|
||||
SecretKey
|
||||
LokidRpcClient::ObtainIdentityKey()
|
||||
{
|
||||
std::promise<std::optional<SecretKey>> promise;
|
||||
|
||||
std::promise<SecretKey> promise;
|
||||
Request(
|
||||
"admin.get_service_privkeys",
|
||||
[self = shared_from_this(), &promise](bool success, std::vector<std::string> data) {
|
||||
if (not success)
|
||||
{
|
||||
LogError("failed to get private key");
|
||||
promise.set_value(std::nullopt);
|
||||
return;
|
||||
}
|
||||
if (data.empty())
|
||||
{
|
||||
LogError("failed to get private key, no response");
|
||||
promise.set_value(std::nullopt);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
auto j = nlohmann::json::parse(data[0]);
|
||||
if (not success)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"failed to get private key request "
|
||||
"failed");
|
||||
}
|
||||
if (data.empty())
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"failed to get private key request "
|
||||
"data empty");
|
||||
}
|
||||
const auto j = nlohmann::json::parse(data[0]);
|
||||
SecretKey k;
|
||||
if (not k.FromHex(j.at("service_node_ed25519_privkey").get<std::string>()))
|
||||
{
|
||||
promise.set_value(std::nullopt);
|
||||
return;
|
||||
throw std::runtime_error("failed to parse private key");
|
||||
}
|
||||
promise.set_value(k);
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
catch (...)
|
||||
{
|
||||
LogError("failed to get private key: ", ex.what());
|
||||
promise.set_value(std::nullopt);
|
||||
promise.set_exception(std::current_exception());
|
||||
}
|
||||
});
|
||||
return promise.get_future().get();
|
||||
auto ftr = promise.get_future();
|
||||
return ftr.get();
|
||||
}
|
||||
|
||||
} // namespace rpc
|
||||
|
|
|
@ -26,7 +26,8 @@ namespace llarp
|
|||
ConnectAsync(lokimq::address url);
|
||||
|
||||
/// blocking request identity key from lokid
|
||||
std::optional<SecretKey>
|
||||
/// throws on failure
|
||||
SecretKey
|
||||
ObtainIdentityKey();
|
||||
|
||||
private:
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace llarp::service
|
|||
std::optional<AuthResult>
|
||||
ParseAuthResult(std::string data)
|
||||
{
|
||||
static thread_local std::unordered_map<std::string, AuthResult> values = {
|
||||
static std::unordered_map<std::string, AuthResult> values = {
|
||||
{"OKAY", AuthResult::eAuthAccepted},
|
||||
{"REJECT", AuthResult::eAuthRejected},
|
||||
{"PAYME", AuthResult::eAuthPaymentRequired},
|
||||
|
@ -17,4 +17,17 @@ namespace llarp::service
|
|||
return std::nullopt;
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
AuthType
|
||||
ParseAuthType(std::string data)
|
||||
{
|
||||
static std::unordered_map<std::string, AuthType> values = {
|
||||
{"lmq", AuthType::eAuthTypeLMQ},
|
||||
{"whitelist", AuthType::eAuthTypeWhitelist},
|
||||
{"none", AuthType::eAuthTypeNone}};
|
||||
const auto itr = values.find(data);
|
||||
if (itr == values.end())
|
||||
throw std::invalid_argument("no such auth type: " + data);
|
||||
return itr->second;
|
||||
}
|
||||
} // namespace llarp::service
|
||||
|
|
|
@ -45,4 +45,20 @@ namespace llarp::service
|
|||
std::string token;
|
||||
};
|
||||
|
||||
/// what kind of backend to use for auth
|
||||
enum class AuthType
|
||||
{
|
||||
/// no authentication
|
||||
eAuthTypeNone,
|
||||
/// manual whitelist
|
||||
eAuthTypeWhitelist,
|
||||
/// LMQ server
|
||||
eAuthTypeLMQ
|
||||
};
|
||||
|
||||
/// get an auth type from a string
|
||||
/// throws std::invalid_argument if arg is invalid
|
||||
AuthType
|
||||
ParseAuthType(std::string arg);
|
||||
|
||||
} // namespace llarp::service
|
||||
|
|
Loading…
Reference in New Issue