AR_IAUTH_HURRY, /**< we told iauth to hurry up */
AR_IAUTH_USERNAME, /**< iauth sent a username (preferred or forced) */
AR_IAUTH_FUSERNAME, /**< iauth sent a forced username */
+ AR_IAUTH_SOFT_DONE, /**< iauth has no objection to client */
AR_PASSWORD_CHECKED, /**< client password already checked */
AR_NUM_FLAGS
};
/* Can this ever happen? */
case ACR_BAD_SOCKET:
++ServerStats->is_ref;
- IPcheck_connect_fail(cptr);
+ IPcheck_connect_fail(cptr, 0);
return exit_client(cptr, cptr, &me, "Unknown error -- Try again");
}
return 0;
if (IsUserPort(auth->client))
sendheader(auth->client, REPORT_FAIL_ID);
++ServerStats->is_abad;
+ if (IAuthHas(iauth, IAUTH_UNDERNET))
+ sendto_iauth(auth->client, "u");
} else {
if (IsUserPort(auth->client))
sendheader(auth->client, REPORT_FIN_ID);
/* Check for iauth timeout. */
if (FlagHas(&auth->flags, AR_IAUTH_PENDING)) {
- if (IAuthHas(iauth, IAUTH_REQUIRED)) {
+ if (IAuthHas(iauth, IAUTH_REQUIRED)
+ && !FlagHas(&auth->flags, AR_IAUTH_SOFT_DONE)) {
sendheader(cptr, REPORT_FAIL_IAUTH);
return exit_client_msg(cptr, cptr, &me, "Authorization Timeout");
}
}
auth->port = remote.port;
- /* Try to start DNS lookup. */
- start_dns_query(auth);
-
- /* Try to start ident lookup. */
- start_auth_query(auth);
-
/* Set required client inputs for users. */
if (IsUserPort(client)) {
cli_user(client) = make_user(client);
start_iauth_query(auth);
}
+ /* Try to start DNS lookup. */
+ start_dns_query(auth);
+
+ /* Try to start ident lookup. */
+ start_auth_query(auth);
+
/* Add client to GlobalClientList. */
add_client_to_list(client);
if (iauth == NULL)
return;
- /* Close main socket. */
- if (s_fd(i_socket(iauth)) != -1) {
- close(s_fd(i_socket(iauth)));
- socket_del(i_socket(iauth));
- s_fd(i_socket(iauth)) = -1;
- }
-
/* Close error socket. */
if (s_fd(i_stderr(iauth)) != -1) {
close(s_fd(i_stderr(iauth)));
socket_del(i_stderr(iauth));
s_fd(i_stderr(iauth)) = -1;
}
+
+ /* Close main socket. */
+ if (s_fd(i_socket(iauth)) != -1) {
+ close(s_fd(i_socket(iauth)));
+ socket_del(i_socket(iauth));
+ s_fd(i_socket(iauth)) = -1;
+ }
}
/** Close all %IAuth connections marked as closing. */
memcpy(&auth->original, &cli_ip(cli), sizeof(auth->original));
/* Undo original IP connection in IPcheck. */
- IPcheck_connect_fail(cli);
+ IPcheck_connect_fail(cli, 1);
ClearIPChecked(cli);
/* Update the IP and charge them as a remote connect. */
return aconf;
}
+/** Tentatively accept a client in IAuth.
+ * @param[in] iauth Active IAuth session.
+ * @param[in] cli Client referenced by command.
+ * @param[in] parc Number of parameters.
+ * @param[in] params Optional class name for client.
+ * @return Negative (CPTR_KILLED) if the connection is refused, one otherwise.
+ */
+static int iauth_cmd_soft_done(struct IAuth *iauth, struct Client *cli,
+ int parc, char **params)
+{
+ /* Clear iauth pending flag. */
+ assert(cli_auth(cli) != NULL);
+ FlagSet(&cli_auth(cli)->flags, AR_IAUTH_SOFT_DONE);
+ return 1;
+}
+
/** Accept a client in IAuth.
* @param[in] iauth Active IAuth session.
* @param[in] cli Client referenced by command.
}
/* If account has a creation timestamp, use it. */
assert(cli_user(cli) != NULL);
- if (params[0][len] == ':')
+ if (params[0][len] == ':') {
cli_user(cli)->acc_create = strtoul(params[0] + len + 1, NULL, 10);
+ params[0][len] = '\0';
+ }
/* Copy account name to User structure. */
ircd_strncpy(cli_user(cli)->account, params[0], ACCOUNTLEN);
case 'I': handler = iauth_cmd_ip_address; has_cli = 1; break;
case 'M': handler = iauth_cmd_usermode; has_cli = 1; break;
case 'C': handler = iauth_cmd_challenge; has_cli = 1; break;
+ case 'd': handler = iauth_cmd_soft_done; has_cli = 1; break;
case 'D': handler = iauth_cmd_done_client; has_cli = 1; break;
case 'R': handler = iauth_cmd_done_account; has_cli = 1; break;
case 'k': /* The 'k' command indicates the user should be booted
switch (ev_type(ev)) {
case ET_DESTROY:
- /* Hm, what happened here? */
- if (!IAuthHas(iauth, IAUTH_CLOSING))
+ if (!IAuthHas(iauth, IAUTH_CLOSING) && !s_active(i_stderr(iauth)))
iauth_do_spawn(iauth, 1);
break;
case ET_READ:
switch (ev_type(ev)) {
case ET_DESTROY:
- /* We do not restart iauth here: the stdout handler does that for us. */
+ if (!IAuthHas(iauth, IAUTH_CLOSING) && !s_active(i_socket(iauth)))
+ iauth_do_spawn(iauth, 1);
break;
case ET_READ:
iauth_read_stderr(iauth);