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 <[email protected]> --- 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 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
