コード例 #1
0
ファイル: submission-client.c プロジェクト: bdraco/core
static void client_proxy_create(struct client *client,
				const struct submission_settings *set)
{
	struct mail_user *user = client->user;
	struct ssl_iostream_settings ssl_set;
	struct smtp_client_settings smtp_set;
	enum smtp_client_connection_ssl_mode ssl_mode;

	i_zero(&ssl_set);
	mail_user_init_ssl_client_settings(user, &ssl_set);
	if (set->submission_relay_ssl_verify)
		ssl_set.verbose_invalid_cert = TRUE;
	else
		ssl_set.allow_invalid_cert = TRUE;

	/* make proxy connection */
	i_zero(&smtp_set);
	smtp_set.my_hostname = set->hostname;
	smtp_set.ssl = &ssl_set;
	smtp_set.debug = user->mail_debug;
	smtp_set.rawlog_dir =
		mail_user_home_expand(user,
				      set->submission_relay_rawlog_dir);

	if (set->submission_relay_trusted) {
		smtp_set.peer_trusted = TRUE;

		if (user->conn.remote_ip != NULL) {
			smtp_set.proxy_data.source_ip =
				*user->conn.remote_ip;
			smtp_set.proxy_data.source_port =
				user->conn.remote_port;
		}
		smtp_set.proxy_data.login = user->username;
	}

	smtp_set.username = set->submission_relay_user;
	smtp_set.master_user = set->submission_relay_master_user;
	smtp_set.password = set->submission_relay_password;
	smtp_set.connect_timeout_msecs =
		set->submission_relay_connect_timeout;
	smtp_set.command_timeout_msecs =
		set->submission_relay_command_timeout;

	if (strcmp(set->submission_relay_ssl, "smtps") == 0)
		ssl_mode = SMTP_CLIENT_SSL_MODE_IMMEDIATE;
	else if (strcmp(set->submission_relay_ssl, "starttls") == 0)
		ssl_mode = SMTP_CLIENT_SSL_MODE_STARTTLS;
	else
		ssl_mode = SMTP_CLIENT_SSL_MODE_NONE;

	client->proxy_conn = smtp_client_connection_create(smtp_client,
		SMTP_PROTOCOL_SMTP, set->submission_relay_host,
		set->submission_relay_port, ssl_mode, &smtp_set);
	smtp_client_connection_connect(client->proxy_conn,
		client_proxy_ready_cb, client);
}
コード例 #2
0
void FV3_(firwindow)::Kaiser(fv3_float_t w[], const long N, fv3_float_t beta)
{
  long i;
  const fv3_float_t M = N-1;
  fv3_float_t inv_izbeta = 1.0 / i_zero(M_PI*beta);
  for(i = 0;i < N;i ++)
    {
      w[i] = i_zero(M_PI*beta*sqrt(1-pow(2*(fv3_float_t)i/M-1, 2)))
	* inv_izbeta;
    }
}
コード例 #3
0
ファイル: sdbox-storage.c プロジェクト: zatsepin/core
static void sdbox_update_header(struct sdbox_mailbox *mbox,
				struct mail_index_transaction *trans,
				const struct mailbox_update *update)
{
	struct sdbox_index_header hdr, new_hdr;
	bool need_resize;

	if (sdbox_read_header(mbox, &hdr, TRUE, &need_resize) < 0) {
		i_zero(&hdr);
		need_resize = TRUE;
	}

	new_hdr = hdr;

	if (update != NULL && !guid_128_is_empty(update->mailbox_guid)) {
		memcpy(new_hdr.mailbox_guid, update->mailbox_guid,
		       sizeof(new_hdr.mailbox_guid));
	} else if (guid_128_is_empty(new_hdr.mailbox_guid)) {
		guid_128_generate(new_hdr.mailbox_guid);
	}

	if (need_resize) {
		mail_index_ext_resize_hdr(trans, mbox->hdr_ext_id,
					  sizeof(new_hdr));
	}
	if (memcmp(&hdr, &new_hdr, sizeof(hdr)) != 0) {
		mail_index_update_header_ext(trans, mbox->hdr_ext_id, 0,
					     &new_hdr, sizeof(new_hdr));
	}
	memcpy(mbox->mailbox_guid, new_hdr.mailbox_guid,
	       sizeof(mbox->mailbox_guid));
}
コード例 #4
0
ファイル: stats-metrics.c プロジェクト: bdraco/core
static void
stats_metric_settings_to_query(const struct stats_metric_settings *set,
			       struct event_filter_query *query_r)
{
	i_zero(query_r);

	/* generate fields for event filter */
	if (array_is_created(&set->filter)) {
		struct event_filter_field *filter_fields;
		const char *const *filters;
		unsigned int i, count;

		filters = array_get(&set->filter, &count);
		i_assert(count % 2 == 0);
		count /= 2;

		filter_fields = t_new(struct event_filter_field, count + 1);
		for (i = 0; i < count; i++) {
			filter_fields[i].key = filters[i*2];
			filter_fields[i].value = filters[i*2+1];
		}
		query_r->fields = filter_fields;
	}

	/* add query to the event filter */
	query_r->categories = t_strsplit_spaces(set->categories, " ");
	query_r->name = set->event_name;
	query_r->source_filename = t_strcut(set->source_location, ':');
	query_r->source_linenum = set->parsed_source_linenum;
}
コード例 #5
0
ファイル: http-parser.c プロジェクト: zatsepin/core
void http_parser_init(struct http_parser *parser,
			const unsigned char *data, size_t size)
{
	i_zero(parser);
	parser->begin = data;
	parser->cur = data;
	parser->end = data + size;
}
コード例 #6
0
ファイル: imap-metadata.c プロジェクト: zatsepin/core
int imap_metadata_unset(struct imap_metadata_transaction *imtrans,
			const char *entry)
{
	struct mail_attribute_value value;

	i_zero(&value);
	return imap_metadata_set(imtrans, entry, &value);
}
コード例 #7
0
ファイル: doveadm-print-formatted.c プロジェクト: bdraco/core
static void doveadm_print_formatted_init(void)
{
	i_zero(&ctx);
	ctx.pool = pool_alloconly_create("doveadm formatted print", 1024);
	ctx.buf = str_new(ctx.pool, 256);
	p_array_init(&ctx.headers, ctx.pool, 8);
	ctx.idx = 0;
}
コード例 #8
0
ファイル: index-sort.c プロジェクト: bdraco/core
void index_sort_list_finish(struct mail_search_sort_program *program)
{
	i_zero(&static_node_cmp_context);
	static_node_cmp_context.program = program;
	static_node_cmp_context.reverse =
		(program->sort_program[0] & MAIL_SORT_FLAG_REVERSE) != 0;

	program->sort_list_finish(program);
}
コード例 #9
0
ファイル: doveadm-print-formatted.c プロジェクト: bdraco/core
static void
doveadm_print_formatted_header(const struct doveadm_print_header *hdr)
{
	struct var_expand_table entry;
	i_zero(&entry);
	entry.key = '\0';
	entry.long_key = p_strdup(ctx.pool, hdr->key);
	entry.value = NULL;
	array_append(&ctx.headers, &entry, 1);
}
コード例 #10
0
ファイル: imap-metadata.c プロジェクト: zatsepin/core
int imap_metadata_get_stream(struct imap_metadata_transaction *imtrans,
		      const char *entry, struct mail_attribute_value *value_r)
{
	enum mail_attribute_type type;
	const char *key;

	i_zero(value_r);
	if (!imap_metadata_entry2key(imtrans, entry, &type, &key))
		return 0;
	return mailbox_attribute_get_stream(imtrans->box, type, key, value_r);
}
コード例 #11
0
ファイル: smtp-server-command.c プロジェクト: bdraco/core
void smtp_server_command_register(struct smtp_server *server,
	const char *name, smtp_server_cmd_start_func_t *func,
	enum smtp_server_command_flags flags)
{
	struct smtp_server_command_reg cmd;

	i_zero(&cmd);
	cmd.name = name;
	cmd.func = func;
	cmd.flags = flags;
	array_append(&server->commands_reg, &cmd, 1);

	server->commands_unsorted = TRUE;
}
コード例 #12
0
ファイル: imap-status.c プロジェクト: bdraco/core
int imap_status_parse_items(struct client_command_context *cmd,
			    const struct imap_arg *args,
			    struct imap_status_items *items_r)
{
	const char *item;
	enum mailbox_status_items status = 0;
	enum mailbox_metadata_items metadata = 0;

	if (IMAP_ARG_IS_EOL(args)) {
		client_send_command_error(cmd, "Empty status list.");
		return -1;
	}

	i_zero(items_r);
	for (; !IMAP_ARG_IS_EOL(args); args++) {
		if (!imap_arg_get_atom(args, &item)) {
			/* list may contain only atoms */
			client_send_command_error(cmd,
				"Status list contains non-atoms.");
			return -1;
		}

		item = t_str_ucase(item);
		if (strcmp(item, "MESSAGES") == 0)
			status |= STATUS_MESSAGES;
		else if (strcmp(item, "RECENT") == 0)
			status |= STATUS_RECENT;
		else if (strcmp(item, "UIDNEXT") == 0)
			status |= STATUS_UIDNEXT;
		else if (strcmp(item, "UIDVALIDITY") == 0)
			status |= STATUS_UIDVALIDITY;
		else if (strcmp(item, "UNSEEN") == 0)
			status |= STATUS_UNSEEN;
		else if (strcmp(item, "HIGHESTMODSEQ") == 0)
			status |= STATUS_HIGHESTMODSEQ;
		else if (strcmp(item, "X-SIZE") == 0)
			metadata |= MAILBOX_METADATA_VIRTUAL_SIZE;
		else if (strcmp(item, "X-GUID") == 0)
			metadata |= MAILBOX_METADATA_GUID;
		else {
			client_send_command_error(cmd, t_strconcat(
				"Invalid status item ", item, NULL));
			return -1;
		}
	}

	items_r->status = status;
	items_r->metadata = metadata;
	return 0;
}
コード例 #13
0
ファイル: main.c プロジェクト: bdraco/core
static void main_preinit(void)
{
	struct module_dir_load_settings mod_set;

	i_zero(&mod_set);
	mod_set.abi_version = DOVECOT_ABI_VERSION;
	mod_set.require_init_funcs = TRUE;

	modules = module_dir_load(STATS_MODULE_DIR, NULL, &mod_set);
	module_dir_init(modules);

	restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
	restrict_access_allow_coredumps(TRUE);
}
コード例 #14
0
ファイル: master-connection.c プロジェクト: bdraco/core
static int
master_connection_input_line(struct master_connection *conn, const char *line)
{
	const char *const *args = t_strsplit_tabescaped(line);
	struct mail_storage_service_input input;
	struct mail_storage_service_user *service_user;
	struct mail_user *user;
	const char *str, *error;
	unsigned int max_recent_msgs;
	int ret;

	/* <username> <mailbox> <session ID> <max_recent_msgs> [i][o] */
	if (str_array_length(args) != 5 ||
	    str_to_uint(args[3], &max_recent_msgs) < 0 || args[4][0] == '\0') {
		i_error("Invalid input from master: %s", line);
		return -1;
	}

	i_zero(&input);
	input.module = "mail";
	input.service = "indexer-worker";
	input.username = args[0];
	/* if session-id is given, use it as a prefix to a unique session ID.
	   we can't use the session-id directly or stats process will complain
	   about duplicates. (especially LMTP would use the same session-id for
	   multiple users' indexing at the same time.) */
	if (args[2][0] != '\0')
		input.session_id_prefix = args[2];

	if (mail_storage_service_lookup_next(conn->storage_service, &input,
					     &service_user, &user, &error) <= 0) {
		i_error("User %s lookup failed: %s", args[0], error);
		ret = -1;
	} else {
		indexer_worker_refresh_proctitle(user->username, args[1], 0, 0);
		ret = index_mailbox(conn, user, args[1],
				    max_recent_msgs, args[4]);
		/* refresh proctitle before a potentially long-running
		   user unref */
		indexer_worker_refresh_proctitle(user->username, "(deinit)", 0, 0);
		mail_user_unref(&user);
		mail_storage_service_user_unref(&service_user);
		indexer_worker_refresh_proctitle(NULL, NULL, 0, 0);
	}

	str = ret < 0 ? "-1\n" : "100\n";
	return write_full(conn->fd, str, strlen(str));
}
コード例 #15
0
ファイル: login-proxy-state.c プロジェクト: bdraco/core
struct login_proxy_record *
login_proxy_state_get(struct login_proxy_state *state,
		      const struct ip_addr *ip, in_port_t port)
{
	struct login_proxy_record *rec, key;

	i_zero(&key);
	key.ip = *ip;
	key.port = port;

	rec = hash_table_lookup(state->hash, &key);
	if (rec == NULL) {
		rec = p_new(state->pool, struct login_proxy_record, 1);
		rec->ip = *ip;
		rec->port = port;
		hash_table_insert(state->hash, rec, rec);
	}
コード例 #16
0
ファイル: submission-client.c プロジェクト: bdraco/core
static void client_init_urlauth(struct client *client)
{
	static const char *access_apps[] = { "submit+", NULL };
	struct imap_urlauth_config config;

	i_zero(&config);
	config.url_host = client->set->imap_urlauth_host;
	config.url_port = client->set->imap_urlauth_port;
	config.socket_path = t_strconcat(client->user->set->base_dir,
					 "/"IMAP_URLAUTH_SOCKET_NAME, NULL);
	config.session_id = client->session_id;
	config.access_anonymous = client->user->anonymous;
	config.access_user = client->user->username;
	config.access_service = "submission";
	config.access_applications = access_apps;

	client->urlauth_ctx = imap_urlauth_init(client->user, &config);
}
コード例 #17
0
ファイル: dsync-mailbox-tree-fill.c プロジェクト: bdraco/core
static int
dsync_mailbox_tree_fix_guid_duplicate(struct dsync_mailbox_tree *tree,
				      struct dsync_mailbox_node *node1,
				      struct dsync_mailbox_node *node2)
{
	struct mailbox *box;
	struct mailbox_update update;
	struct dsync_mailbox_node *change_node;
	const char *change_vname;
	int ret = 0;

	i_zero(&update);
	guid_128_generate(update.mailbox_guid);

	/* just in case the duplication exists in both sides,
	   make them choose the same node */
	if (strcmp(dsync_mailbox_node_get_full_name(tree, node1),
		   dsync_mailbox_node_get_full_name(tree, node2)) <= 0)
		change_node = node1;
	else
		change_node = node2;

	change_vname = dsync_mailbox_node_get_full_name(tree, change_node);
	i_error("Duplicate mailbox GUID %s for mailboxes %s and %s - "
		"giving a new GUID %s to %s",
		guid_128_to_string(node1->mailbox_guid),
		dsync_mailbox_node_get_full_name(tree, node1),
		dsync_mailbox_node_get_full_name(tree, node2),
		guid_128_to_string(update.mailbox_guid), change_vname);

	i_assert(node1->ns != NULL && node2->ns != NULL);
	box = mailbox_alloc(change_node->ns->list, change_vname, 0);
	if (mailbox_update(box, &update) < 0) {
		i_error("Couldn't update mailbox %s GUID: %s",
			change_vname, mailbox_get_last_internal_error(box, NULL));
		ret = -1;
	} else {
		memcpy(change_node->mailbox_guid, update.mailbox_guid,
		       sizeof(change_node->mailbox_guid));
	}
	mailbox_free(&box);
	return ret;
}
コード例 #18
0
ファイル: fs-test-async.c プロジェクト: bdraco/core
void test_fs_async(const char *test_name, enum fs_properties properties,
		   const char *driver, const char *args)
{
	struct fs_settings fs_set;
	struct fs *fs;
	struct test_fs *test_fs;
	const char *error;

	i_zero(&fs_set);
	if (fs_init(driver, args, &fs_set, &fs, &error) < 0)
		i_fatal("fs_init() failed: %s", error);

	test_fs = test_fs_get(fs);
	test_fs->properties = properties;

	test_fs_async_write(test_name, fs);
	test_fs_async_copy(test_name, fs);

	fs_deinit(&fs);
}
コード例 #19
0
ファイル: indexer-worker.c プロジェクト: bdraco/core
static void drop_privileges(void)
{
	struct restrict_access_settings set;
	const char *error;

	/* by default we don't drop any privileges, but keep running as root. */
	restrict_access_get_env(&set);
	if (set.uid != 0) {
		/* open config connection before dropping privileges */
		struct master_service_settings_input input;
		struct master_service_settings_output output;

		i_zero(&input);
		input.module = "mail";
		input.service = "indexer-worker";
		(void)master_service_settings_read(master_service,
						   &input, &output, &error);
	}
	restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
}
コード例 #20
0
static int
auth_server_input_mech(struct auth_server_connection *conn,
		       const char *const *args)
{
	struct auth_mech_desc mech_desc;

	if (conn->handshake_received) {
		i_error("BUG: Authentication server already sent handshake");
		return -1;
	}
	if (args[0] == NULL) {
		i_error("BUG: Authentication server sent broken MECH line");
		return -1;
	}

	i_zero(&mech_desc);
	mech_desc.name = p_strdup(conn->pool, args[0]);

	if (strcmp(mech_desc.name, "PLAIN") == 0)
		conn->has_plain_mech = TRUE;

	for (args++; *args != NULL; args++) {
		if (strcmp(*args, "private") == 0)
			mech_desc.flags |= MECH_SEC_PRIVATE;
		else if (strcmp(*args, "anonymous") == 0)
			mech_desc.flags |= MECH_SEC_ANONYMOUS;
		else if (strcmp(*args, "plaintext") == 0)
			mech_desc.flags |= MECH_SEC_PLAINTEXT;
		else if (strcmp(*args, "dictionary") == 0)
			mech_desc.flags |= MECH_SEC_DICTIONARY;
		else if (strcmp(*args, "active") == 0)
			mech_desc.flags |= MECH_SEC_ACTIVE;
		else if (strcmp(*args, "forward-secrecy") == 0)
			mech_desc.flags |= MECH_SEC_FORWARD_SECRECY;
		else if (strcmp(*args, "mutual-auth") == 0)
			mech_desc.flags |= MECH_SEC_MUTUAL_AUTH;
	}
	array_append(&conn->available_auth_mechs, &mech_desc, 1);
	return 0;
}
コード例 #21
0
ファイル: sdbox-storage.c プロジェクト: zatsepin/core
int sdbox_read_header(struct sdbox_mailbox *mbox,
		      struct sdbox_index_header *hdr, bool log_error,
		      bool *need_resize_r)
{
	struct mail_index_view *view;
	const void *data;
	size_t data_size;
	int ret = 0;

	i_assert(mbox->box.opened);

	view = mail_index_view_open(mbox->box.index);
	mail_index_get_header_ext(view, mbox->hdr_ext_id,
				  &data, &data_size);
	if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE &&
	    (!mbox->box.creating || data_size != 0)) {
		if (log_error) {
			mailbox_set_critical(&mbox->box,
				"sdbox: Invalid dbox header size");
		}
		ret = -1;
	} else {
		i_zero(hdr);
		memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr)));
		if (guid_128_is_empty(hdr->mailbox_guid))
			ret = -1;
		else {
			/* data is valid. remember it in case mailbox
			   is being reset */
			mail_index_set_ext_init_data(mbox->box.index,
						     mbox->hdr_ext_id,
						     hdr, sizeof(*hdr));
		}
	}
	mail_index_view_close(&view);
	*need_resize_r = data_size < sizeof(*hdr);
	return ret;
}
コード例 #22
0
ファイル: dcrypt-gnutls.c プロジェクト: bdraco/core
static
int dcrypt_gnutls_pbkdf2(const unsigned char *password, size_t password_len, const unsigned char *salt, size_t salt_len, const char *algorithm,
	unsigned int rounds, buffer_t *result, unsigned int result_len, const char **error_r)
{
	unsigned char buf[result_len];
	/* only sha1 or sha256 is supported */
	if (strncasecmp(algorithm, "sha1", 4) == 0) {
		pbkdf2_hmac_sha1(password_len, password, rounds, salt_len, salt, result_len, buf);
	} else if (strncasecmp(algorithm, "sha256", 6) == 0) {
		pbkdf2_hmac_sha256(password_len, password, rounds, salt_len, salt, result_len, buf);
	} else if (strncasecmp(algorithm, "sha512", 6) == 0) {
		struct hmac_sha512_ctx ctx;
		hmac_sha512_set_key(&ctx, password_len, password);
		PBKDF2(&ctx, hmac_sha512_update, hmac_sha512_digest, 64, rounds, salt_len, salt, result_len, buf);
		i_zero(&ctx);
	} else {
		*error_r = "Unsupported algorithm";
		return -1;
	}
	buffer_append(result, buf, result_len);
	memset(buf, 0, sizeof(buf));
	return 0;
}
コード例 #23
0
ファイル: message-part-serialize.c プロジェクト: bdraco/core
struct message_part *
message_part_deserialize(pool_t pool, const void *data, size_t size,
			 const char **error_r)
{
	struct deserialize_context ctx;
        struct message_part *part;

	i_zero(&ctx);
	ctx.pool = pool;
	ctx.data = data;
	ctx.end = ctx.data + size;

	if (!message_part_deserialize_part(&ctx, NULL, 1, &part)) {
		*error_r = ctx.error;
		return NULL;
	}

	if (ctx.data != ctx.end) {
		*error_r = "Too much data";
		return NULL;
	}

	return part;
}
コード例 #24
0
ファイル: imap-master-client.c プロジェクト: bdraco/core
static int
imap_master_client_parse_input(const char *const *args, pool_t pool,
			       struct mail_storage_service_input *input_r,
			       struct imap_master_input *master_input_r,
			       const char **error_r)
{
	const char *key, *value;
	unsigned int peer_dev_major = 0, peer_dev_minor = 0;

	i_zero(input_r);
	i_zero(master_input_r);
	master_input_r->client_input = buffer_create_dynamic(pool, 64);
	master_input_r->client_output = buffer_create_dynamic(pool, 16);
	master_input_r->state = buffer_create_dynamic(pool, 512);

	input_r->module = input_r->service = "imap";
	/* we never want to do userdb lookup again when restoring the client.
	   we have the userdb_fields cached already. */
	input_r->flags_override_remove = MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;

	if (args[0] == NULL) {
		*error_r = "Missing username in input";
		return -1;
	}
	input_r->username = args[0];

	for (args++; *args != NULL; args++) {
		value = strchr(*args, '=');
		if (value != NULL)
			key = t_strdup_until(*args, value++);
		else {
			key = *args;
			value = "";
		}
		if (strcmp(key, "lip") == 0) {
			if (net_addr2ip(value, &input_r->local_ip) < 0) {
				*error_r = t_strdup_printf(
					"Invalid lip value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "rip") == 0) {
			if (net_addr2ip(value, &input_r->remote_ip) < 0) {
				*error_r = t_strdup_printf(
					"Invalid rip value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "peer_dev_major") == 0) {
			if (str_to_uint(value, &peer_dev_major) < 0) {
				*error_r = t_strdup_printf(
					"Invalid peer_dev_major value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "peer_dev_minor") == 0) {
			if (str_to_uint(value, &peer_dev_minor) < 0) {
				*error_r = t_strdup_printf(
					"Invalid peer_dev_minor value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "peer_ino") == 0) {
			if (str_to_ino(value, &master_input_r->peer_ino) < 0) {
				*error_r = t_strdup_printf(
					"Invalid peer_ino value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "session") == 0) {
			input_r->session_id = value;
		} else if (strcmp(key, "session_created") == 0) {
			if (str_to_time(value, &input_r->session_create_time) < 0) {
				*error_r = t_strdup_printf(
					"Invalid session_created value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "userdb_fields") == 0) {
			input_r->userdb_fields =
				t_strsplit_tabescaped(value);
		} else if (strcmp(key, "client_input") == 0) {
			if (base64_decode(value, strlen(value), NULL,
					  master_input_r->client_input) < 0) {
				*error_r = t_strdup_printf(
					"Invalid client_input base64 value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "client_output") == 0) {
			if (base64_decode(value, strlen(value), NULL,
					  master_input_r->client_output) < 0) {
				*error_r = t_strdup_printf(
					"Invalid client_output base64 value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "state") == 0) {
			if (base64_decode(value, strlen(value), NULL,
					  master_input_r->state) < 0) {
				*error_r = t_strdup_printf(
					"Invalid state base64 value: %s", value);
				return -1;
			}
		} else if (strcmp(key, "tag") == 0) {
			master_input_r->tag = t_strdup(value);
		} else if (strcmp(key, "bad-done") == 0) {
			master_input_r->state_import_bad_idle_done = TRUE;
		} else if (strcmp(key, "idle-continue") == 0) {
			master_input_r->state_import_idle_continue = TRUE;
		}
	}
	if (peer_dev_major != 0 || peer_dev_minor != 0) {
		master_input_r->peer_dev =
			makedev(peer_dev_major, peer_dev_minor);
	}
	return 0;
}
コード例 #25
0
ファイル: submission-client.c プロジェクト: bdraco/core
static void client_state_reset(struct client *client)
{
	i_stream_unref(&client->state.data_input);

	i_zero(&client->state);
}
コード例 #26
0
ファイル: submission-client.c プロジェクト: bdraco/core
struct client *client_create(int fd_in, int fd_out,
			     const char *session_id, struct mail_user *user,
			     struct mail_storage_service_user *service_user,
			     const struct submission_settings *set,
			     const char *helo,
			     const unsigned char *pdata, unsigned int pdata_len)
{
	const struct mail_storage_settings *mail_set;
	struct smtp_server_settings smtp_set;
	const char *ident;
	struct client *client;

	/* always use nonblocking I/O */
	net_set_nonblock(fd_in, TRUE);
	net_set_nonblock(fd_out, TRUE);

	client = i_new(struct client, 1);
	client->user = user;
	client->service_user = service_user;
	client->set = set;
	client->session_id = i_strdup(session_id);

	i_zero(&smtp_set);
	smtp_set.hostname = set->hostname;
	smtp_set.login_greeting = set->login_greeting;
	smtp_set.max_recipients = set->submission_max_recipients;
	smtp_set.max_client_idle_time_msecs = CLIENT_IDLE_TIMEOUT_MSECS;
	smtp_set.debug = user->mail_debug;

	client->conn = smtp_server_connection_create(smtp_server,
		fd_in, fd_out, user->conn.remote_ip, user->conn.remote_port,
		FALSE, &smtp_set, &smtp_callbacks, client);

	client_proxy_create(client, set);

	smtp_server_connection_login(client->conn,
		client->user->username, helo,
		pdata, pdata_len, user->conn.ssl_secured);
	smtp_server_connection_start_pending(client->conn);

	mail_set = mail_user_set_get_storage_set(user);
	if (*set->imap_urlauth_host != '\0' &&
	    *mail_set->mail_attribute_dict != '\0') {
		/* Enable BURL capability only when urlauth dict is
		   configured correctly */
		client_init_urlauth(client);
	}

	submission_client_count++;
	DLLIST_PREPEND(&submission_clients, client);

	ident = mail_user_get_anvil_userip_ident(client->user);
	if (ident != NULL) {
		master_service_anvil_send(master_service, t_strconcat(
			"CONNECT\t", my_pid, "\tsubmission/",
			ident, "\n", NULL));
		client->anvil_sent = TRUE;
	}

	if (hook_client_created != NULL)
		hook_client_created(&client);

	submission_refresh_proctitle();
	return client;
}
コード例 #27
0
ファイル: master-service-haproxy.c プロジェクト: bdraco/core
static int
master_service_haproxy_read(struct master_service_haproxy_conn *hpconn)
{
	/* reasonable max size for haproxy data */
	unsigned char rbuf[1500];
	const char *error;
	static union {
		unsigned char v1_data[HAPROXY_V1_MAX_HEADER_SIZE];
		struct {
			const struct haproxy_header_v2 hdr;
			const struct haproxy_data_v2 data;
		} v2;
	} buf;
	struct ip_addr *real_remote_ip = &hpconn->conn.remote_ip;
	int fd = hpconn->conn.fd;
	struct ip_addr local_ip, remote_ip;
	in_port_t local_port, remote_port;
	size_t size,i,want;
	ssize_t ret;
	enum haproxy_version_t version;

	/* the protocol specification explicitly states that the protocol header
	   must be sent as one TCP frame, meaning that we will get it in full
	   with the first recv() call.
	 */
	i_zero(&buf);
	i_zero(rbuf);

	/* see if there is a HAPROXY protocol command waiting */
	if ((ret = master_service_haproxy_recv(fd, &buf, sizeof(buf), MSG_PEEK))<=0) {
		if (ret < 0)
			i_info("haproxy: Client disconnected (rip=%s): %m",
			       net_ip2addr(real_remote_ip));
		return ret;
	/* see if there is a haproxy command, 8 is used later on as well */
	} else if (ret >= 8 && memcmp(buf.v1_data, "PROXY", 5) == 0) {
		/* fine */
		version = HAPROXY_VERSION_1;
	} else if ((size_t)ret >= sizeof(buf.v2.hdr) &&
		   memcmp(buf.v2.hdr.sig, haproxy_v2sig, sizeof(haproxy_v2sig)) == 0) {
		want = ntohs(buf.v2.hdr.len) + sizeof(buf.v2.hdr);
		if (want > sizeof(rbuf)) {
			i_error("haproxy: Client disconnected: Too long header (rip=%s)",
				net_ip2addr(real_remote_ip));
			return -1;
		}

		if ((ret = master_service_haproxy_recv(fd, rbuf, want, MSG_WAITALL))<=0) {
			if (ret < 0)
				i_info("haproxy: Client disconnected (rip=%s): %m",
				       net_ip2addr(real_remote_ip));
			return ret;
		}

		if (ret != (ssize_t)want) {
			i_info("haproxy: Client disconnected: Failed to read full header (rip=%s)",
				net_ip2addr(real_remote_ip));
			return -1;
		}
		memcpy(&buf, rbuf, sizeof(buf));
		version = HAPROXY_VERSION_2;
	} else {
		/* it wasn't haproxy data */
		i_error("haproxy: Client disconnected: "
			"Failed to read valid HAproxy data (rip=%s)",
			net_ip2addr(real_remote_ip));
		return -1;
	}

	/* don't update true connection data until we succeed */
	local_ip = hpconn->conn.local_ip;
	remote_ip = hpconn->conn.remote_ip;
	local_port = hpconn->conn.local_port;
	remote_port = hpconn->conn.remote_port;

	/* protocol version 2 */
	if (version == HAPROXY_VERSION_2) {
		const struct haproxy_header_v2 *hdr = &buf.v2.hdr;
		const struct haproxy_data_v2 *data = &buf.v2.data;
		size_t hdr_len;

		i_assert(ret >= (ssize_t)sizeof(buf.v2.hdr));

		if ((hdr->ver_cmd & 0xf0) != 0x20) {
			i_error("haproxy: Client disconnected: "
				"Unsupported protocol version (version=%02x, rip=%s)",
				(hdr->ver_cmd & 0xf0) >> 4,
				net_ip2addr(real_remote_ip));
			return -1;
		}

		hdr_len = ntohs(hdr->len);
		size = sizeof(*hdr) + hdr_len;
		/* keep tab of how much address data there really is because
		   because TLVs begin after that. */
		i = 0;

		if (ret < (ssize_t)size) {
			i_error("haproxy(v2): Client disconnected: "
				"Protocol payload length does not match header "
				"(got=%"PRIuSIZE_T", expect=%"PRIuSIZE_T", rip=%s)",
				(size_t)ret, size, net_ip2addr(real_remote_ip));
			return -1;
		}

		i += sizeof(*hdr);

		switch (hdr->ver_cmd & 0x0f) {
		case HAPROXY_CMD_LOCAL:
			/* keep local connection address for LOCAL */
			/*i_debug("haproxy(v2): Local connection (rip=%s)",
				net_ip2addr(real_remote_ip));*/
			break;
		case HAPROXY_CMD_PROXY:
			if ((hdr->fam & 0x0f) != HAPROXY_SOCK_STREAM) {
				/* UDP makes no sense currently */
				i_error("haproxy(v2): Client disconnected: "
					"Not using TCP (type=%02x, rip=%s)",
					(hdr->fam & 0x0f), net_ip2addr(real_remote_ip));
				return -1;
			}
			switch ((hdr->fam & 0xf0) >> 4) {
			case HAPROXY_AF_INET:
				/* IPv4 */
				if (hdr_len < sizeof(data->addr.ip4)) {
					i_error("haproxy(v2): Client disconnected: "
						"IPv4 data is incomplete (rip=%s)",
						net_ip2addr(real_remote_ip));
					return -1;
				}
				local_ip.family = AF_INET;
				local_ip.u.ip4.s_addr = data->addr.ip4.dst_addr;
				local_port = ntohs(data->addr.ip4.dst_port);
				remote_ip.family = AF_INET;
				remote_ip.u.ip4.s_addr = data->addr.ip4.src_addr;
				remote_port = ntohs(data->addr.ip4.src_port);
				i += sizeof(data->addr.ip4);
				break;
			case HAPROXY_AF_INET6:
				/* IPv6 */
				if (hdr_len < sizeof(data->addr.ip6)) {
					i_error("haproxy(v2): Client disconnected: "
						"IPv6 data is incomplete (rip=%s)",
						net_ip2addr(real_remote_ip));
					return -1;
				}
				local_ip.family = AF_INET6;
				memcpy(&local_ip.u.ip6.s6_addr, data->addr.ip6.dst_addr, 16);
				local_port = ntohs(data->addr.ip6.dst_port);
				remote_ip.family = AF_INET6;
				memcpy(&remote_ip.u.ip6.s6_addr, data->addr.ip6.src_addr, 16);
				remote_port = ntohs(data->addr.ip6.src_port);
				i += sizeof(data->addr.ip6);
				break;
			case HAPROXY_AF_UNSPEC:
			case HAPROXY_AF_UNIX:
				/* unsupported; ignored */
				i_error("haproxy(v2): Unsupported address family "
					"(family=%02x, rip=%s)", (hdr->fam & 0xf0) >> 4,
					net_ip2addr(real_remote_ip));
				break;
			default:
				/* unsupported; error */
				i_error("haproxy(v2): Client disconnected: "
					"Unknown address family "
					"(family=%02x, rip=%s)", (hdr->fam & 0xf0) >> 4,
					net_ip2addr(real_remote_ip));
				return -1;
			}
			break;
		default:
			i_error("haproxy(v2): Client disconnected: "
				"Invalid command (cmd=%02x, rip=%s)",
				(hdr->ver_cmd & 0x0f),
				net_ip2addr(real_remote_ip));
			return -1; /* not a supported command */
		}

		if (master_service_haproxy_parse_tlv(hpconn, rbuf+i, size-i, &error) < 0) {
			i_error("haproxy(v2): Client disconnected: "
				"Invalid TLV: %s (cmd=%02x, rip=%s)",
				error,
				(hdr->ver_cmd & 0x0f),
				net_ip2addr(real_remote_ip));
			return -1;
		}
	/* protocol version 1 (soon obsolete) */
	} else if (version == HAPROXY_VERSION_1) {
コード例 #28
0
ファイル: pop3-proxy.c プロジェクト: bdraco/core
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;
}
コード例 #29
0
ファイル: client-authenticate.c プロジェクト: bdraco/core
void imap_client_auth_result(struct client *client,
			     enum client_auth_result result,
			     const struct client_auth_reply *reply,
			     const char *text)
{
	struct imap_url url;
	string_t *referral;

	switch (result) {
	case CLIENT_AUTH_RESULT_SUCCESS:
		/* nothing to be done for IMAP */
		break;
	case CLIENT_AUTH_RESULT_REFERRAL_SUCCESS:
	case CLIENT_AUTH_RESULT_REFERRAL_NOLOGIN:
		/* IMAP referral

		   [nologin] referral host=.. [port=..] [destuser=..]
		   [reason=..]

		   NO [REFERRAL imap://destuser;AUTH=..@host:port/] Can't login.
		   OK [...] Logged in, but you should use this server instead.
		   .. [REFERRAL ..] (Reason from auth server)
		*/
		referral = t_str_new(128);

		i_zero(&url);
		url.userid = reply->destuser;
		url.auth_type = client->auth_mech_name;
		url.host.name = reply->host;
		if (reply->port != 143)
			url.port = reply->port;
		str_append(referral, "REFERRAL ");
		str_append(referral, imap_url_create(&url));

		if (result == CLIENT_AUTH_RESULT_REFERRAL_SUCCESS) {
			client_send_reply_code(client, IMAP_CMD_REPLY_OK,
					       str_c(referral), text);
		} else {
			client_send_reply_code(client, IMAP_CMD_REPLY_NO,
					       str_c(referral), text);
		}
		break;
	case CLIENT_AUTH_RESULT_INVALID_BASE64:
	case CLIENT_AUTH_RESULT_ABORTED:
		client_send_reply(client, IMAP_CMD_REPLY_BAD, text);
		break;
	case CLIENT_AUTH_RESULT_AUTHFAILED_REASON:
	case CLIENT_AUTH_RESULT_MECH_INVALID:
		if (text[0] == '[')
			client_send_reply(client, IMAP_CMD_REPLY_NO, text);
		else {
			client_send_reply_code(client, IMAP_CMD_REPLY_NO,
					       "ALERT", text);
		}
		break;
	case CLIENT_AUTH_RESULT_AUTHZFAILED:
		client_send_reply_code(client, IMAP_CMD_REPLY_NO,
				       IMAP_RESP_CODE_AUTHZFAILED, text);
		break;
	case CLIENT_AUTH_RESULT_TEMPFAIL:
		client_send_reply_code(client, IMAP_CMD_REPLY_NO,
				       IMAP_RESP_CODE_UNAVAILABLE, text);
		break;
	case CLIENT_AUTH_RESULT_SSL_REQUIRED:
	case CLIENT_AUTH_RESULT_MECH_SSL_REQUIRED:
		client_send_reply_code(client, IMAP_CMD_REPLY_NO,
				       IMAP_RESP_CODE_PRIVACYREQUIRED, text);
		break;
	case CLIENT_AUTH_RESULT_PASS_EXPIRED:
		client_send_reply_code(client, IMAP_CMD_REPLY_NO,
				       IMAP_RESP_CODE_EXPIRED, text);
		break;
	case CLIENT_AUTH_RESULT_LOGIN_DISABLED:
		client_send_reply_code(client, IMAP_CMD_REPLY_NO,
				       IMAP_RESP_CODE_CONTACTADMIN, text);
		break;
	case CLIENT_AUTH_RESULT_AUTHFAILED:
		client_send_reply_code(client, IMAP_CMD_REPLY_NO,
				       IMAP_RESP_CODE_AUTHFAILED, text);
		break;
	}
}
コード例 #30
0
ファイル: stats-dist.c プロジェクト: bdraco/core
void stats_dist_reset(struct stats_dist *stats)
{
	unsigned int sample_count = stats->sample_count;
	i_zero(stats);
	stats->sample_count = sample_count;
}