Exemple #1
0
session_t *session_new()
{
  pthread_mutex_lock(&session_mutex);

  while (n_sessions >= MAX_SESSIONS && !purge_oldest_session()) { }

  session_t *session = malloc(sizeof(session_t));
  memset(session, 0, sizeof(session_t));

  session->id = generate_session_id();
  session->refs = 1;

  musicd_log(LOG_DEBUG, "session", "new session %s", session->id);

  if (sessions) {
    session->next = sessions;
    sessions->prev = session;
  }
  sessions = session;

  ++n_sessions;

  pthread_mutex_unlock(&session_mutex);
  return session;
}
/**
 * Creates a Authorization Session.
 */
AAASession* AAACreateAuthSession(void *generic_data,int is_client,int is_statefull,AAASessionCallback_f *cb,void *param)
{
	AAASession *s;
	str id;
	cdp_session_type_t type;
	
	generate_session_id(&id,0);
	
	if (is_client){
		if (is_statefull) type = AUTH_CLIENT_STATEFULL;
		else type = AUTH_CLIENT_STATELESS;
	}else{
		if (is_statefull) type = AUTH_SERVER_STATEFULL;
		else type = AUTH_SERVER_STATELESS;		
	}
	s = new_session(id,type);
	if (s) {
		s->u.auth.generic_data = generic_data;
		s->cb = cb;
		s->cb_param = param;
		s->u.auth.timeout=time(0)+config->tc*30; 
		s->u.auth.lifetime=time(0)+config->tc*32;
		s->u.auth.grace_period=config->tc*2;
		LOG(L_DBG,"id is %.*s",s->id.len,s->id.s);
		LOG(L_DBG,"hash is %u",s->hash);
		add_session(s);
	}
	return s;
}
Exemple #3
0
// Return 1 if request is authorized, 0 otherwise.
int is_authorized(const struct mg_connection *conn,
		const struct mg_request_info *request_info) {
	struct session *session;
	char valid_id[33];
	int authorized = 0;

	// Always authorize accesses to login page and to authorize URI
	if (!strcmp(request_info->uri, login_url)
			|| !strcmp(request_info->uri, authorize_url)
			|| (request_info->query_string
					&& !strncmp(request_info->query_string, authorize_url_q,
							strlen(authorize_url_q)))) {
		return 1;
	}

	pthread_rwlock_rdlock(&rwlock);
	if ((session = get_session(conn)) != NULL) {
		generate_session_id(valid_id, session->random, session->user);
		if (strcmp(valid_id, session->session_id) == 0) {
			session->expire = time(0) + SESSION_TTL;
			authorized = 1;
		}
	}
	pthread_rwlock_unlock(&rwlock);

	return authorized;
}
Exemple #4
0
static void set_cookie(const struct mg_connection *conn,
                       char *user, char *referer) {
  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((struct mg_connection *)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 ? 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);
}
Exemple #5
0
bool Server::is_authorized(const struct mg_connection *conn, struct http_message *hm) {
	Server::session *session;
	char valid_id[33];
	bool authorized = false;

	// Always authorize accesses to login page and to authorize URI
	if (!mg_vcmp(&hm->uri, "/login") ||
		!mg_vcmp(&hm->uri, "/login/") ||
		!mg_vcmp(&hm->uri, "/form.css") ||
		!mg_vcmp(&hm->uri, "/style.css") ||
		!mg_vcmp(&hm->uri, "/logo.png") ||
		!mg_vcmp(&hm->uri, "/users/register.shtml") ||
		!mg_vcmp(&hm->uri, "/api/v1/users/add") ||
		!mg_vcmp(&hm->uri, "/authorize")) {
		return true;
	}

	if ((session = get_session(hm)) != NULL) {
		generate_session_id(valid_id, session->random, session->user);
		if (strcmp(valid_id, session->session_id) == 0) {
			session->expire = time(0) + SESSION_TTL;
			authorized = true;
		}
	}

	return authorized;
}
Exemple #6
0
// 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);
  }
}
Exemple #7
0
// Allocate new session object
Server::session *Server::new_session(const std::string &user) {
	Server::session *session = new Server::session;

	my_strlcpy(session->user, user.c_str(), sizeof(session->user));
	snprintf(session->random, sizeof(session->random), "%d", rand());
	generate_session_id(session->session_id, session->random, session->user);
	session->expire = time(0) + SESSION_TTL;
	session->admin = std::string(user) == m_user;

	sessions[session->session_id] = session;
	return session;
}
/**
 * Creates a Generic Session.
 */
