More refactoring.

This commit is contained in:
James Pace 2022-03-24 01:40:22 +00:00
parent 3309b19c2e
commit deb1cef30f
6 changed files with 32 additions and 37 deletions

View File

@ -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
```

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;

View File

@ -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, "", ""));