summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancis Dupont <fdupont@isc.org>2021-11-28 15:26:42 +0100
committerRazvan Becheriu <razvan@isc.org>2022-01-21 18:15:38 +0100
commit71a6b1261bcfe89f6f3634960514bf2a929d79bf (patch)
treea1e64d9edbdbbfb1af59b30cabe4c61061f12fd8
parent[#2208] removed references of %l from logger pattern (diff)
downloadkea-71a6b1261bcfe89f6f3634960514bf2a929d79bf.tar.xz
kea-71a6b1261bcfe89f6f3634960514bf2a929d79bf.zip
[#2006] Added doc and syntax
-rw-r--r--doc/examples/agent/simple.json21
-rw-r--r--doc/sphinx/arm/agent.rst17
-rw-r--r--src/bin/agent/agent_lexer.ll27
-rw-r--r--src/bin/agent/agent_parser.yy36
-rw-r--r--src/bin/agent/simple_parser.cc5
5 files changed, 101 insertions, 5 deletions
diff --git a/doc/examples/agent/simple.json b/doc/examples/agent/simple.json
index e248bf5e3e..3f8fbd1588 100644
--- a/doc/examples/agent/simple.json
+++ b/doc/examples/agent/simple.json
@@ -27,6 +27,10 @@
// Its default is "kea-control-agent".
"realm": "kea-control-agent",
+ // This optional parameter can be used to specify a common
+ // prefix for files handling client credentials.
+ "directory": "/tmp/ca",
+
// This list specifies the user ids and passwords to use for
// basic HTTP authentication. If empty or not present any client
// is authorized.
@@ -42,7 +46,22 @@
// If password is not specified an empty password is used.
"password": "1234"
- }
+ },
+
+ // This specifies a hiddent client.
+ {
+ // The user id is the content of the file /tmp/ca/hiddenu.
+ "user-file": "hiddenu",
+
+ // The password is the content of the file /tmp/ca/hiddenp.
+ "password-file": "hiddenp"
+ },
+
+ // This specifies a hidden client using a secret in a file.
+ {
+ // The secret is the content of the file /tmp/ca/hiddens
+ // which must be in the <user-id>%<password> format.
+ "password-file": "hiddens"
]
},
diff --git a/doc/sphinx/arm/agent.rst b/doc/sphinx/arm/agent.rst
index 9e9ecdaa12..8e559b0bd5 100644
--- a/doc/sphinx/arm/agent.rst
+++ b/doc/sphinx/arm/agent.rst
@@ -173,6 +173,23 @@ is used.
in UTF-8, but the current Kea JSON syntax only supports the Latin-1
(i.e. 0x00..0xff) Unicode subset.
+To avoid to expose the password or both the user ID and the associated
+password these values can be read from files. The syntax was extended by:
+
+- The ``directory`` authentication parameter which handles the common
+ part of file paths. By default the value is the empty string.
+
+- The``password-file`` client parameter which with the ``directory``
+ parameter specifies the path of a file where the password or when no
+ user ID is given the whole basic HTTP authentication secret before
+ encoding can be read.
+
+- The ``user-file`` client parameter which with the ``directory`` parameter
+ specifies the path of a file where the user ID can be read.
+
+When files are used they are read when the configuration is loaded in order
+to detect configuration errors as soon as possible.
+
Hook libraries can be loaded by the Control Agent in the same way as
they are loaded by the DHCPv4 and DHCPv6 servers. The CA currently
supports one hook point - ``control_command_receive`` - which makes it
diff --git a/src/bin/agent/agent_lexer.ll b/src/bin/agent/agent_lexer.ll
index 57ec1232f8..775bf31230 100644
--- a/src/bin/agent/agent_lexer.ll
+++ b/src/bin/agent/agent_lexer.ll
@@ -263,6 +263,15 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
}
}
+\"directory\" {
+ switch(driver.ctx_) {
+ case ParserContext::AUTHENTICATION:
+ return AgentParser::make_DIRECTORY(driver.loc_);
+ default:
+ return AgentParser::make_STRING("directory", driver.loc_);
+ }
+}
+
\"clients\" {
switch(driver.ctx_) {
case ParserContext::AUTHENTICATION:
@@ -281,6 +290,15 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
}
}
+\"user-file\" {
+ switch(driver.ctx_) {
+ case ParserContext::CLIENTS:
+ return AgentParser::make_USER_FILE(driver.loc_);
+ default:
+ return AgentParser::make_STRING("user-file", driver.loc_);
+ }
+}
+
\"password\" {
switch(driver.ctx_) {
case ParserContext::CLIENTS:
@@ -290,6 +308,15 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
}
}
+\"password-file\" {
+ switch(driver.ctx_) {
+ case ParserContext::CLIENTS:
+ return AgentParser::make_PASSWORD_FILE(driver.loc_);
+ default:
+ return AgentParser::make_STRING("password-file", driver.loc_);
+ }
+}
+
\"trust-anchor\" {
switch(driver.ctx_) {
case ParserContext::AGENT:
diff --git a/src/bin/agent/agent_parser.yy b/src/bin/agent/agent_parser.yy
index fd4aaf96d7..648bf25ea6 100644
--- a/src/bin/agent/agent_parser.yy
+++ b/src/bin/agent/agent_parser.yy
@@ -59,9 +59,11 @@ using namespace std;
TYPE "type"
BASIC "basic"
REALM "realm"
+ DIRECTORY "directory"
CLIENTS "clients"
USER "user"
- PASSWORD "password"
+ USER_FILE "user-file"
+ PASSWORD_FILE "password-file"
TRUST_ANCHOR "trust-anchor"
CERT_FILE "cert-file"
@@ -589,6 +591,7 @@ auth_params: auth_param
auth_param: auth_type
| realm
+ | directory
| clients
| comment
| user_context
@@ -604,7 +607,7 @@ auth_type: TYPE {
};
auth_type_value: BASIC { $$ = ElementPtr(new StringElement("basic", ctx.loc2pos(@1))); }
- ;
+ ;
realm: REALM {
ctx.unique("realm", ctx.loc2pos(@1));
@@ -615,6 +618,15 @@ realm: REALM {
ctx.leave();
};
+directory: DIRECTORY {
+ ctx.unique("directory", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORDS);
+} COLON STRING {
+ ElementPtr directory(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("directory", directory);
+ ctx.leave();
+};
+
clients: CLIENTS {
ctx.unique("clients", ctx.loc2pos(@1));
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
@@ -653,7 +665,9 @@ clients_params: clients_param
;
clients_param: user
+ | user_file
| password
+ | password_file
| user_context
| comment
| unknown_map_entry
@@ -668,6 +682,15 @@ user: USER {
ctx.leave();
};
+user_file: USER_FILE {
+ ctx.unique("user-file", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORDS);
+} COLON STRING {
+ ElementPtr user(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("user-file", user);
+ ctx.leave();
+};
+
password: PASSWORD {
ctx.unique("password", ctx.loc2pos(@1));
ctx.enter(ctx.NO_KEYWORDS);
@@ -677,6 +700,15 @@ password: PASSWORD {
ctx.leave();
};
+password_file: PASSWORD_FILE {
+ ctx.unique("password-file", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORDS);
+} COLON STRING {
+ ElementPtr password(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("password-file", password);
+ ctx.leave();
+};
+
// --- authentication end here -----------------------------------------------------
// --- Loggers starts here -----------------------------------------------------
diff --git a/src/bin/agent/simple_parser.cc b/src/bin/agent/simple_parser.cc
index 47e302d2a0..a5c025c982 100644
--- a/src/bin/agent/simple_parser.cc
+++ b/src/bin/agent/simple_parser.cc
@@ -47,8 +47,9 @@ const SimpleDefaults AgentSimpleParser::AGENT_DEFAULTS = {
/// @brief This table defines default values for authentication.
const SimpleDefaults AgentSimpleParser::AUTH_DEFAULTS = {
- { "type", Element::string, "basic" },
- { "realm", Element::string, "kea-control-agent" }
+ { "type", Element::string, "basic" },
+ { "realm", Element::string, "kea-control-agent" },
+ { "directory", Element::string, "" }
};
/// @brief This table defines default values for control sockets.