コード例 #1
0
ファイル: probe.c プロジェクト: mimicmod/uhub
void probe_destroy(struct hub_probe* probe)
{
	LOG_TRACE("probe_destroy(): %p (connection=%p)", probe, probe->connection);
	if (probe->connection)
	{
		net_con_close(probe->connection);
		probe->connection = 0;
	}
	hub_free(probe);
}
コード例 #2
0
ファイル: mod_topic.c プロジェクト: CoiLock/uhub
static int command_showtopic_handler(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
{
	struct cbuffer* buf = cbuf_create(128);
	char* topic = plugin->hub.get_description(plugin);
	cbuf_append_format(buf, "*** %s: Current topic is: \"%s\"", cmd->prefix, topic);
	plugin->hub.send_message(plugin, user, cbuf_get(buf));
	cbuf_destroy(buf);
	hub_free(topic);
	return 0;
}
コード例 #3
0
ファイル: config.c プロジェクト: CoiLock/uhub
static int apply_string(const char* key, const char* data, char** target, char* regexp)
{
	(void) regexp;
	// FIXME: Add regexp checks for correct data

	if (*target)
		hub_free(*target);

	*target = hub_strdup(data);
	return 1;
}
コード例 #4
0
ファイル: auth.c プロジェクト: CoiLock/uhub
struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name)
{
	struct auth_info* info = 0;
	info = (struct auth_info*) hub_malloc(sizeof(struct auth_info));
	if (plugin_auth_get_user(hub, name, info) != st_allow)
	{
		hub_free(info);
		return NULL;
	}
	return info;
}
コード例 #5
0
ファイル: connection.c プロジェクト: Tilka/uhub
struct net_connect_handle* net_con_connect(const char* address, uint16_t port, net_connect_cb callback, void* ptr)
{
	struct net_connect_handle* handle = hub_malloc_zero(sizeof(struct net_connect_handle));

	handle->address = hub_strdup(address);
	handle->port = port;
	handle->ptr = ptr;
	handle->callback = callback;

	// FIXME: Check if DNS resolving is necessary ?
	handle->dns = net_dns_gethostbyname(address, AF_UNSPEC, net_con_connect_dns_callback, handle);
	if (!handle->dns)
	{
		LOG_TRACE("net_con_connect(): Unable to create DNS lookup job.");
		hub_free((char*) handle->address);
		hub_free(handle);
		return NULL;
	}

