Beispiel #1
0
// Return 1 if request is authorized, 0 otherwise.
static int is_authorized(const struct mg_connection *conn,
                         const struct mg_request_info *request_info) {
  char key[64], user[32];
  char session_id[33], username[33];

  // Always authorize accesses to login page and to authorize URI
  if (!strcmp(request_info->uri, LOGIN_URL) ||
      !strcmp(request_info->uri, AUTHORIZE_URL)) {
    return 1;
  }

  mg_get_cookie(conn, "session", session_id, sizeof(session_id));
  if(session_id[0] == '\0') return(0);

  mg_get_cookie(conn, "user", username, sizeof(username));
  
  // ntop->getTrace()->traceEvent(TRACE_WARNING, "[HTTP] Received session %s/%s", session_id, username);

  snprintf(key, sizeof(key), "sessions.%s", session_id);
  if((ntop->getRedis()->get(key, user, sizeof(user)) < 0)
     || strcmp(user, username) /* Users don't match */) {
    ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Session %s/%s is expired or empty user", 
				 session_id, username);
    return(0);
  } else {
    ntop->getRedis()->expire(key, HTTP_SESSION_DURATION); /* Extend session */
    ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Session %s is OK: extended for %u sec", 
				 session_id, HTTP_SESSION_DURATION);
    return(1);
  }
}
Beispiel #2
0
int CivetServer::getCookie(struct mg_connection *conn, const std::string &cookieName, std::string &cookieValue)
{
	//Maximum cookie length as per microsoft is 4096. http://msdn.microsoft.com/en-us/library/ms178194.aspx
	char _cookieValue[4096];
	const char *cookie = mg_get_header(conn, "Cookie");
	int lRead = mg_get_cookie(cookie, cookieName.c_str(), _cookieValue, sizeof(_cookieValue));
	cookieValue.clear();
	cookieValue.append(_cookieValue);
	return lRead;
}
Beispiel #3
0
int
CookieHandler(struct mg_connection *conn, void *cbdata)
{
	/* Handler may access the request info using mg_get_request_info */
	const struct mg_request_info *req_info = mg_get_request_info(conn);
	const char *cookie = mg_get_header(conn, "Cookie");
	char first_str[64], count_str[64];
	int count;

	(void)mg_get_cookie(cookie, "first", first_str, sizeof(first_str));
	(void)mg_get_cookie(cookie, "count", count_str, sizeof(count_str));

	mg_printf(conn, "HTTP/1.1 200 OK\r\nConnection: close\r\n");
	if (first_str[0] == 0) {
		time_t t = time(0);
		struct tm *ptm = localtime(&t);
		mg_printf(conn,
		          "Set-Cookie: first=%04i-%02i-%02iT%02i:%02i:%02i\r\n",
		          ptm->tm_year + 1900,
		          ptm->tm_mon + 1,
		          ptm->tm_mday,
		          ptm->tm_hour,
		          ptm->tm_min,
		          ptm->tm_sec);
	}
	count = (count_str[0] == 0) ? 0 : atoi(count_str);
	mg_printf(conn, "Set-Cookie: count=%i\r\n", count + 1);
	mg_printf(conn, "Content-Type: text/html\r\n\r\n");

	mg_printf(conn, "<html><body>");
	mg_printf(conn, "<h2>This is the CookieHandler.</h2>");
	mg_printf(conn, "<p>The actual uri is %s</p>", req_info->local_uri);

	if (first_str[0] == 0) {
		mg_printf(conn, "<p>This is the first time, you opened this page</p>");
	} else {
		mg_printf(conn, "<p>You opened this page %i times before.</p>", count);
		mg_printf(conn, "<p>You first opened this page on %s.</p>", first_str);
	}

	mg_printf(conn, "</body></html>\n");
	return 1;
}
Beispiel #4
0
// Return 1 if request is authorized, 0 otherwise.
static int is_authorized(const struct mg_connection *conn,
                         const struct mg_request_info *request_info,
			 char *username, u_int username_len) {
  char session_id[33];

  // Always authorize accesses to login page and to authorize URI
  if(!strcmp(request_info->uri, LOGIN_URL) ||
     !strcmp(request_info->uri, AUTHORIZE_URL)) {
    return 1;
  }

  mg_get_cookie(conn, "user", username, username_len);
  mg_get_cookie(conn, "session", session_id, sizeof(session_id));

  if(session_id[0] == '\0') {
    char password[32];

    /* Last resort: see if we have a user and password matching */
    mg_get_cookie(conn, "password", password, sizeof(password));

    return(ntop->checkUserPassword(username, password));
  }

  // ntop->getTrace()->traceEvent(TRACE_WARNING, "[HTTP] Received session %s/%s", session_id, username);

  if(ntop->getPrefs()->do_auto_logout()) {
    char key[64], user[32];

    snprintf(key, sizeof(key), "sessions.%s", session_id);
    if((ntop->getRedis()->get(key, user, sizeof(user)) < 0)
       || strcmp(user, username) /* Users don't match */) {
      ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Session %s/%s is expired or empty user",
				   session_id, username);
      return(0);
    } else {
      ntop->getRedis()->expire(key, HTTP_SESSION_DURATION); /* Extend session */
      ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Session %s is OK: extended for %u sec",
				   session_id, HTTP_SESSION_DURATION);
      return(1);
    }
  } else
    return(1);
}
Beispiel #5
0
    string Request::getCookie(string key, string fallback)
    {
        string output;
        int i;
        int size = 1024;
        int ret;
        char *buffer = new char[size];
        char dummy[10];
        const char *place = NULL;

        for (i=0; i<connection->num_headers; i++) {
            const struct mg_connection::mg_header *header = &connection->http_headers[i];

            if (strcmp(header->name, "Cookie") == 0) {
                if (mg_get_cookie(header->value, key.c_str(), dummy, sizeof(dummy)) != -1) {
                    place = header->value;
                }
            }
        }

        if (place == NULL) {
            return fallback;
        }

        do {
            ret = mg_get_cookie(place, key.c_str(), buffer, size);

            if (ret == -2) {
                size *= 2;
                delete[] buffer;
                buffer = new char[size];
            }
        } while (ret == -2);

        output = string(buffer);
        delete[] buffer;

        return output;
    }
