[PATCH] rpcd: implement certificate authentication
Luka Logar
luka.logar at cifra.si
Fri Feb 19 15:01:51 EST 2021
When the TLS client certificate is used for LuCI authentication, ubus session login is called with
username = subject name
password = certificate hash
mode = 'cert'
Extra parameter 'mode' is needed to differentiate a regular username/password login attempt from the client
certificate auth. Otherwise one could fake the certificate login using the standard username/password
method entering subject name as username and cert hash as password, both of which are public/known/not-secret.
Session login is successful if the password/certificate hash matches the one stored in the /etc/config/rpcd
file.
Signed-off-by: Luka Logar <luka.logar at cifra.si>
---
session.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/session.c b/session.c
index 908e298..b577475 100644
--- a/session.c
+++ b/session.c
@@ -120,12 +120,14 @@ enum {
RPC_L_USERNAME,
RPC_L_PASSWORD,
RPC_L_TIMEOUT,
+ RPC_L_MODE,
__RPC_L_MAX,
};
static const struct blobmsg_policy login_policy[__RPC_L_MAX] = {
[RPC_L_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING },
[RPC_L_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING },
[RPC_L_TIMEOUT] = { .name = "timeout", .type = BLOBMSG_TYPE_INT32 },
+ [RPC_L_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
};
/*
@@ -827,7 +829,7 @@ rpc_login_test_password(const char *hash, const char *password)
static struct uci_section *
rpc_login_test_login(struct uci_context *uci,
- const char *username, const char *password)
+ const char *username, const char *password, const char *mode)
{
struct uci_package *p = NULL;
struct uci_section *s;
@@ -877,6 +879,13 @@ rpc_login_test_login(struct uci_context *uci,
if (ptr.o->type != UCI_TYPE_STRING)
continue;
+ if (mode && !strcmp(mode, "cert"))
+ {
+ if (!strcasecmp(ptr.o->v.string, password))
+ return ptr.s;
+ continue;
+ }
+
if (rpc_login_test_password(ptr.o->v.string, password))
return ptr.s;
}
@@ -1137,7 +1146,8 @@ rpc_handle_login(struct ubus_context *ctx, struct ubus_object *obj,
}
login = rpc_login_test_login(uci, blobmsg_get_string(tb[RPC_L_USERNAME]),
- blobmsg_get_string(tb[RPC_L_PASSWORD]));
+ blobmsg_get_string(tb[RPC_L_PASSWORD]),
+ blobmsg_get_string(tb[RPC_L_MODE]));
if (!login) {
rv = UBUS_STATUS_PERMISSION_DENIED;
@@ -1296,7 +1306,7 @@ rpc_session_from_blob(struct uci_context *uci, struct blob_attr *attr)
}
if (uci && user) {
- login = rpc_login_test_login(uci, user, NULL);
+ login = rpc_login_test_login(uci, user, NULL, NULL);
if (login)
rpc_login_setup_acls(ses, login);
}
--
2.25.1
More information about the openwrt-devel
mailing list