AAASession* AAACreateSession(void *generic_data)
{
	AAASession *s;
	str id;
	
	generate_session_id(&id,0);
	s = new_session(id,UNKNOWN_SESSION);
	if (s) {
		s->u.generic_data = generic_data;
	}
	
	return s;
}
Exemple #9
0
/**
 * Creates a Authorization Session for the Client.
 * It generates a new id and adds the session to the cdp list of sessions
 * \note Returns with a lock on AAASession->hash. Unlock when done working with the result
 * @returns the new AAASession or null on error
 */
AAASession* AAACreateClientAuthSession(int is_statefull,AAASessionCallback_f *cb,void *generic_data)
{
	AAASession *s;
	str id;

	generate_session_id(&id,0);

	s = cdp_new_auth_session(id,1,is_statefull);
	if (s) {
		s->u.auth.generic_data = generic_data;
		s->cb = cb;
		if (s->cb)
			(s->cb)(AUTH_EV_SESSION_CREATED,s);
	}
	return s;
}
Exemple #10
0
/**
 * Creates an Accounting Session (Credit control - RFC 4006) for the client
 * It generates a new id and adds the session to the cdp list of sessions
 * \note Returns with a lock on AAASession->hash. Unlock when done working with the result
 * @returns the new AAASession or null on error
 */
AAASession* AAACreateCCAccSession(AAASessionCallback_f *cb, int is_session, void *generic_data)
{
	AAASession *s;
	str id;

	generate_session_id(&id, 0);

	s = cdp_new_cc_acc_session(id, is_session);
	if (s) {
		if (generic_data) 
			s->u.auth.generic_data = generic_data;
		s->cb = cb;
		if (s->cb)
			(s->cb)(ACC_CC_EV_SESSION_CREATED, s);
	}
	return s;
}
Exemple #11
0
// Return 1 if request is authorized, 0 otherwise.
static struct session * if_authorized(const struct mg_connection *conn,
		const struct mg_request_info *request_info) {
	struct session *session = 0;
	char valid_id[33];
	int authorized = 0;

	pthread_rwlock_rdlock(&rwlock);
	if ((session = get_session(conn)) != NULL) {
		generate_session_id(valid_id, session->random, session->user);
		if (strcmp(valid_id, session->session_id) == 0) {
			session->expire = time(0) + SESSION_TTL;
			authorized = 1;
		}
	}
	pthread_rwlock_unlock(&rwlock);

	return authorized ? session : 0;
}
Exemple #12
0
// A handler for the /authorize endpoint.
// Login page form sends user name and password to this endpoint.
struct session* authorize_ex(struct mg_connection *conn,
		const struct mg_request_info *request_info) {
	char user[MAX_USER_LEN], password[MAX_USER_LEN];
	struct session *session;

	if (session = if_authorized(conn, request_info))
		return 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) {
		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);
		return session;
	}

	return 0;
}
Exemple #13
0
// 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;
	}
}
/*
 * a) Generate new Session ID
 * b) Copies the Session as Set-Cookie into the response header field
 * c) Creates the required structures in the shared memory segment
 *
 * Will set Set-Cookie headers via the apr_table_t *headers_out, which can
 * be r->headers_out or r->err_headers_out.
 */
