void auth_request_handler_reply(struct auth_request *request,
				enum auth_client_result result,
				const void *auth_reply, size_t reply_size)
{
        struct auth_request_handler *handler = request->handler;
	string_t *str;
	int ret;

	if (handler->destroyed) {
		/* the client connection was already closed. we can't do
		   anything but abort this request */
		request->internal_failure = TRUE;
		result = AUTH_CLIENT_RESULT_FAILURE;
		/* make sure this request is set to finished state
		   (it's not with result=continue) */
		auth_request_set_state(request, AUTH_REQUEST_STATE_FINISHED);
	}

	switch (result) {
	case AUTH_CLIENT_RESULT_CONTINUE:
		str = t_str_new(16 + MAX_BASE64_ENCODED_SIZE(reply_size));
		str_printfa(str, "CONT\t%u\t", request->id);
		base64_encode(auth_reply, reply_size, str);

		request->accept_cont_input = TRUE;
		handler->callback(str_c(str), handler->context);
		break;
	case AUTH_CLIENT_RESULT_SUCCESS:
		if (reply_size > 0) {
			str = t_str_new(MAX_BASE64_ENCODED_SIZE(reply_size));
			base64_encode(auth_reply, reply_size, str);
			auth_fields_add(request->extra_fields, "resp",
					str_c(str), 0);
		}
		ret = auth_request_proxy_finish(request,
				auth_request_handler_proxy_callback);
		if (ret < 0)
			auth_request_handler_reply_failure_finish(request);
		else if (ret > 0)
			auth_request_handler_reply_success_finish(request);
		else
			return;
		break;
	case AUTH_CLIENT_RESULT_FAILURE:
		auth_request_proxy_finish_failure(request);
		auth_request_handler_reply_failure_finish(request);
		break;
	}
	/* NOTE: request may be destroyed now */

        auth_request_handler_unref(&handler);
}
int cmd_login(struct imap_client *imap_client, const struct imap_arg *args)
{
	struct client *client = &imap_client->common;
	const char *user, *pass;
	string_t *plain_login, *base64;

	/* two arguments: username and password */
	if (!imap_arg_get_astring(&args[0], &user) ||
	    !imap_arg_get_astring(&args[1], &pass) ||
	    !IMAP_ARG_IS_EOL(&args[2]))
		return -1;

	if (!client_check_plaintext_auth(client, TRUE))
		return 1;

	/* authorization ID \0 authentication ID \0 pass */
	plain_login = buffer_create_dynamic(pool_datastack_create(), 64);
	buffer_append_c(plain_login, '\0');
	buffer_append(plain_login, user, strlen(user));
	buffer_append_c(plain_login, '\0');
	buffer_append(plain_login, pass, strlen(pass));

	base64 = buffer_create_dynamic(pool_datastack_create(),
        			MAX_BASE64_ENCODED_SIZE(plain_login->used));
	base64_encode(plain_login->data, plain_login->used, base64);
	return imap_client_auth_begin(imap_client, "PLAIN", str_c(base64));
}
Beispiel #3
0
bool cmd_x_state(struct client_command_context *cmd)
{
	/* FIXME: state importing can cause unnecessarily large memory usage
	   by specifying an old modseq, because the EXPUNGE/FETCH replies
	   aren't currently sent asynchronously. so this command is disabled
	   for now. */
#if 0
	const struct imap_arg *args;
	const char *str, *error;
	buffer_t *state, *state_encoded;
	int ret;

	if (!client_read_args(cmd, 0, 0, &args))
		return FALSE;

	state = buffer_create_dynamic(cmd->pool, 256);
	if (imap_arg_get_astring(&args[0], &str)) {
		if (cmd->client->mailbox != NULL) {
			client_send_tagline(cmd,
				"BAD Can't be used in SELECTED state");
			return TRUE;
		}
		if (base64_decode(str, strlen(str), NULL, state) < 0)
			ret = 0;
		else {
			ret = imap_state_import_external(cmd->client,
				state->data, state->used, &error);
		}
		if (ret < 0) {
			client_send_tagline(cmd, t_strdup_printf(
				"NO Failed to restore state: %s", error));
		} else if (ret == 0) {
			client_send_tagline(cmd, t_strdup_printf(
				"BAD Broken state: %s", error));
		} else {
			client_send_tagline(cmd, "OK State imported.");
		}
		return TRUE;
	} else if (args[0].type == IMAP_ARG_EOL) {
		if (!imap_state_export_external(cmd->client, state, &error)) {
			client_send_tagline(cmd, t_strdup_printf(
				"NO Can't save state: %s", error));
			return TRUE;
		}
		state_encoded = buffer_create_dynamic(cmd->pool,
				MAX_BASE64_ENCODED_SIZE(state->used)+10);
		str_append(state_encoded, "* STATE ");
		base64_encode(state->data, state->used, state_encoded);
		client_send_line(cmd->client, str_c(state_encoded));
		client_send_tagline(cmd, "OK State exported.");
		return TRUE;
	} else {
		client_send_command_error(cmd, "Invalid arguments.");
		return TRUE;
	}
#else
	client_send_command_error(cmd, "Command is disabled for now.");
	return TRUE;
#endif
}
Beispiel #4
0
bool password_generate_encoded(const char *plaintext, const struct password_generate_params *params,
			       const char *scheme, const char **password_r)
{
	const struct password_scheme *s;
	const unsigned char *raw_password;
	enum password_encoding encoding;
	string_t *str;
	size_t size;

	s = password_scheme_lookup(scheme, &encoding);
	if (s == NULL)
		return FALSE;

	s->password_generate(plaintext, params, &raw_password, &size);
	switch (encoding) {
	case PW_ENCODING_NONE:
		*password_r = t_strndup(raw_password, size);
		break;
	case PW_ENCODING_BASE64:
		str = t_str_new(MAX_BASE64_ENCODED_SIZE(size) + 1);
		base64_encode(raw_password, size, str);
		*password_r = str_c(str);
		break;
	case PW_ENCODING_HEX:
		*password_r = binary_to_hex(raw_password, size);
		break;
	}
	return TRUE;
}
Beispiel #5
0
static string_t *get_digest_challenge(struct digest_auth_request *request)
{
	const struct auth_settings *set = request->auth_request.set;
	buffer_t buf;
	string_t *str;
	const char *const *tmp;
	unsigned char nonce[16];
	unsigned char nonce_base64[MAX_BASE64_ENCODED_SIZE(sizeof(nonce))+1];
	int i;
	bool first_qop;

	/*
	   realm="hostname" (multiple allowed)
	   nonce="randomized data, at least 64bit"
	   qop="auth,auth-int,auth-conf"
	   maxbuf=number (with auth-int, auth-conf, defaults to 64k)
	   charset="utf-8" (iso-8859-1 if it doesn't exist)
	   algorithm="md5-sess"
	   cipher="3des,des,rc4-40,rc4,rc4-56" (with auth-conf)
	*/

	/* get 128bit of random data as nonce */
	random_fill(nonce, sizeof(nonce));

	buffer_create_from_data(&buf, nonce_base64, sizeof(nonce_base64));
	base64_encode(nonce, sizeof(nonce), &buf);
	buffer_append_c(&buf, '\0');
	request->nonce = p_strdup(request->pool, buf.data);

	str = t_str_new(256);
	if (*set->realms_arr == NULL) {
		/* If no realms are given, at least Cyrus SASL client defaults
		   to destination host name */
		str_append(str, "realm=\"\",");
	} else {
		for (tmp = set->realms_arr; *tmp != NULL; tmp++)
			str_printfa(str, "realm=\"%s\",", *tmp);
	}

	str_printfa(str, "nonce=\"%s\",", request->nonce);

	str_append(str, "qop=\""); first_qop = TRUE;
	for (i = 0; i < QOP_COUNT; i++) {
		if (request->qop & (1 << i)) {
			if (first_qop)
				first_qop = FALSE;
			else
				str_append_c(str, ',');
			str_append(str, qop_names[i]);
		}
	}
	str_append(str, "\",");

	str_append(str, "charset=\"utf-8\","
		   "algorithm=\"md5-sess\"");
	return str;
}
static const char *
mail_storage_service_generate_session_id(pool_t pool, const char *prefix)
{
	guid_128_t guid;
	unsigned int prefix_len = prefix == NULL ? 0 : strlen(prefix);
	string_t *str = str_new(pool, MAX_BASE64_ENCODED_SIZE(prefix_len + 1 + sizeof(guid)));

	if (prefix != NULL)
		str_printfa(str, "%s-", prefix);

	guid_128_generate(guid);
	base64_encode(guid, sizeof(guid), str);
	/* remove the trailing "==" */
	i_assert(str_data(str)[str_len(str)-2] == '=');
	str_truncate(str, str_len(str)-2);
	return str_c(str);

}