Ejemplo n.º 1
0
static int proxy_send_login(struct pop3_client *client, struct ostream *output)
{
	struct dsasl_client_settings sasl_set;
	const unsigned char *sasl_output;
	size_t len;
	const char *mech_name, *error;
	string_t *str = t_str_new(128);

	i_assert(client->common.proxy_ttl > 1);
	if (client->proxy_xclient &&
	    !client->common.proxy_not_trusted) {
		string_t *fwd = t_str_new(128);
                for(const char *const *ptr = client->common.auth_passdb_args;*ptr != NULL; ptr++) {
                        if (strncasecmp(*ptr, "forward_", 8) == 0) {
                                if (str_len(fwd) > 0)
                                        str_append_c(fwd, '\t');
                                str_append_tabescaped(fwd, (*ptr)+8);
                        }
		}

		str_printfa(str, "XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u",
			    net_ip2addr(&client->common.ip),
			    client->common.remote_port,
			    client_get_session_id(&client->common),
			    client->common.proxy_ttl - 1);
		if (str_len(fwd) > 0) {
			str_append(str, " FORWARD=");
			base64_encode(str_data(fwd), str_len(fwd), str);
		}
		str_append(str, "\r\n");
		/* remote supports XCLIENT, send it */
		o_stream_nsend(output, str_data(str), str_len(str));
		client->proxy_state = POP3_PROXY_XCLIENT;
	} else {
		client->proxy_state = POP3_PROXY_LOGIN1;
	}

	str_truncate(str, 0);

	if (client->common.proxy_mech == NULL) {
		/* send USER command */
		str_append(str, "USER ");
		str_append(str, client->common.proxy_user);
		str_append(str, "\r\n");
		o_stream_nsend(output, str_data(str), str_len(str));
		return 0;
	}

	i_assert(client->common.proxy_sasl_client == NULL);
	i_zero(&sasl_set);
	sasl_set.authid = client->common.proxy_master_user != NULL ?
		client->common.proxy_master_user : client->common.proxy_user;
	sasl_set.authzid = client->common.proxy_user;
	sasl_set.password = client->common.proxy_password;
	client->common.proxy_sasl_client =
		dsasl_client_new(client->common.proxy_mech, &sasl_set);
	mech_name = dsasl_client_mech_get_name(client->common.proxy_mech);

	str_printfa(str, "AUTH %s ", mech_name);
	if (dsasl_client_output(client->common.proxy_sasl_client,
				&sasl_output, &len, &error) < 0) {
		client_log_err(&client->common, t_strdup_printf(
			"proxy: SASL mechanism %s init failed: %s",
			mech_name, error));
		return -1;
	}
	if (len == 0)
		str_append_c(str, '=');
	else
		base64_encode(sasl_output, len, str);
	str_append(str, "\r\n");
	o_stream_nsend(output, str_data(str), str_len(str));

	proxy_free_password(&client->common);
	if (client->proxy_state != POP3_PROXY_XCLIENT)
		client->proxy_state = POP3_PROXY_LOGIN2;
	return 0;
}
Ejemplo n.º 2
0
static int proxy_write_login(struct imap_client *client, string_t *str)
{
	struct dsasl_client_settings sasl_set;
	const unsigned char *output;
	unsigned int len;
	const char *mech_name, *error;

	/* Send CAPABILITY command if we don't know the capabilities yet.
	   Also as kind of a Dovecot-backend workaround if the client insisted
	   on sending CAPABILITY command (even though our banner already sent
	   it), send the (unnecessary) CAPABILITY command to backend as well
	   to avoid sending the CAPABILITY reply twice (untagged and OK resp
	   code). */
	if (!client->proxy_capability_request_sent &&
	    (client->proxy_backend_capability == NULL ||
	     client->client_ignores_capability_resp_code)) {
		client->proxy_capability_request_sent = TRUE;
		str_append(str, "C CAPABILITY\r\n");
		if (client->common.proxy_nopipelining) {
			/* authenticate only after receiving C OK reply. */
			return 0;
		}
	}

	if (client->common.proxy_mech == NULL) {
		/* logging in normally - use LOGIN command */
		if (client->proxy_logindisabled &&
		    login_proxy_get_ssl_flags(client->common.login_proxy) == 0) {
			client_log_err(&client->common,
				"proxy: Remote advertised LOGINDISABLED and SSL/TLS not enabled");
			return -1;
		}
		str_append(str, "L LOGIN ");
		imap_append_string(str, client->common.proxy_user);
		str_append_c(str, ' ');
		imap_append_string(str, client->common.proxy_password);
		str_append(str, "\r\n");

		proxy_free_password(&client->common);
		return 0;
	}

	i_assert(client->common.proxy_sasl_client == NULL);
	memset(&sasl_set, 0, sizeof(sasl_set));
	sasl_set.authid = client->common.proxy_master_user != NULL ?
		client->common.proxy_master_user : client->common.proxy_user;
	sasl_set.authzid = client->common.proxy_user;
	sasl_set.password = client->common.proxy_password;
	client->common.proxy_sasl_client =
		dsasl_client_new(client->common.proxy_mech, &sasl_set);
	mech_name = dsasl_client_mech_get_name(client->common.proxy_mech);

	str_append(str, "L AUTHENTICATE ");
	str_append(str, mech_name);
	if (client->proxy_sasl_ir) {
		if (dsasl_client_output(client->common.proxy_sasl_client,
					&output, &len, &error) < 0) {
			client_log_err(&client->common, t_strdup_printf(
				"proxy: SASL mechanism %s init failed: %s",
				mech_name, error));
			return -1;
		}
		str_append_c(str, ' ');
		if (len == 0)
			str_append_c(str, '=');
		else
			base64_encode(output, len, str);
	}
	str_append(str, "\r\n");
	proxy_free_password(&client->common);
	return 0;
}
Ejemplo n.º 3
0
static int proxy_send_login(struct pop3_client *client, struct ostream *output)
{
	struct dsasl_client_settings sasl_set;
	const unsigned char *sasl_output;
	unsigned int len;
	const char *mech_name, *error;
	string_t *str;

	i_assert(client->common.proxy_ttl > 1);
	if (client->proxy_xclient &&
	    !client->common.proxy_not_trusted) {
		/* remote supports XCLIENT, send it */
		o_stream_nsend_str(output, t_strdup_printf(
			"XCLIENT ADDR=%s PORT=%u SESSION=%s TTL=%u\r\n",
			net_ip2addr(&client->common.ip),
			client->common.remote_port,
			client_get_session_id(&client->common),
			client->common.proxy_ttl - 1));
		client->common.proxy_state = POP3_PROXY_XCLIENT;
	} else {
		client->common.proxy_state = POP3_PROXY_LOGIN1;
	}

	str = t_str_new(128);
	if (client->common.proxy_mech == NULL) {
		/* send USER command */
		str_append(str, "USER ");
		str_append(str, client->common.proxy_user);
		str_append(str, "\r\n");
		o_stream_nsend(output, str_data(str), str_len(str));
		return 0;
	}

	i_assert(client->common.proxy_sasl_client == NULL);
	memset(&sasl_set, 0, sizeof(sasl_set));
	sasl_set.authid = client->common.proxy_master_user != NULL ?
		client->common.proxy_master_user : client->common.proxy_user;
	sasl_set.authzid = client->common.proxy_user;
	sasl_set.password = client->common.proxy_password;
	client->common.proxy_sasl_client =
		dsasl_client_new(client->common.proxy_mech, &sasl_set);
	mech_name = dsasl_client_mech_get_name(client->common.proxy_mech);

	str_printfa(str, "AUTH %s ", mech_name);
	if (dsasl_client_output(client->common.proxy_sasl_client,
				&sasl_output, &len, &error) < 0) {
		client_log_err(&client->common, t_strdup_printf(
			"proxy: SASL mechanism %s init failed: %s",
			mech_name, error));
		return -1;
	}
	if (len == 0)
		str_append_c(str, '=');
	else
		base64_encode(sasl_output, len, str);
	str_append(str, "\r\n");
	o_stream_nsend(output, str_data(str), str_len(str));

	proxy_free_password(&client->common);
	if (client->common.proxy_state != POP3_PROXY_XCLIENT)
		client->common.proxy_state = POP3_PROXY_LOGIN2;
	return 0;
}