#include "s_conf.h"
#include "client.h"
#include "common.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 "s_log.h"
+#include "logger.h"
#include "s_stats.h"
#include "send.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
/* This hook takes a struct Client for its argument */
memset(&auth_poll_list, 0, sizeof(auth_poll_list));
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 = rb_bh_create(sizeof(struct AuthRequest), LCLIENT_HEAP_SIZE, "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 = rb_current_time() + ConfigFileEntry.connect_timeout;
return request;
client->localClient->auth_request = NULL;
rb_dlinkDelete(&auth->node, &auth_poll_list);
free_auth_request(auth);
- if(client->localClient->F->fd > highest_fd)
- highest_fd = client->localClient->F->fd;
/*
* When a client has auth'ed, we want to start reading what it sends
* -- adrian
*/
client->localClient->allow_read = MAX_FLOOD;
- rb_setflush(client->localClient->F->fd, 1000, flood_recalc, client);
rb_dlinkAddTail(client, &client->node, &global_client_list);
- read_packet(client->localClient->F->fd, client);
+ read_packet(client->localClient->F, client);
}
/*
good = 0;
}
}
-#ifdef IPV6
+#ifdef RB_IPV6
else if(auth->client->localClient->ip.ss_family == AF_INET6)
{
struct sockaddr_in6 *ip, *ip_fwd;
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)
{
++ServerStats.is_abad;
- rb_close(auth->fd);
- auth->fd = -1;
+ rb_close(auth->F);
+ auth->F = NULL;
ClearAuth(auth);
sendheader(auth->client, REPORT_FAIL_ID);
static int
start_auth_query(struct AuthRequest *auth)
{
- struct rb_sockaddr_storage localaddr;
- socklen_t locallen = sizeof(struct rb_sockaddr_storage);
- int fd;
+ struct rb_sockaddr_storage localaddr, destaddr;
+ rb_fde_t *F;
int family;
if(IsAnyDead(auth->client))
return 0;
family = auth->client->localClient->ip.ss_family;
- if((fd = rb_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);
+ ilog_error("creating auth stream socket");
++ServerStats.is_abad;
return 0;
}
/*
* TBD: this is a pointless arbitrary limit .. we either have a socket or not. -nenolod
*/
- if((rb_get_maxconnections() - 10) < fd)
+ 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));
- rb_close(fd);
+ rb_close(F);
return 0;
}
* since the ident request must originate from that same address--
* and machines with multiple IP addresses are common now
*/
- memset(&localaddr, 0, locallen);
- getsockname(auth->client->localClient->F->fd,
- (struct sockaddr *) &localaddr, &locallen);
+ localaddr = auth->client->preClient->lip;
- 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);
- rb_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 */
}
if(auth->timeout < rb_current_time())
{
- if(auth->fd >= 0)
- rb_close(auth->fd);
+ if(auth->F != NULL)
+ rb_close(auth->F);
if(IsDoingAuth(auth))
{
* 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->F->fd, (struct sockaddr *) &us,
- (socklen_t *) & ulen)
- || getpeername(auth->client->localClient->F->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;
- }
rb_snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n",
- (unsigned int) ntohs(them.sin_port), (unsigned int) ntohs(us.sin_port));
+ 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);
}
#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;
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))
{
- rb_setselect(fd, FDLIST_IDLECLIENT, COMM_SELECT_READ, read_auth_reply, auth, 0);
+ rb_setselect(F, RB_SELECT_READ, read_auth_reply, auth);
return;
}
}
}
- rb_close(auth->fd);
- auth->fd = -1;
+ rb_close(auth->F);
+ auth->F = NULL;
ClearAuth(auth);
if(s == NULL)
if(IsDNSPending(auth))
delete_resolver_queries(&auth->dns_query);
- if(auth->fd >= 0)
- rb_close(auth->fd);
+ if(auth->F != NULL)
+ rb_close(auth->F);
rb_dlinkDelete(&auth->node, &auth_poll_list);
free_auth_request(auth);