X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fs_auth.c;h=e250ae6736ef3a9348f32fd097e11c8d0bf77d71;hb=8a0fce5ce44018405ec3aab7115f7b7028c90329;hp=b578c43dfde8561ab448c4923775d95f439ad773;hpb=92a11018ec6d46d6c3cda510c5a59afd29e0148c;p=ircu2.10.12-pk.git diff --git a/ircd/s_auth.c b/ircd/s_auth.c index b578c43..e250ae6 100644 --- a/ircd/s_auth.c +++ b/ircd/s_auth.c @@ -52,6 +52,7 @@ #include "list.h" #include "msg.h" /* for MAXPARA */ #include "numeric.h" +#include "numnicks.h" #include "querycmds.h" #include "random.h" #include "res.h" @@ -83,6 +84,7 @@ enum AuthRequestFlag { 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 }; @@ -790,7 +792,8 @@ int auth_ping_timeout(struct Client *cptr) /* 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"); } @@ -1019,12 +1022,6 @@ void start_auth(struct Client* client) } 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); @@ -1036,6 +1033,12 @@ void start_auth(struct Client* 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); @@ -1140,6 +1143,17 @@ void auth_send_exit(struct Client *cptr) sendto_iauth(cptr, "D"); } +/** Forward an XREPLY on to iauth. + * @param[in] sptr Source of the XREPLY. + * @param[in] routing Routing information for the original XQUERY. + * @param[in] reply Contents of the reply. + */ +void auth_send_xreply(struct Client *sptr, const char *routing, + const char *reply) +{ + sendto_iauth(NULL, "X %#C %s :%s", sptr, routing, reply); +} + /** Mark that a user has started capabilities negotiation. * This blocks authorization until auth_cap_done() is called. * @param[in] auth Authorization request for client. @@ -1188,13 +1202,17 @@ int iauth_do_spawn(struct IAuth *iauth, int automatic) /* Attempt to allocate a pair of sockets. */ res = os_socketpair(s_io); - if (res) - return errno; + if (res) { + res = errno; + Debug((DEBUG_INFO, "Unable to create IAuth socketpair: %s", strerror(res))); + return res; + } /* Mark the parent's side of the pair (element 0) as non-blocking. */ res = os_set_nonblocking(s_io[0]); if (!res) { res = errno; + Debug((DEBUG_INFO, "Unable to make IAuth socket non-blocking: %s", strerror(res))); close(s_io[1]); close(s_io[0]); return res; @@ -1205,6 +1223,7 @@ int iauth_do_spawn(struct IAuth *iauth, int automatic) SS_CONNECTED, SOCK_EVENT_READABLE, s_io[0]); if (!res) { res = errno; + Debug((DEBUG_INFO, "Unable to register IAuth socket: %s", strerror(res))); close(s_io[1]); close(s_io[0]); return res; @@ -1214,6 +1233,7 @@ int iauth_do_spawn(struct IAuth *iauth, int automatic) res = os_socketpair(s_err); if (res) { res = errno; + Debug((DEBUG_INFO, "Unable to create IAuth stderr: %s", strerror(res))); socket_del(i_socket(iauth)); close(s_io[1]); close(s_io[0]); @@ -1224,6 +1244,7 @@ int iauth_do_spawn(struct IAuth *iauth, int automatic) res = os_set_nonblocking(s_err[0]); if (!res) { res = errno; + Debug((DEBUG_INFO, "Unable to make IAuth stderr non-blocking: %s", strerror(res))); close(s_err[1]); close(s_err[0]); socket_del(i_socket(iauth)); @@ -1237,6 +1258,7 @@ int iauth_do_spawn(struct IAuth *iauth, int automatic) SS_CONNECTED, SOCK_EVENT_READABLE, s_err[0]); if (!res) { res = errno; + Debug((DEBUG_INFO, "Unable to register IAuth stderr: %s", strerror(res))); close(s_err[1]); close(s_err[0]); socket_del(i_socket(iauth)); @@ -1250,6 +1272,7 @@ int iauth_do_spawn(struct IAuth *iauth, int automatic) if (cpid < 0) { /* Error forking the child, still in parent. */ res = errno; + Debug((DEBUG_INFO, "Unable to fork IAuth child: %s", strerror(res))); socket_del(i_stderr(iauth)); close(s_err[1]); close(s_err[0]); @@ -1309,17 +1332,15 @@ int auth_spawn(int argc, char *argv[]) same = 0; } /* Check that we have no more pre-existing arguments. */ - if (iauth->i_argv[ii]) + if (same && iauth->i_argv[ii]) same = 0; - /* If they are the same and still connected, clear the "closing" flag and exit.*/ + /* If they are the same and still connected, clear the "closing" flag and exit. */ if (same && i_GetConnected(iauth)) { + Debug((DEBUG_INFO, "Reusing existing IAuth process")); IAuthClr(iauth, IAUTH_CLOSING); return 2; } - /* Deallocate old argv elements. */ - for (ii = 0; iauth->i_argv[ii]; ++ii) - MyFree(iauth->i_argv[ii]); - MyFree(iauth->i_argv); + auth_close_unused(); } /* Need to initialize a new connection. */ @@ -1861,6 +1882,22 @@ static struct ConfItem *auth_find_class_conf(const char *class_name) 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. @@ -1934,8 +1971,10 @@ static int iauth_cmd_done_account(struct IAuth *iauth, struct Client *cli, } /* 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); @@ -1997,6 +2036,55 @@ static int iauth_cmd_challenge(struct IAuth *iauth, struct Client *cli, return 0; } +/** Send an extension query to a specified remote server. + * @param[in] iauth Active IAuth session. + * @param[in] cli Client referenced by command. + * @param[in] parc Number of parameters (3). + * @param[in] params Remote server, routing information, and query. + * @return Zero. + */ +static int iauth_cmd_xquery(struct IAuth *iauth, struct Client *cli, + int parc, char **params) +{ + char *serv; + const char *routing; + const char *query; + struct Client *acptr; + + /* Process parameters */ + if (EmptyString(params[0])) { + sendto_iauth(cli, "E Missing :Missing server parameter"); + return 0; + } else + serv = params[0]; + + if (EmptyString(params[1])) { + sendto_iauth(cli, "E Missing :Missing routing parameter"); + return 0; + } else + routing = params[1]; + + if (EmptyString(params[2])) { + sendto_iauth(cli, "E Missing :Missing query parameter"); + return 0; + } else + query = params[2]; + + /* Try to find the specified server */ + if (!(acptr = find_match_server(serv))) { + sendto_iauth(cli, "x %s %s :Server not online", serv, routing); + return 0; + } + + /* If it's to us, do nothing; otherwise, forward the query */ + if (!IsMe(acptr)) + /* The "iauth:" prefix helps ircu route the reply to iauth */ + sendcmdto_one(&me, CMD_XQUERY, acptr, "%C iauth:%s :%s", acptr, routing, + query); + + return 0; +} + /** Parse a \a message from \a iauth. * @param[in] iauth Active IAuth session. * @param[in] message Message to be parsed. @@ -2021,6 +2109,7 @@ static void iauth_parse(struct IAuth *iauth, char *message) case 'A': handler = iauth_cmd_config; has_cli = 0; break; case 's': handler = iauth_cmd_newstats; has_cli = 0; break; case 'S': handler = iauth_cmd_stats; has_cli = 0; break; + case 'X': handler = iauth_cmd_xquery; has_cli = 0; break; case 'o': handler = iauth_cmd_username_forced; has_cli = 1; break; case 'U': handler = iauth_cmd_username_good; has_cli = 1; break; case 'u': handler = iauth_cmd_username_bad; has_cli = 1; break; @@ -2028,6 +2117,7 @@ static void iauth_parse(struct IAuth *iauth, char *message) 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