static void login_host_callback(const struct ip_addr *ip, const char *errormsg, void *context) { struct login_host_request *request = context; struct director *dir = request->conn->dir; const char *line, *line_params; unsigned int secs; if (ip != NULL) { secs = dir->set->director_user_expire / 2; line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u", request->line, net_ip2addr(ip), secs); } else { if (strncmp(request->line, "OK\t", 3) == 0) line_params = request->line + 3; else if (strncmp(request->line, "PASS\t", 5) == 0) line_params = request->line + 5; else i_panic("BUG: Unexpected line: %s", request->line); i_error("director: User %s host lookup failed: %s", request->username, errormsg); line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'), "\ttemp", NULL); } login_connection_send_line(request->conn, line); login_connection_unref(&request->conn); i_free(request->username); i_free(request->line); i_free(request); }
static void login_host_callback(const struct ip_addr *ip, const char *hostname, const char *errormsg, void *context) { struct login_host_request *request = context; struct director *dir = request->conn->dir; const char *line, *line_params; unsigned int secs; if (ip == NULL) { if (strncmp(request->line, "OK\t", 3) == 0) line_params = request->line + 3; else if (strncmp(request->line, "PASS\t", 5) == 0) line_params = request->line + 5; else i_panic("BUG: Unexpected line: %s", request->line); i_error("director: User %s host lookup failed: %s", request->username, errormsg); line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'), "\ttemp", NULL); } else if (request->director_proxy_maybe && login_host_request_is_self(request, ip)) { line = request->line; } else { string_t *str = t_str_new(64); secs = dir->set->director_user_expire / 2; str_printfa(str, "%s\tproxy_refresh=%u\t", request->line, secs); if (hostname == NULL || hostname[0] == '\0') str_printfa(str, "host=%s", net_ip2addr(ip)); else { str_printfa(str, "host=%s\thostip=%s", hostname, net_ip2addr(ip)); } line = str_c(str); } login_connection_send_line(request->conn, line); login_connection_unref(&request->conn); i_free(request->username); i_free(request->line); i_free(request); }
static void auth_input_line(const char *line, void *context) { struct login_connection *conn = context; struct login_host_request *request, temp_request; const char *const *args, *line_params, *username = NULL, *tag = ""; bool proxy = FALSE, host = FALSE; if (line == NULL) { /* auth connection died -> kill also this login connection */ login_connection_deinit(&conn); return; } if (conn->type != LOGIN_CONNECTION_TYPE_USERDB && strncmp(line, "OK\t", 3) == 0) line_params = line + 3; else if (conn->type == LOGIN_CONNECTION_TYPE_USERDB && strncmp(line, "PASS\t", 5) == 0) line_params = line + 5; else { login_connection_send_line(conn, line); return; } /* OK <id> [<parameters>] */ args = t_strsplit_tab(line_params); if (*args != NULL) { /* we should always get here, but in case we don't just forward as-is and let login process handle the error. */ args++; } memset(&temp_request, 0, sizeof(temp_request)); for (; *args != NULL; args++) { if (strncmp(*args, "proxy", 5) == 0 && ((*args)[5] == '=' || (*args)[5] == '\0')) proxy = TRUE; else if (strncmp(*args, "host=", 5) == 0) host = TRUE; else if (strncmp(*args, "lip=", 4) == 0) { if (net_addr2ip((*args) + 4, &temp_request.local_ip) < 0) i_error("auth sent invalid lip field: %s", (*args) + 6); } else if (strncmp(*args, "lport=", 6) == 0) { if (str_to_uint((*args) + 6, &temp_request.local_port) < 0) i_error("auth sent invalid lport field: %s", (*args) + 6); } else if (strncmp(*args, "port=", 5) == 0) { if (str_to_uint((*args) + 5, &temp_request.dest_port) < 0) i_error("auth sent invalid port field: %s", (*args) + 6); } else if (strncmp(*args, "destuser="******"director_tag=", 13) == 0) tag = *args + 13; else if (strncmp(*args, "director_proxy_maybe", 20) == 0 && ((*args)[20] == '=' || (*args)[20] == '\0')) temp_request.director_proxy_maybe = TRUE; else if (strncmp(*args, "user=", 5) == 0) { if (username == NULL) username = *args + 5; } } if ((!proxy && !temp_request.director_proxy_maybe) || host || username == NULL) { login_connection_send_line(conn, line); return; } if (*conn->dir->set->master_user_separator != '\0') { /* with master user logins we still want to use only the login username */ username = t_strcut(username, *conn->dir->set->master_user_separator); } /* we need to add the host. the lookup might be asynchronous */ request = i_new(struct login_host_request, 1); *request = temp_request; request->conn = conn; request->line = i_strdup(line); request->username = i_strdup(username); conn->refcount++; director_request(conn->dir, username, tag, login_host_callback, request); }
static void auth_input_line(const char *line, void *context) { struct login_connection *conn = context; struct login_host_request *request; const char *const *args, *line_params, *username = NULL; bool proxy = FALSE, host = FALSE; if (line == NULL) { /* auth connection died -> kill also this login connection */ login_connection_deinit(&conn); return; } if (!conn->userdb && strncmp(line, "OK\t", 3) == 0) line_params = line + 3; else if (conn->userdb && strncmp(line, "PASS\t", 5) == 0) line_params = line + 5; else { login_connection_send_line(conn, line); return; } /* OK <id> [<parameters>] */ args = t_strsplit_tab(line_params); if (*args != NULL) { /* we should always get here, but in case we don't just forward as-is and let login process handle the error. */ args++; } for (; *args != NULL; args++) { if (strncmp(*args, "proxy", 5) == 0 && ((*args)[5] == '=' || (*args)[5] == '\0')) proxy = TRUE; else if (strncmp(*args, "host=", 5) == 0) host = TRUE; else if (strncmp(*args, "destuser="******"user=", 5) == 0) { if (username == NULL) username = *args + 5; } } if (!proxy || host || username == NULL) { login_connection_send_line(conn, line); return; } if (*conn->dir->set->master_user_separator != '\0') { /* with master user logins we still want to use only the login username */ username = t_strcut(username, *conn->dir->set->master_user_separator); } /* we need to add the host. the lookup might be asynchronous */ request = i_new(struct login_host_request, 1); request->conn = conn; request->line = i_strdup(line); request->username = i_strdup(username); conn->refcount++; director_request(conn->dir, username, login_host_callback, request); }