// A handler for the /authorize endpoint. // Login page form sends user name and password to this endpoint. static void authorize(struct mg_connection *conn, const struct mg_request_info *request_info) { char user[32], password[32], referer[256]; if(!strcmp(request_info->request_method, "POST")) { char post_data[1024]; int post_data_len = mg_read(conn, post_data, sizeof(post_data)); mg_get_var(post_data, post_data_len, "user", user, sizeof(user)); mg_get_var(post_data, post_data_len, "password", password, sizeof(password)); mg_get_var(post_data, post_data_len, "referer", referer, sizeof(referer)); } else { // Fetch user name and password. get_qsvar(request_info, "user", user, sizeof(user)); get_qsvar(request_info, "password", password, sizeof(password)); get_qsvar(request_info, "ref", referer, sizeof(referer)); } /* Referer url must begin with '/' */ if((referer[0] != '/') || (strcmp(referer, AUTHORIZE_URL) == 0)) strcpy(referer, "/"); if(ntop->checkUserPassword(user, password)) { set_cookie(conn, user, referer); } else { // Authentication failure, redirect to login. redirect_to_login(conn, request_info); } }
// A handler for the /authorize endpoint. // Login page form sends user name and password to this endpoint. static void authorize(struct mg_connection *conn, const struct mg_request_info *request_info) { char user[32], password[32], referer[256]; if(!strcmp(request_info->request_method, "POST")) { char post_data[1024]; int post_data_len = mg_read(conn, post_data, sizeof(post_data)); mg_get_var(post_data, post_data_len, "user", user, sizeof(user)); mg_get_var(post_data, post_data_len, "password", password, sizeof(password)); mg_get_var(post_data, post_data_len, "referer", referer, sizeof(referer)); } else { // Fetch user name and password. get_qsvar(request_info, "user", user, sizeof(user)); get_qsvar(request_info, "password", password, sizeof(password)); get_qsvar(request_info, "ref", referer, sizeof(referer)); } /* Referer url must begin with '/' */ if((referer[0] != '/') || (strcmp(referer, AUTHORIZE_URL) == 0)) strcpy(referer, "/"); if(ntop->checkUserPassword(user, password)) { char key[256], session_id[64], random[64]; // Authentication success: // 1. create new session // 2. set session ID token in the cookie // // The most secure way is to stay HTTPS all the time. However, just to // show the technique, we redirect to HTTP after the successful // authentication. The danger of doing this is that session cookie can // be stolen and an attacker may impersonate the user. // Secure application must use HTTPS all the time. snprintf(random, sizeof(random), "%d", rand()); generate_session_id(session_id, random, user); // ntop->getTrace()->traceEvent(TRACE_ERROR, "==> %s\t%s", random, session_id); /* http://en.wikipedia.org/wiki/HTTP_cookie */ mg_printf(conn, "HTTP/1.1 302 Found\r\n" "Set-Cookie: session=%s; path=/; max-age=%u; HttpOnly\r\n" // Session ID "Set-Cookie: user=%s; path=/; max-age=%u; HttpOnly\r\n" // Set user, needed by Javascript code "Location: %s%s\r\n\r\n", session_id, HTTP_SESSION_DURATION, user, HTTP_SESSION_DURATION, ntop->getPrefs()->get_http_prefix(), referer); /* Save session in redis */ snprintf(key, sizeof(key), "sessions.%s", session_id); ntop->getRedis()->set(key, user, HTTP_SESSION_DURATION); ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Set session sessions.%s", session_id); } else { // Authentication failure, redirect to login. redirect_to_login(conn, request_info); } }
static int begin_request_handler(struct mg_connection *conn) { const struct mg_request_info *request_info = mg_get_request_info(conn); int processed = 1; if (!request_info->is_ssl) { redirect_to_ssl(conn, request_info); } else if (!is_authorized(conn, request_info)) { redirect_to_login(conn, request_info); } else if (strcmp(request_info->uri, authorize_url) == 0) { authorize(conn, request_info); } else if (strcmp(request_info->uri, "/ajax/get_messages") == 0) { ajax_get_messages(conn, request_info); } else if (strcmp(request_info->uri, "/ajax/send_message") == 0) { ajax_send_message(conn, request_info); } else { // No suitable handler found, mark as not processed. Civetweb will // try to serve the request. processed = 0; } return processed; }
// A handler for the /authorize endpoint. // Login page form sends user name and password to this endpoint. int authorize(struct mg_connection *conn, const struct mg_request_info *request_info) { char user[MAX_USER_LEN], password[MAX_USER_LEN]; struct session *session; // Fetch user name and password. get_qsvar(request_info, "user", user, sizeof(user)); get_qsvar(request_info, "password", password, sizeof(password)); if (check_password(user, password) && (session = new_session()) != NULL) { // Authentication success: // 1. create new session // 2. set session ID token in the cookie // 3. remove original_url from the cookie - not needed anymore // 4. redirect client back to the original URL // // The most secure way is to stay HTTPS all the time. However, just to // show the technique, we redirect to HTTP after the successful // authentication. The danger of doing this is that session cookie can // be stolen and an attacker may impersonate the user. // Secure application must use HTTPS all the time. my_strlcpy(session->user, user, sizeof(session->user)); snprintf(session->random, sizeof(session->random), "%d", rand()); generate_session_id(session->session_id, session->random, session->user); mg_printf(conn, "HTTP/1.1 302 Found\r\n" "Set-Cookie: session=%s; max-age=3600; http-only\r\n" // Session ID "Set-Cookie: user=%s\r\n"// Set user, needed by Javascript code "Set-Cookie: original_url=/; max-age=0\r\n"// Delete original_url "Location: /\r\n\r\n", session->session_id, session->user); return 1; } else { // Authentication failure, redirect to login. redirect_to_login(conn, request_info); return 0; } }
static int handle_lua_request(struct mg_connection *conn) { struct mg_request_info *request_info = mg_get_request_info(conn); u_int len = (u_int)strlen(request_info->uri); char username[33] = { 0 }; if((ntop->getGlobals()->isShutdown()) //|| (strcmp(request_info->request_method, "GET")) || (ntop->getRedis() == NULL /* Starting up... */)) return(send_error(conn, 403 /* Forbidden */, request_info->uri, "Unexpected HTTP method or ntopng still starting up...")); if(ntop->get_HTTPserver()->is_ssl_enabled() && (!request_info->is_ssl)) redirect_to_ssl(conn, request_info); if(enable_users_login) { if((len > 4) && ((strcmp(&request_info->uri[len-4], ".css") == 0) || (strcmp(&request_info->uri[len-3], ".js")) == 0)) ; else if(!is_authorized(conn, request_info, username)) { redirect_to_login(conn, request_info); return(1); } else if(strcmp(request_info->uri, AUTHORIZE_URL) == 0) { authorize(conn, request_info); return(1); } } ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] %s", request_info->uri); if(strstr(request_info->uri, "//") || strstr(request_info->uri, "&&") || strstr(request_info->uri, "??") || strstr(request_info->uri, "..")) { ntop->getTrace()->traceEvent(TRACE_WARNING, "[HTTP] The URL %s is invalid/dangerous", request_info->uri); return(send_error(conn, 400 /* Bad Request */, request_info->uri, "The URL specified contains invalid/dangerous characters")); } if((strncmp(request_info->uri, "/lua/", 5) == 0) || (strcmp(request_info->uri, "/") == 0)) { /* Lua Script */ char path[255] = { 0 }, uri[2048]; struct stat buf; snprintf(path, sizeof(path), "%s%s", httpserver->get_scripts_dir(), (strlen(request_info->uri) == 1) ? "/lua/index.lua" : request_info->uri); ntop->fixPath(path); if((stat(path, &buf) == 0) && (S_ISREG (buf.st_mode))) { Lua *l = new Lua(); ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] %s [%s]", request_info->uri, path); if(l == NULL) { ntop->getTrace()->traceEvent(TRACE_ERROR, "[HTTP] Unable to start Lua interpreter"); return(send_error(conn, 500 /* Internal server error */, "Internal server error", "%s", "Unable to start Lua interpreter")); } else { l->handle_script_request(conn, request_info, path); delete l; return(1); /* Handled */ } } uri_encode(request_info->uri, uri, sizeof(uri)-1); return(send_error(conn, 404, "Not Found", PAGE_NOT_FOUND, uri)); } else { ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Serving file %s%s", ntop->get_HTTPserver()->get_docs_dir(), request_info->uri); return(0); /* This is a static document so let mongoose handle it */ } }