Beispiel #6
0
// Redirect user to the login form. In the cookie, store the original URL
// we came from, so that after the authorization we could redirect back.
static void redirect_to_login(struct mg_connection *conn,
                              const struct mg_request_info *request_info) {

  char session_id[33];

  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=/; expires=Thu, 01-Jan-1970 00:00:01 GMT; max-age=0; HttpOnly\r\n"  // Session ID
	    "Location: %s%s\r\n\r\n",
	    session_id, ntop->getPrefs()->get_http_prefix(), LOGIN_URL);
}
Beispiel #7
0
static void test_mg_get_cookie(void) {
  char buf[20];

  ASSERT(mg_get_cookie("", "foo", NULL, sizeof(buf)) == -2);
  ASSERT(mg_get_cookie("", "foo", buf, 0) == -2);
  ASSERT(mg_get_cookie("", "foo", buf, sizeof(buf)) == -1);
  ASSERT(mg_get_cookie("", NULL, buf, sizeof(buf)) == -1);
  ASSERT(mg_get_cookie("a=1; b=2; c; d", "a", buf, sizeof(buf)) == 1);
  ASSERT(strcmp(buf, "1") == 0);
  ASSERT(mg_get_cookie("a=1; b=2; c; d", "b", buf, sizeof(buf)) == 1);
  ASSERT(strcmp(buf, "2") == 0);
  ASSERT(mg_get_cookie("a=1; b=123", "b", buf, sizeof(buf)) == 3);
  ASSERT(strcmp(buf, "123") == 0);
  ASSERT(mg_get_cookie("a=1; b=2; c; d", "c", buf, sizeof(buf)) == -1);
}
Beispiel #8
0
// Get session object for the connection. Caller must hold the lock.
static struct session *get_session(const struct mg_connection *conn) {
	int i;
	const char *cookie = mg_get_header(conn, "Cookie");
	char session_id[33];
	time_t now = time(NULL);
	mg_get_cookie(cookie, "session", session_id, sizeof(session_id));
	for (i = 0; i < MAX_SESSIONS; i++) {
		if (sessions[i].expire != 0 && sessions[i].expire > now
				&& strcmp(sessions[i].session_id, session_id) == 0) {
			break;
		}
	}
	return i == MAX_SESSIONS ? NULL : &sessions[i];
}
Beispiel #9
0
    bool Request::hasCookie(string key)
    {
        int i;
        char dummy[10];

        for (i=0; i<connection->num_headers; i++) {
            const struct mg_connection::mg_header *header = &connection->http_headers[i];

            if (strcmp(header->name, "Cookie") == 0) {
                if (mg_get_cookie(header->value, key.c_str(), dummy, sizeof(dummy)) != -1) {
                    return true;
                }
            }
        }

        return false;
    }