apr_status_t
create_new_mod_but_session(request_rec *r, apr_table_t *headers_out, int *shmoffset)
{
	apr_status_t rc;
	char *cookie = NULL, *sid = NULL;
	mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module);

	ERRLOG_INFO("Creating new mod_but session");

	sid = generate_session_id(r);
	if (sid == NULL) {
		ERRLOG_CRIT("Failed to generate session ID");
		return STATUS_ERROR;
	}

	/*
	 * Create a new "session" into the shared memory segment
	 */
	cleaning_shm_from_expired_session(r);
	cleaning_shm_history_from_expired_session(r);
	rc = create_new_shm_session(r, sid, shmoffset);
	if (rc != STATUS_OK) {
		ERRLOG_CRIT("Failed to create new SHM session");
		return rc;
	}
	ERRLOG_INFO("Created session at SHM offset [%d]", *shmoffset);

	cookie = build_cookie(r, config, sid);
	if (cookie == NULL) {
		ERRLOG_CRIT("Failed to build cookie");
		return STATUS_ERROR;
	}

	apr_table_setn(headers_out, "Set-Cookie", cookie);
	ERRLOG_INFO("Set-Cookie: [%s]", cookie);
	return STATUS_OK;
}
Exemple #15
0
boost::tuple<shared_data::action, client_info> shared_data::process_user(const std::string& uname,
        const std::string& phash,
        int session_id)
{
    boost::mutex::scoped_lock lock(guard_);
    // XXX Get password from database.
    // if(lookup_username_in_database_fails) {
    //     return boost::make_tuple(user_not_found, it->second);
    // }
    auto it = clients_.find(uname);
    if(session_id == -1) {
        // No session id, check if user name in list already.
        if(it == clients_.end()) {
            // User name not in list. Let's add it.
            auto ret = clients_.insert(std::pair<std::string, client_info>(uname, client_info(generate_session_id(), true, generate_salt())));
            it = ret.first;
        }
    } else {
        if(it == clients_.end()) {
            // user not in list, but we've got a session id. Expire session and generate a new id.
            auto ret = clients_.insert(std::pair<std::string, client_info>(uname, client_info(generate_session_id(), true, generate_salt())));
            it = ret.first;
        } else {
            // We have been sent a session_id, check if it's valid.
            if(it->second.session_id != session_id) {
                it->second.signed_in = false;
                return boost::make_tuple(bad_session_id, it->second);
            }
        }
    }
    if(phash.empty()) {
        return boost::make_tuple(send_salt, it->second);
    } else {
        if(check_password(it->second.salt, fixed_password, phash)) {
            it->second.signed_in = true;
            return boost::make_tuple(login_success, it->second);
        } else {
            it->second.signed_in = false;
            return boost::make_tuple(password_failed, it->second);
        }
    }
}
Exemple #16
0
int shared_data::make_session_id()
{
    return generate_session_id();
}
Exemple #17
0
static LmHandlerResult handle_iq_command_leave_groupchats(LmMessageHandler *h,
                                                          LmConnection *c,
                                                          LmMessage *m,
                                                          gpointer ud)
{
  const char *action, *node;
  char *sessionid;
  LmMessage *iq;
  LmMessageNode *command, *x;

  x = lm_message_node_get_child(m->node, "command");
  if (!x)
    return LM_HANDLER_RESULT_REMOVE_MESSAGE;

  action = lm_message_node_get_attribute(x, "action");
  node = lm_message_node_get_attribute(x, "node");
  sessionid = (char*)lm_message_node_get_attribute(x, "sessionid");

  iq = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
  command = lm_message_node_add_child(iq->node, "command", NULL);
  lm_message_node_set_attributes(command,
                                 "node", node,
                                 "xmlns", NS_COMMANDS,
                                 NULL);

  if (!sessionid) {
    LmMessageNode *field;

    sessionid = generate_session_id("leave-groupchats");
    lm_message_node_set_attribute(command, "sessionid", sessionid);
    g_free(sessionid);
    sessionid = NULL;
    lm_message_node_set_attribute(command, "status", "executing");

    x = lm_message_node_add_child(command, "x", NULL);
    lm_message_node_set_attributes(x,
                                   "type", "form",
                                   "xmlns", "jabber:x:data",
                                   NULL);

    lm_message_node_add_child(x, "title", "Leave groupchat(s)");

    lm_message_node_add_child(x, "instructions",
                              "What groupchats do you want to leave?");

    field = lm_message_node_add_child(x, "field", NULL);
    lm_message_node_set_attributes(field,
                                   "type", "hidden",
                                   "var", "FORM_TYPE",
                                   NULL);

    lm_message_node_add_child(field, "value",
                              "http://jabber.org/protocol/rc");

    field = lm_message_node_add_child(x, "field", NULL);
    lm_message_node_set_attributes(field,
                                   "type", "list-multi",
                                   "var", "groupchats",
                                   "label", "Groupchats: ",
                                   NULL);
    lm_message_node_add_child(field, "required", NULL);

    foreach_buddy(ROSTER_TYPE_ROOM, &_callback_foreach_buddy_groupchat, field);
    // TODO: return an error if we are not connected to groupchats
  } else if (action && !strcmp(action, "cancel")) {
    lm_message_node_set_attribute(command, "status", "canceled");
  } else  { // (if sessionid and not canceled)
    LmMessageNode *form = lm_message_node_find_xmlns(x, "jabber:x:data");// TODO
    if (form) {
      LmMessageNode *field;

      lm_message_node_set_attribute(command, "status", "completed");
      // TODO: implement sth. like "field?var=groupchats" in xmlnode...
      field  = lm_message_node_get_child(form, "field");
      while (field && strcmp("groupchats",
                             lm_message_node_get_attribute(field, "var")))
        field = field->next;

      if (field)
        for (x = field->children ; x ; x = x->next)
        {
          if (!strcmp (x->name, "value")) {
            GList* b = buddy_search_jid(lm_message_node_get_value(x));
            if (b)
              cmd_room_leave(b->data, "Requested by remote command");
          }
        }
      lm_message_node_add_dataform_result(command,
                                          "Groupchats have been left");
    }
  }
  if (sessionid)
    lm_message_node_set_attribute(command, "sessionid", sessionid);
  lm_connection_send(c, iq, NULL);
  lm_message_unref(iq);
  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}
