diff --git a/AGENTS.md b/AGENTS.md index f848e8c2..383bcd66 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -267,11 +267,17 @@ To enable user authentication, set `authenticate` function for the dashboard des ```c static struct mg_dash s_dash; -static int authenticate(const char *user, const char *pass) { +// Signature: (char *user, size_t userlen, const char *pass) +// `user` is both input (username from the login form) and output: the function +// may overwrite it with the canonical username. Return access level > 0 on +// success, 0 on failure. +static int authenticate(char *user, size_t userlen, const char *pass) { int level = 0; // Authentication failure - if (strcmp(pass, "admin") == 0 && strcmp(user, "admin") == 0) { + if (strcmp(pass, "admin") == 0) { + mg_snprintf(user, userlen, "%s", "admin"); level = 7; // Administrator - } else if (strcmp(pass, "user") == 0 && strcmp(user, "user") == 0) { + } else if (strcmp(pass, "user") == 0) { + mg_snprintf(user, userlen, "%s", "user"); level = 3; // Ordinary dude } return level; diff --git a/mongoose.c b/mongoose.c index b84c2ae0..4f653bf6 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1013,7 +1013,7 @@ static struct mg_dash_user *mg_dash_authenticate(struct mg_http_message *hm, struct mg_str *ah = mg_http_get_header(hm, "Authorization"); if (ah != NULL) { // Auth header and password are set, auth by user/password via glue API - int num_users = 0, level = dash->authenticate(user, pass); + int num_users = 0, level = dash->authenticate(user, sizeof(user), pass); MG_DEBUG(("user %s, level: %d", user, level)); if (level > 0) { // Proceed only if the firmware authenticated us for (u = s_users; u != NULL && result == NULL; diff --git a/mongoose.h b/mongoose.h index cf56f0e1..e72f68a0 100644 --- a/mongoose.h +++ b/mongoose.h @@ -3318,7 +3318,7 @@ struct mg_dash_file { struct mg_dash { struct mg_field_set *sets; struct mg_dash_custom_handler *custom_handlers; - int (*authenticate)(const char *user, const char *pass); + int (*authenticate)(char *user, size_t userlen, const char *pass); int session_auto_expiration_seconds; //struct mg_dash_file *files; }; diff --git a/src/dash.c b/src/dash.c index 2fe44207..51f90965 100644 --- a/src/dash.c +++ b/src/dash.c @@ -354,7 +354,7 @@ static struct mg_dash_user *mg_dash_authenticate(struct mg_http_message *hm, struct mg_str *ah = mg_http_get_header(hm, "Authorization"); if (ah != NULL) { // Auth header and password are set, auth by user/password via glue API - int num_users = 0, level = dash->authenticate(user, pass); + int num_users = 0, level = dash->authenticate(user, sizeof(user), pass); MG_DEBUG(("user %s, level: %d", user, level)); if (level > 0) { // Proceed only if the firmware authenticated us for (u = s_users; u != NULL && result == NULL; diff --git a/src/dash.h b/src/dash.h index e92a1290..004f2659 100644 --- a/src/dash.h +++ b/src/dash.h @@ -48,7 +48,7 @@ struct mg_dash_file { struct mg_dash { struct mg_field_set *sets; struct mg_dash_custom_handler *custom_handlers; - int (*authenticate)(const char *user, const char *pass); + int (*authenticate)(char *user, size_t userlen, const char *pass); int session_auto_expiration_seconds; //struct mg_dash_file *files; }; diff --git a/test/unit_test.c b/test/unit_test.c index 1af00d2a..4bd7db1a 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -4190,14 +4190,14 @@ static void dash_custom(struct mg_connection *c, int ev, void *ev_data) { (void) c, (void) ev, (void) ev_data; } -static int dash_authenticate(const char *user, const char *pass) { +static int dash_authenticate(char *user, size_t userlen, const char *pass) { int level = 0; if (strcmp(pass, "admin") == 0) { level = 7; } else if (strcmp(pass, "user") == 0) { level = 3; } - (void) user; + (void) user, (void) userlen; return level; } diff --git a/tutorials/device-dashboard/full/dashboard.c b/tutorials/device-dashboard/full/dashboard.c index b39bbdc5..6e11a861 100644 --- a/tutorials/device-dashboard/full/dashboard.c +++ b/tutorials/device-dashboard/full/dashboard.c @@ -4,7 +4,7 @@ #include "mongoose.h" static struct mg_dash s_dash; -static int authenticate(const char *user, const char *pass); +static int authenticate(char *user, size_t userlen, const char *pass); // Action buttons static bool s_action1, s_action2; @@ -176,14 +176,15 @@ static struct mg_field_set set_graph2 = { "graph2", fields_graph2, read_graph2, NULL, 0, 0, NULL, }; -static int authenticate(const char *user, const char *pass) { +static int authenticate(char *user, size_t userlen, const char *pass) { int level = 0; // Authentication failure if (strcmp(pass, "admin") == 0) { + mg_snprintf(user, userlen, "%s", "admin"); level = 7; // Administrator } else if (strcmp(pass, "user") == 0) { + mg_snprintf(user, userlen, "%s", "user"); level = 3; // Ordinary dude } - (void) user; return level; }