Beispiel #10
0
void Ntop::getAllowedNetworks(lua_State* vm) {
  char key[64], val[64];
  char username[33];
  struct mg_connection *conn;

  lua_getglobal(vm, CONST_HTTP_CONN);
  if((conn = (struct mg_connection*)lua_touserdata(vm, lua_gettop(vm))) == NULL) {
    ntop->getTrace()->traceEvent(TRACE_ERROR, "INTERNAL ERROR: null HTTP connection");
    lua_pushstring(vm, (char*)"");
    return;
  }

  mg_get_cookie(conn, CONST_USER, username, sizeof(username));

  snprintf(key, sizeof(key), CONST_STR_USER_NETS, username);
  lua_pushstring(vm, (ntop->getRedis()->get(key, val, sizeof(val)) >= 0) ? val : (char*)"");
}
Beispiel #11
0
// Redirect user to the login form. In the cookie, store the original URL
// we came from, so that after the authorization we could redirect back.
static void redirect_to_login(struct mg_connection *conn,
                              const struct mg_request_info *request_info) {
  char session_id[33], buf[128];

  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"
	    // "HTTP/1.1 401 Unauthorized\r\n"
	    // "WWW-Authenticate: Basic\r\n"
	    "Set-Cookie: session=%s; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT; max-age=0; HttpOnly\r\n"  // Session ID
	    "Location: %s%s?referer=%s%s%s\r\n\r\n",
	    session_id,
	    ntop->getPrefs()->get_http_prefix(), 
	    Utils::getURL((char*)LOGIN_URL, buf, sizeof(buf)),
	    conn->request_info.uri,
	    conn->request_info.query_string ? "%3F" /* ? */: "",
	    conn->request_info.query_string ? conn->request_info.query_string : "");
}
Beispiel #12
0
END_TEST


