More refactoring.
This commit is contained in:
parent
3309b19c2e
commit
deb1cef30f
12
README.md
12
README.md
|
|
@ -8,6 +8,12 @@ sudo apt install mosquitto-dev g++ cmake libmosquitto-dev mosquitto-clients open
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generating offline keys
|
## Generating offline keys
|
||||||
ssh-keygen -t rsa -b 4096 -m PEM -f priv.key
|
```
|
||||||
rm priv.key.pub
|
openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:2048
|
||||||
openssl rsa -in priv.key -pubout -outform PEM -out pub.key
|
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
## Converting Client Keys to Format for Browser
|
||||||
|
```
|
||||||
|
openssl pkcs12 -export -out client.p12 -inkey client-key.pem -in -client.pem -certfile ca.pem
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// Copyright 2022 James Pace
|
// Copyright 2022 James Pace
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
@ -20,7 +19,7 @@
|
||||||
|
|
||||||
std::optional<std::string> read_key(const std::string & key_file);
|
std::optional<std::string> read_key(const std::string & key_file);
|
||||||
|
|
||||||
std::tuple<bool, bool> validate(
|
bool validate(
|
||||||
const std::string & token,
|
const std::string & token,
|
||||||
const std::string & username,
|
const std::string & username,
|
||||||
const std::string & issuer,
|
const std::string & issuer,
|
||||||
|
|
@ -29,8 +28,7 @@ std::tuple<bool, bool> validate(
|
||||||
std::string gen_token(
|
std::string gen_token(
|
||||||
const std::string & issuer,
|
const std::string & issuer,
|
||||||
const std::string & username,
|
const std::string & username,
|
||||||
const std::string & can_read,
|
|
||||||
const std::string & can_write,
|
|
||||||
const std::string & pub_key,
|
const std::string & pub_key,
|
||||||
const std::string & priv_key,
|
const std::string & priv_key,
|
||||||
|
const std::chrono::time_point<std::chrono::system_clock> & issue_time,
|
||||||
const std::chrono::time_point<std::chrono::system_clock> & expr_time);
|
const std::chrono::time_point<std::chrono::system_clock> & expr_time);
|
||||||
|
|
|
||||||
|
|
@ -34,21 +34,16 @@ bool Authorizer::is_unknown(const std::string & username)
|
||||||
|
|
||||||
bool Authorizer::add(const std::string & token, const std::string & username)
|
bool Authorizer::add(const std::string & token, const std::string & username)
|
||||||
{
|
{
|
||||||
const auto [can_read, can_write] = validate(token, username, _issuer, _pub_key);
|
const auto validated = validate(token, username, _issuer, _pub_key);
|
||||||
if (not(can_write or can_read))
|
if (not validated)
|
||||||
{
|
{
|
||||||
std::cerr << "Can't write or can't read." << std::endl;
|
std::cerr << "Not validated." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_write)
|
// TODO: Check ACL file to see which one.
|
||||||
{
|
|
||||||
_writeList.add(username);
|
_writeList.add(username);
|
||||||
}
|
|
||||||
if (can_read)
|
|
||||||
{
|
|
||||||
_readList.add(username);
|
_readList.add(username);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,16 +62,16 @@ int main(int argc, char * argv[])
|
||||||
const std::string can_read = program.get<bool>("--can-read") ? "true" : "false";
|
const std::string can_read = program.get<bool>("--can-read") ? "true" : "false";
|
||||||
const std::string can_write = program.get<bool>("--can-write") ? "true" : "false";
|
const std::string can_write = program.get<bool>("--can-write") ? "true" : "false";
|
||||||
|
|
||||||
const auto expr_time = std::chrono::system_clock::now() +
|
const auto now = std::chrono::system_clock::now();
|
||||||
std::chrono::days(std::stoi(program.get<std::string>("--valid-days")));
|
const auto expr_time =
|
||||||
|
now + std::chrono::days(std::stoi(program.get<std::string>("--valid-days")));
|
||||||
|
|
||||||
const auto token = gen_token(
|
const auto token = gen_token(
|
||||||
program.get<std::string>("--issuer"),
|
program.get<std::string>("--issuer"),
|
||||||
program.get<std::string>("--username"),
|
program.get<std::string>("--username"),
|
||||||
can_read,
|
|
||||||
can_write,
|
|
||||||
pub_key.value(),
|
pub_key.value(),
|
||||||
priv_key.value(),
|
priv_key.value(),
|
||||||
|
now,
|
||||||
expr_time);
|
expr_time);
|
||||||
|
|
||||||
std::cout << token;
|
std::cout << token;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ std::optional<std::string> read_key(const std::string & key_file)
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<bool, bool> validate(
|
bool validate(
|
||||||
const std::string & token,
|
const std::string & token,
|
||||||
const std::string & username,
|
const std::string & username,
|
||||||
const std::string & issuer,
|
const std::string & issuer,
|
||||||
|
|
@ -50,7 +50,7 @@ std::tuple<bool, bool> validate(
|
||||||
catch (jwt::error::token_verification_exception & exception)
|
catch (jwt::error::token_verification_exception & exception)
|
||||||
{
|
{
|
||||||
std::cerr << exception.what() << std::endl;
|
std::cerr << exception.what() << std::endl;
|
||||||
return std::make_tuple(false, false);
|
return false;
|
||||||
}
|
}
|
||||||
auto claims = decoded_token.get_payload_claims();
|
auto claims = decoded_token.get_payload_claims();
|
||||||
|
|
||||||
|
|
@ -58,42 +58,38 @@ std::tuple<bool, bool> validate(
|
||||||
if (not claims.contains("upn"))
|
if (not claims.contains("upn"))
|
||||||
{
|
{
|
||||||
std::cerr << "Missing upn." << std::endl;
|
std::cerr << "Missing upn." << std::endl;
|
||||||
return std::make_tuple(false, false);
|
return false;
|
||||||
}
|
}
|
||||||
if (claims["upn"].as_string() != username)
|
if (claims["upn"].as_string() != username)
|
||||||
{
|
{
|
||||||
std::cerr << "Wrong username." << std::endl;
|
std::cerr << "Wrong username." << std::endl;
|
||||||
return std::make_tuple(false, false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for mqtt-write claim value.
|
// Check for mqtt-write claim value.
|
||||||
if (not(claims.contains("mqtt-write") and claims.contains("mqtt-read")))
|
if (not claims.contains("mqtt"))
|
||||||
{
|
{
|
||||||
std::cerr << "Missing mqtt-write or mqtt-read." << std::endl;
|
std::cerr << "Missing mqtt claim." << std::endl;
|
||||||
return std::make_tuple(false, false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_read = claims["mqtt-read"].as_bool();
|
return claims["mqtt"].as_bool();
|
||||||
bool can_write = claims["mqtt-write"].as_bool();
|
|
||||||
|
|
||||||
return std::make_tuple(can_read, can_write);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string gen_token(
|
std::string gen_token(
|
||||||
const std::string & issuer,
|
const std::string & issuer,
|
||||||
const std::string & username,
|
const std::string & username,
|
||||||
const std::string & can_read,
|
|
||||||
const std::string & can_write,
|
|
||||||
const std::string & pub_key,
|
const std::string & pub_key,
|
||||||
const std::string & priv_key,
|
const std::string & priv_key,
|
||||||
|
const std::chrono::time_point<std::chrono::system_clock> & issue_time,
|
||||||
const std::chrono::time_point<std::chrono::system_clock> & expr_time)
|
const std::chrono::time_point<std::chrono::system_clock> & expr_time)
|
||||||
{
|
{
|
||||||
const auto token = jwt::create()
|
const auto token = jwt::create()
|
||||||
.set_type("JWT")
|
.set_type("JWT")
|
||||||
.set_issuer(issuer)
|
.set_issuer(issuer)
|
||||||
.set_payload_claim("upn", jwt::claim(username))
|
.set_payload_claim("upn", jwt::claim(username))
|
||||||
.set_payload_claim("mqtt-read", jwt::claim(can_read))
|
.set_payload_claim("mqtt", jwt::claim(std::string("true")))
|
||||||
.set_payload_claim("mqtt-write", jwt::claim(can_write))
|
.set_issued_at(issue_time)
|
||||||
.set_expires_at(expr_time)
|
.set_expires_at(expr_time)
|
||||||
.sign(jwt::algorithm::rs256(pub_key, priv_key, "", ""));
|
.sign(jwt::algorithm::rs256(pub_key, priv_key, "", ""));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue