login-connection.c revision e93184a9055c2530366dfe617e07199603c399dd
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2010-2016 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct login_connection *login_connections;
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainenstatic void auth_input_line(const char *line, void *context);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void login_connection_unref(struct login_connection **_conn);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void login_connection_input(struct login_connection *conn)
2cc34f340d31125b16f58948bed8cc6a86911fcfTimo Sirainen output = auth_connection_get_output(conn->auth);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainenstatic void login_connection_authreply_input(struct login_connection *conn)
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen while ((line = i_stream_read_next_line(conn->input)) != NULL) T_BEGIN {
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen if (!version_string_verify(line, "director-authreply-client",
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen i_error("authreply client sent invalid handshake: %s", line);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen i_error("read(authreply connection) failed: %s",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenlogin_connection_send_line(struct login_connection *conn, const char *line)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen o_stream_nsendv(conn->output, iov, N_ELEMENTS(iov));
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainenstatic bool login_host_request_is_self(struct login_host_request *request,
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen if (!net_ip_compare(dest_ip, &request->local_ip))
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen if (request->dest_port != 0 && request->local_port != 0 &&
9de5eb9e1ac3a07c4197a60fdefd412d6cc78eb2Timo Sirainenlogin_host_callback(const struct ip_addr *ip, const char *hostname,
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen unsigned int secs;
44875c83e0fa7111571262686818d8de43a57b2fTimo Sirainen else if (strncmp(request->line, "PASS\t", 5) == 0)
44875c83e0fa7111571262686818d8de43a57b2fTimo Sirainen i_panic("BUG: Unexpected line: %s", request->line);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainen i_error("director: User %s host lookup failed: %s",
44875c83e0fa7111571262686818d8de43a57b2fTimo Sirainen line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'),
9de5eb9e1ac3a07c4197a60fdefd412d6cc78eb2Timo Sirainen str_printfa(str, "%s\tproxy_refresh=%u\t", request->line, secs);
152db3f90f298b7fb2dbbd4276f0fc30a9bc30f6Timo Sirainen login_connection_send_line(request->conn, line);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void auth_input_line(const char *line, void *context)
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen struct login_host_request *request, temp_request;
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainen const char *const *args, *line_params, *username = NULL, *tag = "";
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* auth connection died -> kill also this login connection */
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen if (conn->type != LOGIN_CONNECTION_TYPE_USERDB &&
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen else if (conn->type == LOGIN_CONNECTION_TYPE_USERDB &&
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* OK <id> [<parameters>] */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* we should always get here, but in case we don't just
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen forward as-is and let login process handle the error. */
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen memset(&temp_request, 0, sizeof(temp_request));
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen if (net_addr2ip((*args) + 4, &temp_request.local_ip) < 0)
f0d8efc20cfcb38c132d333704bb08de2e9c62f1Timo Sirainen i_error("auth sent invalid lip field: %s", (*args) + 6);
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen } else if (strncmp(*args, "lport=", 6) == 0) {
009217abb57a24a4076092e8e4e165545747839eStephan Bosch if (net_str2port((*args) + 6, &temp_request.local_port) < 0)
f0d8efc20cfcb38c132d333704bb08de2e9c62f1Timo Sirainen i_error("auth sent invalid lport field: %s", (*args) + 6);
009217abb57a24a4076092e8e4e165545747839eStephan Bosch if (net_str2port((*args) + 5, &temp_request.dest_port) < 0)
f0d8efc20cfcb38c132d333704bb08de2e9c62f1Timo Sirainen i_error("auth sent invalid port field: %s", (*args) + 6);
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen } else if (strncmp(*args, "destuser=", 9) == 0)
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainen else if (strncmp(*args, "director_tag=", 13) == 0)
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen else if (strncmp(*args, "director_proxy_maybe", 20) == 0 &&
0dc72981f5286d60ca9233f6ac7c444d393d24fbTimo Sirainen if ((!proxy && !temp_request.director_proxy_maybe) ||
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (*conn->dir->set->master_user_separator != '\0') {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* with master user logins we still want to use only the
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen login username */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* we need to add the host. the lookup might be asynchronous */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen request = i_new(struct login_host_request, 1);
09060303d565e15d54e42b4ef722f9d3c26f5336Timo Sirainen director_request(conn->dir, username, tag, login_host_callback, request);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenlogin_connection_init(struct director *dir, int fd,
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi conn->output = o_stream_create_fd(conn->fd, (size_t)-1);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen o_stream_set_no_error_handling(conn->output, TRUE);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen if (type != LOGIN_CONNECTION_TYPE_AUTHREPLY) {
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen auth_connection_set_callback(conn->auth, auth_input_line, conn);
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi conn->input = i_stream_create_fd(conn->fd, IO_BLOCK_SIZE);
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen o_stream_nsend_str(conn->output, t_strdup_printf(
db3b95d5a33ddce552d41136ae68d7331f8bf5feTimo Sirainen "VERSION\tdirector-authreply-server\t%d\t%d\n",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid login_connection_deinit(struct login_connection **_conn)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_error("close(login connection) failed: %m");
fe8af34153615d9007f2238fca87df11ff32d614Timo Sirainen master_service_client_connection_destroyed(master_service);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void login_connection_unref(struct login_connection **_conn)