diff --git a/include/HTTPserver.h b/include/HTTPserver.h index cfff42031e..a40ac9c053 100644 --- a/include/HTTPserver.h +++ b/include/HTTPserver.h @@ -59,6 +59,8 @@ class HTTPserver { static bool authorized_localhost_user_login(const struct mg_connection *conn); static void traceLogin(const char *user, bool authorized); + bool authorize_noconn(char *username, char *session_id, u_int session_id_size); + inline char* get_docs_dir() { return(docs_dir); }; inline char* get_scripts_dir() { return(scripts_dir); }; inline bool is_ssl_enabled() { return(ssl_enabled); }; diff --git a/scripts/lua/rest/v1/get/ntopng/session.lua b/scripts/lua/rest/v1/get/ntopng/session.lua new file mode 100644 index 0000000000..2618b7380a --- /dev/null +++ b/scripts/lua/rest/v1/get/ntopng/session.lua @@ -0,0 +1,42 @@ +-- +-- (C) 2013-20 - ntop.org +-- + +local dirs = ntop.getDirs() +package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path +package.path = dirs.installdir .. "/scripts/lua/modules/pools/?.lua;" .. package.path + +require "lua_utils" +local json = require ("dkjson") +local rest_utils = require("rest_utils") + +-- +-- Get a new ntopng user session (Cookie) +-- Example: curl -u admin:admin -d '{"username": "mario"}' http://localhost:3000/lua/rest/v1/get/ntopng/session.lua +-- +-- NOTE: in case of invalid login, no error is returned but redirected to login +-- + +sendHTTPHeader('application/json') + +local rc = rest_utils.consts_ok +local res = {} + +local username = _POST["username"] + +if username == nil then + print(rest_utils.rc(rest_utils.consts_invalid_args)) + return +end + +username = string.lower(username) + +res.session = ntop.createUserSession(username) + +if isEmptyString(res.session) then + print(rest_utils.rc(rest_utils.consts_invalid_args)) + return +end + +print(rest_utils.rc(rc, res)) + diff --git a/src/HTTPserver.cpp b/src/HTTPserver.cpp index a68ed45c23..4dc1dda11f 100644 --- a/src/HTTPserver.cpp +++ b/src/HTTPserver.cpp @@ -750,15 +750,15 @@ static void redirect_to_password_change(struct mg_connection *conn, mg_get_cookie(conn, "session", session_id, sizeof(session_id)); ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] %s(%s)", __FUNCTION__, session_id); - mg_printf(conn, - "HTTP/1.1 302 Found\r\n" - "Set-Cookie: session=%s; path=/;%s\r\n" // Session ID - "Location: %s%s%s%s\r\n\r\n", /* FIX */ - session_id, - get_secure_cookie_attributes(request_info), - ntop->getPrefs()->get_http_prefix(), Utils::getURL((char*)CHANGE_PASSWORD_ULR, buf, sizeof(buf)), - (referer[0] != '\0') ? (char*)"?referer=" : (char*)"", - (referer[0] != '\0') ? (referer_enc = Utils::urlEncode(referer)) : (char*)""); + mg_printf(conn, + "HTTP/1.1 302 Found\r\n" + "Set-Cookie: session=%s; path=/;%s\r\n" // Session ID + "Location: %s%s%s%s\r\n\r\n", /* FIX */ + session_id, + get_secure_cookie_attributes(request_info), + ntop->getPrefs()->get_http_prefix(), Utils::getURL((char*)CHANGE_PASSWORD_ULR, buf, sizeof(buf)), + (referer[0] != '\0') ? (char*)"?referer=" : (char*)"", + (referer[0] != '\0') ? (referer_enc = Utils::urlEncode(referer)) : (char*)""); if(referer_enc) free(referer_enc); @@ -773,7 +773,6 @@ static void authorize(struct mg_connection *conn, char *username, char *group, bool *localuser) { char user[32] = { '\0' }, password[32] = { '\0' }, referer[256] = { '\0' }; - if(!strcmp(request_info->request_method, "POST")) { char post_data[1024]; int post_data_len = mg_read(conn, post_data, sizeof(post_data)); @@ -822,6 +821,30 @@ static void authorize(struct mg_connection *conn, /* ****************************************** */ +// Used to retrieve a session cookie for third-party users via REST API +// Note: there is no connection directly tied to this request (out of bound) +bool HTTPserver::authorize_noconn(char *username, char *session_id, u_int session_id_size) { + char group[NTOP_GROUP_MAXLEN] = { 0 }; + u_int session_duration = 0; + + /* Note: we are not checking the user password as the admin + * or the same (authenticated) user is generating the session */ + if (ntop->existsUserLocal(username)) { + + strncpy(group, NTOP_UNKNOWN_GROUP, NTOP_GROUP_MAXLEN-1); + group[NTOP_GROUP_MAXLEN - 1] = '\0'; + ntop->getUserGroupLocal(username, group); + + create_session(username, group, true, session_id, session_id_size, &session_duration); + + return(true); + } + + return(false); +} + +/* ****************************************** */ + static void uri_encode(const char *src, char *dst, u_int dst_len) { u_int i = 0, j = 0; diff --git a/src/LuaEngineNtop.cpp.inc b/src/LuaEngineNtop.cpp.inc index 81e1bf8c38..b21b307822 100644 --- a/src/LuaEngineNtop.cpp.inc +++ b/src/LuaEngineNtop.cpp.inc @@ -2007,6 +2007,34 @@ static int ntop_clear_user_lifetime(lua_State* vm) { return CONST_LUA_OK; } +/* ******************************************* */ + +static int ntop_create_user_session(lua_State* vm) { + char *username; + char session_id[NTOP_SESSION_ID_LENGTH]; + + session_id[0] = '\0'; + + if(ntop_lua_check(vm, __FUNCTION__, 1, LUA_TSTRING) != CONST_LUA_OK) return(CONST_LUA_PARAM_ERROR); + if((username = (char*)lua_tostring(vm, 1)) == NULL) return(CONST_LUA_PARAM_ERROR); + + if(strlen(username) == 0) + return(CONST_LUA_PARAM_ERROR); + + /* Admin or the same user is allowed to get a session */ + if(!ntop->isUserAdministrator(vm)) { + char *curr_user = getLuaVMUserdata(vm,user); + + if (strcmp(curr_user, username) != 0) + return(CONST_LUA_ERROR); + } + + ntop->get_HTTPserver()->authorize_noconn(username, session_id, sizeof(session_id)); + + lua_pushstring(vm, session_id); + return CONST_LUA_OK; +} + /* ****************************************** */ static int ntop_delete_user(lua_State* vm) { @@ -5587,6 +5615,7 @@ static const luaL_Reg ntop_reg[] = { { "addUserLifetime", ntop_add_user_lifetime }, { "clearUserLifetime", ntop_clear_user_lifetime }, { "deleteUser", ntop_delete_user }, + { "createUserSession", ntop_create_user_session }, { "isLoginDisabled", ntop_is_login_disabled }, { "isLoginBlacklisted", ntop_is_login_blacklisted }, { "getNetworkNameById", ntop_network_name_by_id },