#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 "send.h"
#include "hook.h"
#include "blacklist.h"
+#include "s_assert.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
}
ReportType;
-#define sendheader(c, r) sendto_one_notice(c, HeaderMessages[(r)])
+#define sendheader(c, r) sendto_one_notice(c, "%s", HeaderMessages[(r)])
static rb_dlink_list auth_poll_list;
static rb_bh *auth_heap;
release_auth_client(struct AuthRequest *auth)
{
struct Client *client = auth->client;
-
+
if(IsDNSPending(auth) || IsDoingAuth(auth))
return;
client->localClient->auth_request = NULL;
rb_dlinkDelete(&auth->node, &auth_poll_list);
- free_auth_request(auth);
+ free_auth_request(auth);
/*
* When a client has auth'ed, we want to start reading what it sends
* us. This is what read_packet() does.
* -- adrian
*/
- client->localClient->allow_read = MAX_FLOOD;
rb_dlinkAddTail(client, &client->node, &global_client_list);
read_packet(client->localClient->F, client);
}
ClearAuth(auth);
sendheader(auth->client, REPORT_FAIL_ID);
-
+
release_auth_client(auth);
}
/*
- * start_auth_query - Flag the client to show that an attempt to
+ * start_auth_query - Flag the client to show that an attempt to
* contact the ident server on
* the client's host. The connect and subsequently the socket are all put
* into 'non-blocking' mode. Should the connect or any later phase of the
start_auth_query(struct AuthRequest *auth)
{
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((F = rb_socket(family, SOCK_STREAM, 0, "ident")) == NULL)
{
sendheader(auth->client, REPORT_DO_ID);
- /*
+ /*
* get the local address of the client and bind to that to
* make the auth request. This used to be done only for
* ifdef VIRTUAL_HOST, but needs to be done for all clients
* since the ident request must originate from that same address--
* and machines with multiple IP addresses are common now
*/
- memset(&localaddr, 0, locallen);
- getsockname(rb_get_fd(auth->client->localClient->F),
- (struct sockaddr *) &localaddr, &locallen);
-
+ localaddr = auth->client->preClient->lip;
+
/* 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
- ((struct sockaddr_in *)&localaddr)->sin_port = 0;
+ {
+ 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
+ }
+ else
#endif
- ((struct sockaddr_in *)&destaddr)->sin_port = htons(113);
-
+ {
+ auth->rport = ntohs(((struct sockaddr_in *)&destaddr)->sin_port);
+ ((struct sockaddr_in *)&destaddr)->sin_port = htons(113);
+ }
+
auth->F = F;
SetAuthConnect(auth);
rb_connect_tcp(F, (struct sockaddr *)&destaddr,
(struct sockaddr *) &localaddr, GET_SS_LEN(&localaddr),
- auth_connect_callback, auth,
+ auth_connect_callback, auth,
GlobalSetOptions.ident_timeout);
return 1; /* We suceed here for now */
}
/*
* GetValidIdent - parse ident query reply from identd server
- *
+ *
* Inputs - pointer to ident buf
* Output - NULL if no valid ident found, otherwise pointer to name
* Side effects -
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);
+ int authlen;
/* Check the error */
if(error != RB_OK)
return;
}
- if(getsockname
- (rb_get_fd(auth->client->localClient->F), (struct sockaddr *) &us,
- (socklen_t *) & ulen)
- || getpeername(rb_get_fd(auth->client->localClient->F),
- (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);
+ authlen = strlen(authbuf);
- if(write(rb_get_fd(auth->F), authbuf, strlen(authbuf)) == -1)
+ if(rb_write(auth->F, authbuf, authlen) != authlen)
{
auth_error(auth);
return;
/*
- * read_auth_reply - read the reply (if any) from the ident server
+ * read_auth_reply - read the reply (if any) from the ident server
* we connected to.
* We only give it one shot, if the reply isn't good the first time
* fail the authentication entirely. --Bleep
int count;
char buf[AUTH_BUFSIZ + 1]; /* buffer to read auth reply into */
- len = read(rb_get_fd(F), buf, AUTH_BUFSIZ);
+ len = rb_read(F, buf, AUTH_BUFSIZ);
if(len < 0 && rb_ignore_errno(errno))
{
if(target_p == NULL || target_p->localClient == NULL ||
target_p->localClient->auth_request == NULL)
return;
-
+
auth = target_p->localClient->auth_request;
target_p->localClient->auth_request = NULL;
if(auth->F != NULL)
rb_close(auth->F);
-
+
rb_dlinkDelete(&auth->node, &auth_poll_list);
free_auth_request(auth);
}