	return handle;
}
コード例 #6
0
ファイル: command_parser.c プロジェクト: leejb521/uhub
static void hub_command_args_free(struct hub_command* cmd)
{
	struct hub_command_arg_data* data = NULL;

	if (!cmd->args)
		return;

	LIST_FOREACH(struct hub_command_arg_data*, data, cmd->args,
	{
		switch (data->type)
		{
			case type_string:
				hub_free(data->data.string);
				break;
			case type_range:
				hub_free(data->data.range);
				break;
			default:
				break;
		}
	});
コード例 #7
0
ファイル: notify.c プロジェクト: CoiLock/uhub
void net_notify_destroy(struct uhub_notify_handle* handle)
{
	LOG_TRACE("net_notify_destroy()");
#ifndef WIN32
	net_con_destroy(handle->con);
	close(handle->pipe_fd[0]);
	close(handle->pipe_fd[1]);
	handle->pipe_fd[0] = -1;
	handle->pipe_fd[0] = -1;
#endif
	hub_free(handle);
}
コード例 #8
0
ファイル: adcclient.c プロジェクト: Tilka/uhub
void ADC_client_destroy(struct ADC_client* client)
{
	ADC_TRACE;
	ADC_client_disconnect(client);
	ioq_send_destroy(client->send_queue);
	ioq_recv_destroy(client->recv_queue);
	hub_free(client->timer);
	adc_msg_free(client->info);
	hub_free(client->nick);
	hub_free(client->desc);
	hub_free(client->address.hostname);
	hub_free(client);

	if (g_adc_client && g_adc_client->references > 0)
	{
		g_adc_client->references--;
		if (!g_adc_client->references)
		{
#ifdef SSL_SUPPORT
			net_ssl_context_destroy(g_adc_client->ctx);
			g_adc_client->ctx = NULL;
#endif
			hub_free(g_adc_client);
			g_adc_client = NULL;
		}
	}
}
コード例 #9
0
ファイル: mod_logging_sqlite.c プロジェクト: mimicmod/uhub
static void log_change_nick(struct plugin_handle* plugin, struct plugin_user* user, const char* new_nick)
{
	struct log_data* ldata = (struct log_data*) plugin->ptr;
	const char* addr = ip_convert_to_string(&user->addr);
	char* nick = strdup(sql_escape_string(user->nick));

	int rc = sql_execute(ldata, null_callback, NULL, "INSERT INTO userlog VALUES('', '%s', '%s', '', '', '%s (%s -> %s)', DATETIME('NOW', 'localtime', '%d hours'));", user->cid, addr, "NickChange", nick, new_nick, ldata->srvtdiff);

	if (rc < 0)
		fprintf(stderr, "[SQLITE LOG] Unable to log: NickChange %s/%s %s \"%s\" -> \"%s\"\n", sid_to_string(user->sid), user->cid, addr, user->nick, new_nick);

	hub_free(nick);
}
コード例 #10
0
ファイル: inf.c プロジェクト: leejb521/uhub
/*
 * Set the expected credentials, and returns 1 if authentication is needed,
 * or 0 if not.
 * If the hub is configured to allow only registered users and the user
 * is not recognized this will return 1.
 */
static int set_credentials(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	int ret = 0;
	struct auth_info* info = acl_get_access_info(hub, user->id.nick);

	if (info)
	{
		user->credentials = info->credentials;
		ret = 1;
	}
	else
	{
		user->credentials = auth_cred_guest;
	}
	hub_free(info);

	switch (user->credentials)
	{
		case auth_cred_none:
			break;

		case auth_cred_bot:
			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_BOT);
			break;

		case auth_cred_guest:
			/* Nothing to be added to the info message */
			break;

		case auth_cred_user:
			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_REGISTERED_USER);
			break;

		case auth_cred_operator:
			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_OPERATOR);
			break;

		case auth_cred_super:
			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_SUPER_USER);
			break;

		case auth_cred_admin:
			adc_msg_add_argument(cmd, ADC_INF_FLAG_CLIENT_TYPE ADC_CLIENT_TYPE_ADMIN);
			break;

		case auth_cred_link:
			break;
 	}

	return ret;
}
コード例 #11
0
ファイル: usermanager.c プロジェクト: Nyogtha/uhub
int uman_shutdown(struct hub_info* hub)
{
	if (!hub || !hub->users)
		return -1;

	if (net_backend_get_timeout_queue())
	{
		timeout_queue_remove(net_backend_get_timeout_queue(), hub->users->timeout);
		hub_free(hub->users->timeout);
	}

	if (hub->users->list)
	{
		list_clear(hub->users->list, &clear_user_list_callback);
		list_destroy(hub->users->list);
	}
	sid_pool_destroy(hub->users->sids);
	hub_free(hub->users);
	hub->users = 0;


	return 0;
}
コード例 #12
0
ファイル: hub.c プロジェクト: q3k/uhub
void hub_shutdown_service(struct hub_info* hub)
{
	LOG_DEBUG("hub_shutdown_service()");

#ifdef SSL_SUPPORT
	unload_ssl_certificates(hub);
#endif

	event_queue_shutdown(hub->queue);
	net_con_close(hub->server);
	hub_free(hub->server);
	server_alt_port_stop(hub);
	uman_shutdown(hub);
	hub->status = hub_status_stopped;
	hub_free(hub->sendbuf);
	hub_free(hub->recvbuf);
	hub_chat_history_clear(hub);
	list_destroy(hub->chat_history);
	list_clear(hub->logout_info, &hub_free);
	list_destroy(hub->logout_info);
	hub_free(hub);
	hub = 0;
	g_hub = 0;
}
コード例 #13
0
ファイル: mod_extras.c プロジェクト: mimicmod/uhub
static int command_releaseadd(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
{
	struct extras_data* extrasdata = (struct extras_data*) plugin->ptr;
	struct cbuffer* buf = cbuf_create(128);
	struct plugin_command_arg_data* arg1 = (struct plugin_command_arg_data*) list_get_first(cmd->args);
	struct plugin_command_arg_data* arg2 = (struct plugin_command_arg_data*) list_get_next(cmd->args);

	char* tth = strdup(sql_escape_string(arg1->data.string));
	char* title = strdup(sql_escape_string(arg2->data.string));
  
	int rc = sql_execute(extrasdata, null_callback, NULL, "INSERT INTO releases (id, title, tth) VALUES(NULL, '%s', '%s');", title, tth);
  
	if (rc > 0)
		cbuf_append_format(buf, "*** %s: Added \"%s\" to releases.", cmd->prefix, title);
	else
		cbuf_append_format(buf, "*** %s: Unable to add \"%s\" to releases.", cmd->prefix, title);
  
	plugin->hub.send_message(plugin, user, cbuf_get(buf));
	cbuf_destroy(buf);
	hub_free(tth);
	hub_free(title);

	return 0;
}
コード例 #14
0
ファイル: openssl.c プロジェクト: Tilka/uhub
/**
 * Create a new SSL context.
 */
struct ssl_context_handle* net_ssl_context_create(const char* tls_version, const char* tls_ciphersuite)
{
	struct net_context_openssl* ctx = (struct net_context_openssl*) hub_malloc_zero(sizeof(struct net_context_openssl));
	const SSL_METHOD* ssl_method = get_ssl_method(tls_version);

	if (!ssl_method)
	{
		hub_free(ctx);
		return 0;
	}

	ctx->ssl = SSL_CTX_new(ssl_method);

	/* Disable SSLv2 */
	SSL_CTX_set_options(ctx->ssl, SSL_OP_NO_SSLv2);

	// FIXME: Why did we need this again?
	SSL_CTX_set_quiet_shutdown(ctx->ssl, 1);

#ifdef SSL_OP_NO_COMPRESSION
	/* Disable compression */
	LOG_TRACE("Disabling SSL compression."); /* "CRIME" attack */
	SSL_CTX_set_options(ctx->ssl, SSL_OP_NO_COMPRESSION);
#endif

	/* Set preferred cipher suite */
	if (SSL_CTX_set_cipher_list(ctx->ssl, tls_ciphersuite) != 1)
	{
		LOG_ERROR("Unable to set cipher suite.");
		SSL_CTX_free(ctx->ssl);
		hub_free(ctx);
		return 0;
	}

	return (struct ssl_context_handle*) ctx;
}
コード例 #15
0
ファイル: mod_auth_simple.c プロジェクト: q3k/uhub
static struct acl_data* parse_config(const char* line)
{
	struct acl_data* data = (struct acl_data*) hub_malloc_zero(sizeof(struct acl_data));
	struct cfg_tokens* tokens = cfg_tokenize(line);
	char* token = cfg_token_get_first(tokens);

	if (!data)
		return 0;

	// set defaults
	data->readonly = 1;
	data->exclusive = 0;
	data->users = list_create();

	while (token)
	{
		char* split = strchr(token, '=');
		size_t len = strlen(token);
		size_t key = split ? (split - token) : len;
		if (key == 4 && strncmp(token, "file", 4) == 0)
		{
			if (data->file)
				hub_free(data->file);
			data->file = strdup(split + 1);
		}
		else if (key == 8 && strncmp(token, "readonly", 8) == 0)
		{
			if (!string_to_boolean(split + 1, &data->readonly))
				data->readonly = 1;
		}
		else if (key == 9 && strncmp(token, "exclusive", 9) == 0)
		{
			if (!string_to_boolean(split + 1, &data->exclusive))
				data->exclusive = 1;
		}
		else
		{
			cfg_tokens_free(tokens);
			free_acl(data);
			return 0;
		}

		token = cfg_token_get_next(tokens);
	}

	cfg_tokens_free(tokens);
	return data;
}
コード例 #16
0
ファイル: pluginloader.c プロジェクト: q3k/uhub
struct plugin_handle* plugin_load(const char* filename, const char* config)
{
	plugin_register_f register_f;
	plugin_unregister_f unregister_f;
	int ret;
	struct plugin_handle* handle = hub_malloc_zero(sizeof(struct plugin_handle));
	struct uhub_plugin* plugin = plugin_open(filename);

	if (!plugin)
		return NULL;

	if (!handle)
	{
		plugin_close(plugin);
		return NULL;
	}

	handle->handle = plugin;
	register_f = plugin_lookup_symbol(plugin, "plugin_register");
	unregister_f = plugin_lookup_symbol(plugin, "plugin_unregister");

	if (register_f && unregister_f)
	{
		ret = register_f(handle, config);
		if (ret == 0)
		{
			if (handle->plugin_api_version == PLUGIN_API_VERSION && handle->plugin_funcs_size == sizeof(struct plugin_funcs))
			{
				LOG_INFO("Loaded plugin: %s: %s, version %s.", filename, handle->name, handle->version);
				LOG_TRACE("Plugin API version: %d (func table size: " PRINTF_SIZE_T ")", handle->plugin_api_version, handle->plugin_funcs_size);
				plugin->unregister = unregister_f;
				return handle;
			}
			else
			{
				LOG_ERROR("Unable to load plugin: %s - API version mistmatch", filename);
			}
		}
		else
		{
			LOG_ERROR("Unable to load plugin: %s - Failed to initialize: %s", filename, handle->error_msg);
		}
	}

	plugin_close(plugin);
	hub_free(handle);
	return NULL;
}
コード例 #17
0
ファイル: mod_chat_history.c プロジェクト: junaidk/uhub
/**
 * Add a chat message to history.
 */
static void history_add(struct plugin_handle* plugin, struct plugin_user* from, const char* message, int flags)
{
	size_t loglen = strlen(message) + strlen(from->nick) + 13;
	struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
	char* log = hub_malloc(loglen + 1);

	snprintf(log, loglen, "%s <%s> %s\n", get_timestamp(time(NULL)), from->nick, message);
	log[loglen] = '\0';
	list_append(data->chat_history, log);
	while (list_size(data->chat_history) > data->history_max)
	{
		char* msg = list_get_first(data->chat_history);
		list_remove(data->chat_history, msg);
		hub_free(msg);
	}
}
コード例 #18
0
ファイル: hub.c プロジェクト: q3k/uhub
void hub_plugins_load(struct hub_info* hub)
{
	if (!hub->config->file_plugins || !*hub->config->file_plugins)
		return;

	hub->plugins = hub_malloc_zero(sizeof(struct uhub_plugins));
	if (!hub->plugins)
		return;

	if (plugin_initialize(hub->config, hub->plugins) < 0)
	{
		hub_free(hub->plugins);
		hub->plugins = 0;
		return;
	}
}
コード例 #19
0
ファイル: user.c プロジェクト: junaidk/uhub
void user_destroy(struct hub_user* user)
{
	LOG_TRACE("user_destroy(), user=%p", user);

	ioq_recv_destroy(user->recv_queue);
	ioq_send_destroy(user->send_queue);

	if (user->connection)
	{
		LOG_TRACE("user_destory() -> net_con_close(%p)", user->connection);
		net_con_close(user->connection);
	}

	adc_msg_free(user->info);
	user_clear_feature_cast_support(user);
	hub_free(user);
}
コード例 #20
0
ファイル: hub.c プロジェクト: q3k/uhub
void hub_logout_log(struct hub_info* hub, struct hub_user* user)
{
	struct hub_logout_info* loginfo = hub_malloc_zero(sizeof(struct hub_logout_info));
	if (!loginfo) return;
	loginfo->time = time(NULL);
	strcpy(loginfo->cid, user->id.cid);
	strcpy(loginfo->nick, user->id.nick);
	memcpy(&loginfo->addr, &user->id.addr, sizeof(struct ip_addr_encap));
	loginfo->reason = user->quit_reason;

	list_append(hub->logout_info, loginfo);
	while (list_size(hub->logout_info) > (size_t) hub->config->max_logout_log)
	{
		struct hub_logout_info* entry = list_get_first(hub->logout_info);
		list_remove(hub->logout_info, entry);
		hub_free(entry);
	}
}
コード例 #21
0
/**
 * The callback function for handling the !history command.
 */
static int command_history(struct plugin_handle* plugin, struct plugin_user* user, struct plugin_command* cmd)
{
	struct chat_history_data* data = (struct chat_history_data*) plugin->ptr;
	struct cbuffer* buf = cbuf_create(MAX_HISTORY_SIZE);
	struct linked_list* found = (struct linked_list*) list_create();
	struct plugin_command_arg_data* arg = plugin->hub.command_arg_next(plugin, cmd, plugin_cmd_arg_type_integer);
	int maxlines;

	if (arg)
		maxlines = arg->data.integer;
	else
		maxlines = data->history_default;

	sql_execute(data, get_messages_callback, found, "SELECT from_nick,message, datetime(time, 'localtime') as time FROM chat_history ORDER BY time DESC LIMIT 0,%d;", maxlines);

	size_t linecount = list_size(found);

	if (linecount > 0)
	{
		cbuf_append_format(buf, "*** %s: Chat History:\n\n", cmd->prefix);
		struct chat_history_line* history_line;
		history_line = (struct chat_history_line*) list_get_last(found);
		while (history_line)
		{
			cbuf_append_format(buf, "[%s] <%s> %s\n", history_line->time, history_line->from, history_line->message);
			list_remove(found, history_line);
			hub_free(history_line);
			history_line = (struct chat_history_line*) list_get_last(found);
		}
	}
	else
	{
		cbuf_append_format(buf, "*** %s: No messages found.", cmd->prefix);
	}

	plugin->hub.send_message(plugin, user, cbuf_get(buf));
	cbuf_destroy(buf);
	list_clear(found, &hub_free);
	list_destroy(found);

	return 0;
}
コード例 #22
0
ファイル: notify.c プロジェクト: CoiLock/uhub
struct uhub_notify_handle* net_notify_create(net_notify_callback cb, void* ptr)
{
	LOG_TRACE("net_notify_create()");
	struct uhub_notify_handle* handle = (struct uhub_notify_handle*) hub_malloc(sizeof(struct uhub_notify_handle));
	handle->callback = cb;
	handle->ptr = ptr;
#ifndef WIN32
	int ret = pipe(handle->pipe_fd);
	if (ret == -1)
	{
		LOG_ERROR("Unable to setup notification pipes.");
		hub_free(handle);
		return 0;
	}

	handle->con = net_con_create();
	net_con_initialize(handle->con, handle->pipe_fd[0], notify_callback, handle, NET_EVENT_READ);
#endif
	return handle;
}
コード例 #23
0
ファイル: hub.c プロジェクト: imobilis/uhub
void hub_send_flood_warning(struct hub_info* hub, struct hub_user* u, const char* message)
{
	struct adc_message* msg;
	char* tmp;

	if (user_flag_get(u, flag_flood))
		return;

	msg = adc_msg_construct(ADC_CMD_ISTA, 128);
	if (msg)
	{
		tmp = adc_msg_escape(message);
		adc_msg_add_argument(msg, "110");
		adc_msg_add_argument(msg, tmp);
		hub_free(tmp);

		route_to_user(hub, u, msg);
		user_flag_set(u, flag_flood);
		adc_msg_free(msg);
	}
}
コード例 #24
0
ファイル: hub.c プロジェクト: imobilis/uhub
int hub_handle_password(struct hub_info* hub, struct hub_user* u, struct adc_message* cmd)
{
	char* password = adc_msg_get_argument(cmd, 0);
	int ret = 0;

	if (u->state == state_verify)
	{
		if (acl_password_verify(hub, u, password))
		{
			on_login_success(hub, u);
		}
		else
		{
			on_login_failure(hub, u, status_msg_auth_invalid_password);
			ret = -1;
		}
	}

	hub_free(password);
	return ret;
}
コード例 #25
0
ファイル: auth.c プロジェクト: Nyogtha/uhub
int acl_password_verify(struct hub_info* hub, struct hub_user* user, const char* password)
{
	char buf[1024];
	struct auth_info* access;
	const char* challenge;
	char raw_challenge[64];
	char password_calc[64];
	uint64_t tiger_res[3];
	size_t password_len;

	if (!password || !user || strlen(password) != MAX_CID_LEN)
		return 0;

	access = acl_get_access_info(hub, user->id.nick);
	if (!access)
		return 0;

	challenge = acl_password_generate_challenge(hub, user);

	base32_decode(challenge, (unsigned char*) raw_challenge, MAX_CID_LEN);

	password_len = strlen(access->password);
	
	memcpy(&buf[0], access->password, password_len);
	memcpy(&buf[password_len], raw_challenge, TIGERSIZE);
	
	tiger((uint64_t*) buf, TIGERSIZE+password_len, (uint64_t*) tiger_res);
	base32_encode((unsigned char*) tiger_res, TIGERSIZE, password_calc);
	password_calc[MAX_CID_LEN] = 0;

#ifdef PLUGIN_SUPPORT
	hub_free(access);
#endif

	if (strcasecmp(password, password_calc) == 0)
	{
		return 1;
	}
	return 0;
}
コード例 #26
0
ファイル: sid.c プロジェクト: q3k/uhub
struct sid_pool* sid_pool_create(sid_t max)
{
	struct sid_pool* pool = hub_malloc(sizeof(struct sid_pool));
	if (!pool)
		return 0;

	pool->min = 1;
	pool->max = max + 1;
	pool->count = 0;
	pool->map = hub_malloc_zero(sizeof(struct hub_user*) * pool->max);
	if (!pool->map)
	{
		hub_free(pool);
		return 0;
	}
	pool->map[0] = (struct hub_user*) pool; /* hack to reserve the first sid. */

#ifdef DEBUG_SID
	LOG_DUMP("SID_POOL:  max=%d", (int) pool->max);
#endif
	return pool;
}
コード例 #27
0
ファイル: epoll.c プロジェクト: Nyogtha/uhub
struct net_backend* net_backend_init_epoll(struct net_backend_handler* handler, struct net_backend_common* common)
{
	struct net_backend_epoll* backend;

	if (getenv("EVENT_NOEPOLL"))
		return 0;

	backend = hub_malloc_zero(sizeof(struct net_backend_epoll));
	backend->epfd = epoll_create(common->max);
	if (backend->epfd == -1)
	{
		LOG_WARN("Unable to create epoll socket.");
		hub_free(backend);
		return 0;
	}

	backend->conns = hub_malloc_zero(sizeof(struct net_connection_epoll*) * common->max);
	backend->common = common;

	net_backend_set_handlers(handler);
	return (struct net_backend*) backend;
}
コード例 #28
0
ファイル: auth.c プロジェクト: Nyogtha/uhub
struct auth_info* acl_get_access_info(struct hub_info* hub, const char* name)
{
	struct auth_info* info = 0;
#ifdef PLUGIN_SUPPORT
	info = (struct auth_info*) hub_malloc(sizeof(struct auth_info));
	if (plugin_auth_get_user(hub, name, info) != st_allow)
	{
		hub_free(info);
		return NULL;
	}
	return info;
#else
	info = (struct auth_info*) list_get_first(hub->acl->users);
	while (info)
	{
		if (strcasecmp((char*)info->nickname, name) == 0)
		{
			return info;
		}
		info = (struct auth_info*) list_get_next(hub->acl->users);
	}
	return NULL;
#endif
}
コード例 #29
0
ファイル: pluginloader.c プロジェクト: q3k/uhub
struct uhub_plugin* plugin_open(const char* filename)
{
	LOG_TRACE("plugin_open: \"%s\"", filename);
#ifdef HAVE_DLOPEN
	struct uhub_plugin* plugin = (struct uhub_plugin*) hub_malloc_zero(sizeof(struct uhub_plugin));
	if (!plugin)
	{
		return 0;
	}

	plugin->handle = dlopen(filename, RTLD_LAZY);

	if (!plugin->handle)
	{
		LOG_ERROR("Unable to open plugin %s: %s", filename, dlerror());
		hub_free(plugin);
		return 0;
	}

	return plugin;
#else
	return 0;
#endif
}
コード例 #30
0
ファイル: inf.c プロジェクト: leejb521/uhub
/*
 * FIXME: Only works for tiger hash. If a client doesnt support tiger we cannot let it in!
 */
static int check_cid(struct hub_info* hub, struct hub_user* user, struct adc_message* cmd)
{
	size_t pos;
	char* cid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_CLIENT_ID);
	char* pid = adc_msg_get_named_argument(cmd, ADC_INF_FLAG_PRIVATE_ID);

	if (!cid || !pid)
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_error_no_memory;
	}

	if (strlen(cid) != MAX_CID_LEN)
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_inf_error_cid_invalid;
	}

	if (strlen(pid) != MAX_CID_LEN)
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_inf_error_pid_invalid;
	}

	for (pos = 0; pos < MAX_CID_LEN; pos++)
	{
		if (!is_valid_base32_char(cid[pos]))
		{
			hub_free(cid);
			hub_free(pid);
			return status_msg_inf_error_cid_invalid;
		}

		if (!is_valid_base32_char(pid[pos]))
		{
			hub_free(cid);
			hub_free(pid);
			return status_msg_inf_error_pid_invalid;
		}
	}

	if (!check_hash_tiger(cid, pid))
	{
		hub_free(cid);
		hub_free(pid);
		return status_msg_inf_error_cid_invalid;
	}

	/* Set the cid in the user object */
	memcpy(user->id.cid, cid, MAX_CID_LEN);
	user->id.cid[MAX_CID_LEN] = 0;

	hub_free(cid);
	hub_free(pid);
	return 0;
}