Exemple #18
0
static LmHandlerResult handle_iq_command_set_status(LmMessageHandler *h,
                                                    LmConnection *c,
                                                    LmMessage *m, gpointer ud)
{
  const char *action, *node;
  char *sessionid;
  LmMessage *iq;
  LmMessageNode *command, *x, *y;
  const struct adhoc_status *s;

  x = lm_message_node_get_child(m->node, "command");
  action = lm_message_node_get_attribute(x, "action");
  node = lm_message_node_get_attribute(x, "node");
  sessionid = (char *)lm_message_node_get_attribute(x, "sessionid");

  iq = lm_message_new_iq_from_query(m, LM_MESSAGE_SUB_TYPE_RESULT);
  command = lm_message_node_add_child(iq->node, "command", NULL);
  lm_message_node_set_attribute(command, "node", node);
  lm_message_node_set_attribute(command, "xmlns", NS_COMMANDS);

  if (!sessionid) {
    sessionid = generate_session_id("set-status");
    lm_message_node_set_attribute(command, "sessionid", sessionid);
    g_free(sessionid);
    sessionid = NULL;
    lm_message_node_set_attribute(command, "status", "executing");

    x = lm_message_node_add_child(command, "x", NULL);
    lm_message_node_set_attribute(x, "type", "form");
    lm_message_node_set_attribute(x, "xmlns", "jabber:x:data");

    lm_message_node_add_child(x, "title", "Change Status");

    lm_message_node_add_child(x, "instructions",
                              "Choose the status and status message");

    // TODO see if factorisation is possible
    y = lm_message_node_add_child(x, "field", NULL);
    lm_message_node_set_attribute(y, "type", "hidden");
    lm_message_node_set_attribute(y, "var", "FORM_TYPE");

    lm_message_node_add_child(y, "value", "http://jabber.org/protocol/rc");

    y = lm_message_node_add_child(x, "field", NULL);
    lm_message_node_set_attributes(y,
                                   "type", "list-single",
                                   "var", "status",
                                   "label", "Status",
                                   NULL);
    lm_message_node_add_child(y, "required", NULL);

    // XXX: ugly
    lm_message_node_add_child(y, "value",
                              adhoc_status_list[xmpp_getstatus()].name);
    for (s = adhoc_status_list; s->name; s++) {
        LmMessageNode *option = lm_message_node_add_child(y, "option", NULL);
        lm_message_node_add_child(option, "value", s->name);
        lm_message_node_set_attribute(option, "label", s->description);
    }
    // TODO add priority ?
    // I do not think this is useful, user should not have to care of the
    // priority like gossip and gajim do (misc)
    lm_message_node_set_attributes
            (lm_message_node_add_child(x, "field", NULL),
             "type", "text-multi",
             "var", "status-message",
             "label", "Message",
             NULL);
  } else if (action && !strcmp(action, "cancel")) {
    lm_message_node_set_attribute(command, "status", "canceled");
  } else  { // (if sessionid and not canceled)
    y = lm_message_node_find_xmlns(x, "jabber:x:data"); //x?xmlns=jabber:x:data
    if (y) {
      const char *value=NULL, *message=NULL;
      LmMessageNode *fields, *field;
      field = fields = lm_message_node_get_child(y, "field"); //field?var=status
      while (field && strcmp("status",
                             lm_message_node_get_attribute(field, "var")))
        field = field->next;
      field = lm_message_node_get_child(field, "value");
      if (field)
        value = lm_message_node_get_value(field);
      field = fields; //field?var=status-message
      while (field && strcmp("status-message",
                             lm_message_node_get_attribute(field, "var")))
        field = field->next;
      field = lm_message_node_get_child(field, "value");
      if (field)
        message = lm_message_node_get_value(field);
      if (value) {
        for (s = adhoc_status_list; !s->name || strcmp(s->name, value); s++);
        if (s->name) {
          char *status = g_strdup_printf("%s %s", s->status,
                                         message ? message : "");
          cmd_setstatus(NULL, status);
          g_free(status);
          lm_message_node_set_attribute(command, "status", "completed");
          lm_message_node_add_dataform_result(command,
                                              "Status has been changed");
        }
      }
    }
  }
  if (sessionid)
    lm_message_node_set_attribute(command, "sessionid", sessionid);
  lm_connection_send(c, iq, NULL);
  lm_message_unref(iq);
  return LM_HANDLER_RESULT_REMOVE_MESSAGE;
}