START_TEST(test_mg_get_cookie)
{
	char buf[32];
	int ret;
	const char *longcookie = "key1=1; key2=2; key3; key4=4; key5=; key6; "
	                         "key7=this+is+it; key8=8; key9";

	/* invalid result buffer */
	ret = mg_get_cookie("", "notfound", NULL, 999);
	ck_assert_int_eq(ret, -2);

	/* zero size result buffer */
	ret = mg_get_cookie("", "notfound", buf, 0);
	ck_assert_int_eq(ret, -2);

	/* too small result buffer */
	ret = mg_get_cookie("key=toooooooooolong", "key", buf, 4);
	ck_assert_int_eq(ret, -3);

	/* key not found in string */
	ret = mg_get_cookie("", "notfound", buf, sizeof(buf));
	ck_assert_int_eq(ret, -1);

	ret = mg_get_cookie(longcookie, "notfound", buf, sizeof(buf));
	ck_assert_int_eq(ret, -1);

	/* key not found in string */
	ret = mg_get_cookie("key1=1; key2=2; key3=3", "notfound", buf, sizeof(buf));
	ck_assert_int_eq(ret, -1);

	/* keys are found as first, middle and last key */
	memset(buf, 77, sizeof(buf));
	ret = mg_get_cookie("key1=1; key2=2; key3=3", "key1", buf, sizeof(buf));
	ck_assert_int_eq(ret, 1);
	ck_assert_str_eq("1", buf);

	memset(buf, 77, sizeof(buf));
	ret = mg_get_cookie("key1=1; key2=2; key3=3", "key2", buf, sizeof(buf));
	ck_assert_int_eq(ret, 1);
	ck_assert_str_eq("2", buf);

	memset(buf, 77, sizeof(buf));
	ret = mg_get_cookie("key1=1; key2=2; key3=3", "key3", buf, sizeof(buf));
	ck_assert_int_eq(ret, 1);
	ck_assert_str_eq("3", buf);

	/* longer value in the middle of a longer string */
	memset(buf, 77, sizeof(buf));
	ret = mg_get_cookie(longcookie, "key7", buf, sizeof(buf));
	ck_assert_int_eq(ret, 10);
	ck_assert_str_eq("this+is+it", buf);

	/* key with = but without value in the middle of a longer string */
	memset(buf, 77, sizeof(buf));
	ret = mg_get_cookie(longcookie, "key5", buf, sizeof(buf));
	ck_assert_int_eq(ret, 0);
	ck_assert_str_eq("", buf);

	/* key without = and without value in the middle of a longer string */
	memset(buf, 77, sizeof(buf));
	ret = mg_get_cookie(longcookie, "key6", buf, sizeof(buf));
	ck_assert_int_eq(ret, -1);
	/* TODO: mg_get_cookie and mg_get_var(2) should have the same behavior */
}
Beispiel #13
0
// Return 1 if request is authorized, 0 otherwise.
static int is_authorized(const struct mg_connection *conn,
                         const struct mg_request_info *request_info,
			 char *username, u_int username_len) {
  char session_id[33], buf[128];
  char key[64], user[32];
  char password[32];
  const char *auth_header_p;
  string auth_type = "", auth_string = "";
  bool user_login_disabled = !ntop->getPrefs()->is_users_login_enabled() ||
    authorized_localhost_users_login_disabled(conn);

  if(user_login_disabled) {
    mg_get_cookie(conn, "user", username, username_len);
    if(strncmp(username, NTOP_NOLOGIN_USER, username_len)) {
      set_cookie(conn, (char *)NTOP_NOLOGIN_USER, NULL);
    }
    return 1;
  }

  // Always authorize accesses to login page and to authorize URI
  if((!strcmp(request_info->uri, LOGIN_URL))
     || (!strcmp(request_info->uri, AUTHORIZE_URL))) {
    return 1;
  }

  if((!strcmp(request_info->uri, Utils::getURL((char*)LOGIN_URL, buf, sizeof(buf))))
     || (!strcmp(request_info->uri, Utils::getURL((char*)AUTHORIZE_URL, buf, sizeof(buf))))) {
    return 1;
  }

  /* Try to decode Authorization header if present */
  auth_header_p = mg_get_header(conn, "Authorization");
  string auth_header = auth_header_p ? auth_header_p  : "";
  istringstream iss(auth_header);
  getline(iss, auth_type, ' ');
  if(auth_type == "Basic") {
    string decoded_auth, user_s = "", pword_s = "";
    /* In case auth type is Basic, info are encoded in base64 */
    getline(iss, auth_string, ' ');
    decoded_auth = Utils::base64_decode(auth_string);
    istringstream authss(decoded_auth);
    getline(authss, user_s, ':');
    getline(authss, pword_s, ':');

    return ntop->checkUserPassword(user_s.c_str(), pword_s.c_str());
  }

  mg_get_cookie(conn, "user", username, username_len);
  mg_get_cookie(conn, "session", session_id, sizeof(session_id));

  if(!strcmp(username, NTOP_NOLOGIN_USER) && !user_login_disabled)
    /* Trying to access web interface with nologin after ntopng restart
       with different settings */
    return 0;

  if(session_id[0] == '\0') {
    /* Last resort: see if we have a user and password matching */
    mg_get_cookie(conn, "password", password, sizeof(password));

    return(ntop->checkUserPassword(username, password));
  }

  // ntop->getTrace()->traceEvent(TRACE_WARNING, "[HTTP] Received session %s/%s", session_id, username);

  snprintf(key, sizeof(key), CONST_RUNTIME_IS_AUTOLOGOUT_ENABLED);
  ntop->getRedis()->get(key, buf, sizeof(buf));
  // do_auto_logout() is the getter for the command-line specified
  // preference that defaults to true (i.e., auto_logout is enabled by default)
  // If do_auto_logout() is disabled, then the runtime auto logout preference
  // is taken into accout.
  // If do_auto_logout() is false, then the auto logout is disabled regardless
  // of runtime preferences.
  if(ntop->getPrefs()->do_auto_logout() && strncmp(buf, (char*)"1", 1) == 0) {
    snprintf(key, sizeof(key), "sessions.%s", session_id);
    if((ntop->getRedis()->get(key, user, sizeof(user)) < 0)
       || strcmp(user, username) /* Users don't match */) {
      ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Session %s/%s is expired or empty user",
				   session_id, username);
      return(0);
    } else {
      ntop->getRedis()->expire(key, HTTP_SESSION_DURATION); /* Extend session */
      ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Session %s is OK: extended for %u sec",
				   session_id, HTTP_SESSION_DURATION);
      return(1);
    }
  } else
    return(1);
}
Beispiel #14
0
int Lua::handle_script_request(struct mg_connection *conn,
			       const struct mg_request_info *request_info, char *script_path) {
  char buf[64], key[64], val[64];

  luaL_openlibs(L); /* Load base libraries */
  lua_register_classes(L, true); /* Load custom classes */

  lua_pushlightuserdata(L, (char*)conn);
  lua_setglobal(L, CONST_HTTP_CONN);

  /* Put the GET params into the environment */
  lua_newtable(L);
  if(request_info->query_string != NULL) {
    char *query_string = strdup(request_info->query_string);

    if(query_string) {
      char *tok, *where;

      tok = strtok_r(query_string, "&", &where);

      while(tok != NULL) {
	/* key=val */
	char *equal = strchr(tok, '=');

	if(equal) {
	  char *decoded_buf;

	  equal[0] = '\0';
	  if((decoded_buf = http_decode(&equal[1])) != NULL) {
	    //ntop->getTrace()->traceEvent(TRACE_WARNING, "'%s'='%s'", tok, decoded_buf);
	    lua_push_str_table_entry(L, tok, decoded_buf);
	    free(decoded_buf);
	  }
	}

	tok = strtok_r(NULL, "&", &where);
      }

      free(query_string);
    }
  }
  lua_setglobal(L, "_GET"); /* Like in php */

  /* Put the _SESSION params into the environment */
  lua_newtable(L);

  mg_get_cookie(conn, "user", buf, sizeof(buf));
  lua_push_str_table_entry(L, "user", buf);
  mg_get_cookie(conn, "session", buf, sizeof(buf));
  lua_push_str_table_entry(L, "session", buf);

  snprintf(key, sizeof(key), "sessions.%s.ifname", buf);
  if(ntop->getRedis()->get(key, val, sizeof(val)) < 0) {
  set_default_if_name_in_session:
    snprintf(val, sizeof(val), "%s", ntop->getInterfaceId(0)->get_name());
    lua_push_str_table_entry(L, "ifname", val);
    ntop->getRedis()->set(key, val, 3600 /* 1h */);
  } else {
    if(ntop->getInterface(val) != NULL) {
      /* The specified interface still exists */
      lua_push_str_table_entry(L, "ifname", val);
      ntop->getRedis()->expire(key, 3600); /* Extend session */
    } else {
      goto set_default_if_name_in_session;
    }
  }

  lua_setglobal(L, "_SESSION"); /* Like in php */

  if(luaL_dofile(L, script_path) != 0) {
    const char *err = lua_tostring(L, -1);

    ntop->getTrace()->traceEvent(TRACE_WARNING, "Script failure [%s][%s]", script_path, err);
    return(send_error(conn, 500 /* Internal server error */, "Internal server error", PAGE_ERROR, script_path, err));
  }

  return(CONST_LUA_OK);
}