X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/5366977b4f3c7a50d170bf7a1e29b14c74944db7..016746cfc222a0df1fc8892e0930ab9c2790b69e:/src/s_auth.c diff --git a/src/s_auth.c b/src/s_auth.c index 6224aa6..83407b3 100644 --- a/src/s_auth.c +++ b/src/s_auth.c @@ -21,7 +21,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_auth.c 3161 2007-01-25 07:23:01Z nenolod $ */ + * $Id: s_auth.c 3354 2007-04-03 09:21:31Z nenolod $ */ /* * Changes: @@ -35,26 +35,56 @@ */ #include "stdinc.h" #include "config.h" -#include "tools.h" #include "s_auth.h" #include "s_conf.h" #include "client.h" #include "common.h" -#include "event.h" -#include "irc_string.h" -#include "sprintf_irc.h" +#include "match.h" #include "ircd.h" #include "numeric.h" #include "packet.h" #include "res.h" -#include "commio.h" -#include "s_log.h" +#include "logger.h" #include "s_stats.h" #include "send.h" -#include "memory.h" #include "hook.h" #include "blacklist.h" +struct AuthRequest +{ + rb_dlink_node node; + struct Client *client; /* pointer to client struct for request */ + struct DNSQuery dns_query; /* DNS Query */ + unsigned int flags; /* current state of request */ + rb_fde_t *F; /* file descriptor for auth queries */ + time_t timeout; /* time when query expires */ + uint16_t lport; + uint16_t rport; +}; + +/* + * flag values for AuthRequest + * NAMESPACE: AM_xxx - Authentication Module + */ +#define AM_AUTH_CONNECTING (1 << 0) +#define AM_AUTH_PENDING (1 << 1) +#define AM_DNS_PENDING (1 << 2) + +#define SetDNSPending(x) ((x)->flags |= AM_DNS_PENDING) +#define ClearDNSPending(x) ((x)->flags &= ~AM_DNS_PENDING) +#define IsDNSPending(x) ((x)->flags & AM_DNS_PENDING) + +#define SetAuthConnect(x) ((x)->flags |= AM_AUTH_CONNECTING) +#define ClearAuthConnect(x) ((x)->flags &= ~AM_AUTH_CONNECTING) +#define IsAuthConnect(x) ((x)->flags & AM_AUTH_CONNECTING) + +#define SetAuthPending(x) ((x)->flags |= AM_AUTH_PENDING) +#define ClearAuthPending(x) ((x)->flags &= AM_AUTH_PENDING) +#define IsAuthPending(x) ((x)->flags & AM_AUTH_PENDING) + +#define ClearAuth(x) ((x)->flags &= ~(AM_AUTH_PENDING | AM_AUTH_CONNECTING)) +#define IsDoingAuth(x) ((x)->flags & (AM_AUTH_PENDING | AM_AUTH_CONNECTING)) + /* * a bit different approach * this replaces the original sendheader macros @@ -89,8 +119,8 @@ ReportType; #define sendheader(c, r) sendto_one_notice(c, HeaderMessages[(r)]) -static dlink_list auth_poll_list; -static BlockHeap *auth_heap; +static rb_dlink_list auth_poll_list; +static rb_bh *auth_heap; static EVH timeout_auth_queries_event; static PF read_auth_reply; @@ -106,8 +136,8 @@ init_auth(void) { /* This hook takes a struct Client for its argument */ memset(&auth_poll_list, 0, sizeof(auth_poll_list)); - eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1); - auth_heap = BlockHeapCreate(sizeof(struct AuthRequest), LCLIENT_HEAP_SIZE); + rb_event_addish("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1); + auth_heap = rb_bh_create(sizeof(struct AuthRequest), LCLIENT_HEAP_SIZE, "auth_heap"); } /* @@ -116,11 +146,11 @@ init_auth(void) static struct AuthRequest * make_auth_request(struct Client *client) { - struct AuthRequest *request = BlockHeapAlloc(auth_heap); + struct AuthRequest *request = rb_bh_alloc(auth_heap); client->localClient->auth_request = request; - request->fd = -1; + request->F = NULL; request->client = client; - request->timeout = CurrentTime + ConfigFileEntry.connect_timeout; + request->timeout = rb_current_time() + ConfigFileEntry.connect_timeout; return request; } @@ -130,7 +160,7 @@ make_auth_request(struct Client *client) static void free_auth_request(struct AuthRequest *request) { - BlockHeapFree(auth_heap, request); + rb_bh_free(auth_heap, request); } /* @@ -147,10 +177,8 @@ release_auth_client(struct AuthRequest *auth) return; client->localClient->auth_request = NULL; - dlinkDelete(&auth->node, &auth_poll_list); + rb_dlinkDelete(&auth->node, &auth_poll_list); free_auth_request(auth); - if(client->localClient->fd > highest_fd) - highest_fd = client->localClient->fd; /* * When a client has auth'ed, we want to start reading what it sends @@ -158,9 +186,8 @@ release_auth_client(struct AuthRequest *auth) * -- adrian */ client->localClient->allow_read = MAX_FLOOD; - comm_setflush(client->localClient->fd, 1000, flood_recalc, client); - dlinkAddTail(client, &client->node, &global_client_list); - read_packet(client->localClient->fd, client); + rb_dlinkAddTail(client, &client->node, &global_client_list); + read_packet(client->localClient->F, client); } /* @@ -182,7 +209,7 @@ auth_dns_callback(void *vptr, struct DNSReply *reply) sendto_realops_snomask(SNO_GENERAL, L_ALL, "auth_dns_callback(): auth->client->localClient (%s) is NULL", get_client_name(auth->client, HIDE_IP)); - dlinkDelete(&auth->node, &auth_poll_list); + rb_dlinkDelete(&auth->node, &auth_poll_list); free_auth_request(auth); /* and they will silently drop through and all will hopefully be ok... -nenolod */ @@ -206,7 +233,7 @@ auth_dns_callback(void *vptr, struct DNSReply *reply) good = 0; } } -#ifdef IPV6 +#ifdef RB_IPV6 else if(auth->client->localClient->ip.ss_family == AF_INET6) { struct sockaddr_in6 *ip, *ip_fwd; @@ -229,7 +256,7 @@ auth_dns_callback(void *vptr, struct DNSReply *reply) if(good && strlen(reply->h_name) <= HOSTLEN) { - strlcpy(auth->client->host, reply->h_name, sizeof(auth->client->host)); + rb_strlcpy(auth->client->host, reply->h_name, sizeof(auth->client->host)); sendheader(auth->client, REPORT_FIN_DNS); } else if (strlen(reply->h_name) > HOSTLEN) @@ -247,10 +274,10 @@ auth_dns_callback(void *vptr, struct DNSReply *reply) static void auth_error(struct AuthRequest *auth) { - ++ServerStats->is_abad; + ++ServerStats.is_abad; - comm_close(auth->fd); - auth->fd = -1; + rb_close(auth->F); + auth->F = NULL; ClearAuth(auth); sendheader(auth->client, REPORT_FAIL_ID); @@ -269,29 +296,31 @@ auth_error(struct AuthRequest *auth) static int start_auth_query(struct AuthRequest *auth) { - struct irc_sockaddr_storage localaddr; - socklen_t locallen = sizeof(struct irc_sockaddr_storage); - int fd; + struct rb_sockaddr_storage localaddr, destaddr; + socklen_t locallen = sizeof(struct rb_sockaddr_storage); + rb_fde_t *F; int family; if(IsAnyDead(auth->client)) return 0; family = auth->client->localClient->ip.ss_family; - if((fd = comm_socket(family, SOCK_STREAM, 0, "ident")) == -1) + if((F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL) { - report_error("creating auth stream socket %s:%s", - get_client_name(auth->client, SHOW_IP), - log_client_name(auth->client, SHOW_IP), errno); - ++ServerStats->is_abad; + ilog_error("creating auth stream socket"); + ++ServerStats.is_abad; return 0; } - if((MAXCONNECTIONS - 10) < fd) + + /* + * TBD: this is a pointless arbitrary limit .. we either have a socket or not. -nenolod + */ + if((maxconnections - 10) < rb_get_fd(F)) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Can't allocate fd for auth on %s", get_client_name(auth->client, SHOW_IP)); - comm_close(fd); + rb_close(F); return 0; } @@ -305,25 +334,49 @@ start_auth_query(struct AuthRequest *auth) * and machines with multiple IP addresses are common now */ memset(&localaddr, 0, locallen); - getsockname(auth->client->localClient->fd, - (struct sockaddr *) &localaddr, &locallen); + if(getsockname(rb_get_fd(auth->client->localClient->F), + (struct sockaddr *) &localaddr, &locallen) == -1) + { + /* can happen if connection was just closed */ + rb_close(F); + return 0; + } - mangle_mapped_sockaddr((struct sockaddr *)&localaddr); -#ifdef IPV6 + /* XXX mangle_mapped_sockaddr((struct sockaddr *)&localaddr); */ +#ifdef RB_IPV6 if(localaddr.ss_family == AF_INET6) { + auth->lport = ntohs(((struct sockaddr_in6 *)&localaddr)->sin6_port); ((struct sockaddr_in6 *)&localaddr)->sin6_port = 0; - } else + } + else +#endif + { + auth->lport = ntohs(((struct sockaddr_in *)&localaddr)->sin_port); + ((struct sockaddr_in *)&localaddr)->sin_port = 0; + } + + destaddr = auth->client->localClient->ip; +#ifdef RB_IPV6 + if(localaddr.ss_family == AF_INET6) + { + auth->rport = ntohs(((struct sockaddr_in6 *)&destaddr)->sin6_port); + ((struct sockaddr_in6 *)&destaddr)->sin6_port = htons(113); + } + else #endif - ((struct sockaddr_in *)&localaddr)->sin_port = 0; + { + auth->rport = ntohs(((struct sockaddr_in *)&destaddr)->sin_port); + ((struct sockaddr_in *)&destaddr)->sin_port = htons(113); + } - auth->fd = fd; + auth->F = F; SetAuthConnect(auth); - comm_connect_tcp(fd, auth->client->sockhost, 113, - (struct sockaddr *) &localaddr, GET_SS_LEN(localaddr), + rb_connect_tcp(F, (struct sockaddr *)&destaddr, + (struct sockaddr *) &localaddr, GET_SS_LEN(&localaddr), auth_connect_callback, auth, - localaddr.ss_family, GlobalSetOptions.ident_timeout); + GlobalSetOptions.ident_timeout); return 1; /* We suceed here for now */ } @@ -415,7 +468,7 @@ start_auth(struct Client *client) if(ConfigFileEntry.disable_auth == 0) start_auth_query(auth); - dlinkAdd(auth, &auth->node, &auth_poll_list); + rb_dlinkAdd(auth, &auth->node, &auth_poll_list); } /* @@ -425,23 +478,23 @@ start_auth(struct Client *client) static void timeout_auth_queries_event(void *notused) { - dlink_node *ptr; - dlink_node *next_ptr; + rb_dlink_node *ptr; + rb_dlink_node *next_ptr; struct AuthRequest *auth; - DLINK_FOREACH_SAFE(ptr, next_ptr, auth_poll_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, auth_poll_list.head) { auth = ptr->data; - if(auth->timeout < CurrentTime) + if(auth->timeout < rb_current_time()) { - if(auth->fd >= 0) - comm_close(auth->fd); + if(auth->F != NULL) + rb_close(auth->F); if(IsDoingAuth(auth)) { ClearAuth(auth); - ++ServerStats->is_abad; + ++ServerStats.is_abad; sendheader(auth->client, REPORT_FAIL_ID); auth->client->localClient->auth_request = NULL; } @@ -452,14 +505,14 @@ timeout_auth_queries_event(void *notused) sendheader(auth->client, REPORT_FAIL_DNS); } - auth->client->localClient->lasttime = CurrentTime; + auth->client->localClient->lasttime = rb_current_time(); release_auth_client(auth); } } } /* - * auth_connect_callback() - deal with the result of comm_connect_tcp() + * auth_connect_callback() - deal with the result of rb_connect_tcp() * * If the connection failed, we simply close the auth fd and report * a failure. If the connection suceeded send the ident server a query @@ -470,45 +523,30 @@ timeout_auth_queries_event(void *notused) * problems arise. -avalon */ static void -auth_connect_callback(int fd, int error, void *data) +auth_connect_callback(rb_fde_t *F, int error, void *data) { struct AuthRequest *auth = data; - struct sockaddr_in us; - struct sockaddr_in them; char authbuf[32]; - socklen_t ulen = sizeof(struct sockaddr_in); - socklen_t tlen = sizeof(struct sockaddr_in); /* Check the error */ - if(error != COMM_OK) + if(error != RB_OK) { /* We had an error during connection :( */ auth_error(auth); return; } - if(getsockname - (auth->client->localClient->fd, (struct sockaddr *) &us, - (socklen_t *) & ulen) - || getpeername(auth->client->localClient->fd, - (struct sockaddr *) &them, (socklen_t *) & tlen)) - { - ilog(L_IOERROR, "auth get{sock,peer}name error for %s:%m", - log_client_name(auth->client, SHOW_IP)); - auth_error(auth); - return; - } - ircsnprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", - (unsigned int) ntohs(them.sin_port), (unsigned int) ntohs(us.sin_port)); + rb_snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", + auth->rport, auth->lport); - if(write(auth->fd, authbuf, strlen(authbuf)) == -1) + if(rb_write(auth->F, authbuf, strlen(authbuf)) != strlen(authbuf)) { auth_error(auth); return; } ClearAuthConnect(auth); SetAuthPending(auth); - read_auth_reply(auth->fd, auth); + read_auth_reply(auth->F, auth); } @@ -521,7 +559,7 @@ auth_connect_callback(int fd, int error, void *data) #define AUTH_BUFSIZ 128 static void -read_auth_reply(int fd, void *data) +read_auth_reply(rb_fde_t *F, void *data) { struct AuthRequest *auth = data; char *s = NULL; @@ -530,11 +568,11 @@ read_auth_reply(int fd, void *data) int count; char buf[AUTH_BUFSIZ + 1]; /* buffer to read auth reply into */ - len = read(auth->fd, buf, AUTH_BUFSIZ); + len = rb_read(F, buf, AUTH_BUFSIZ); - if(len < 0 && ignoreErrno(errno)) + if(len < 0 && rb_ignore_errno(errno)) { - comm_setselect(fd, FDLIST_IDLECLIENT, COMM_SELECT_READ, read_auth_reply, auth, 0); + rb_setselect(F, RB_SELECT_READ, read_auth_reply, auth); return; } @@ -565,20 +603,20 @@ read_auth_reply(int fd, void *data) } } - comm_close(auth->fd); - auth->fd = -1; + rb_close(auth->F); + auth->F = NULL; ClearAuth(auth); if(s == NULL) { - ++ServerStats->is_abad; + ++ServerStats.is_abad; strcpy(auth->client->username, "unknown"); sendheader(auth->client, REPORT_FAIL_ID); } else { sendheader(auth->client, REPORT_FIN_ID); - ++ServerStats->is_asuc; + ++ServerStats.is_asuc; SetGotId(auth->client); } @@ -606,9 +644,9 @@ delete_auth_queries(struct Client *target_p) if(IsDNSPending(auth)) delete_resolver_queries(&auth->dns_query); - if(auth->fd >= 0) - comm_close(auth->fd); + if(auth->F != NULL) + rb_close(auth->F); - dlinkDelete(&auth->node, &auth_poll_list); + rb_dlinkDelete(&auth->node, &auth_poll_list); free_auth_request(auth); }