/************************************************************************
* IRC - Internet Relay Chat, server/s_servauth.c
* Copyright (C) 1992 Darren Reed
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: s_servauth.c,v 1.3 2003/06/14 13:55:52 tr-ircd Exp $
*
* Changes:
* July 6, 1999 - Rewrote most of the code here. When a client connects
* to the server and passes initial socket validation checks, it
* is owned by this module (auth) which returns it to the rest of the
* server when dns and auth queries are finished. Until the client is
* released, the server does not know it exists and does not process
* any messages from it.
* --Bleep Thomas Helvey <tomh@inxpress.net>
*/
#include "struct.h"
#include "common.h"
#include "s_auth.h"
#include "event.h"
#include "fd.h" /* fdlist_add */
#include "sys.h"
#include "h.h"
#include "numeric.h"
#include "packet.h"
#include "resnew.h"
#include "s_bsd.h"
#include "s_conf.h"
#include "config.h"
#include "dh.h"
struct {
const char *message;
size_t length;
} ServerHeaderMessages[] = {
/* 123456789012345678901234567890123456789012345678901234567890 */
{"NOTICE AUTH :*** Looking up your hostname...\r\n", 46},
{"NOTICE AUTH :*** Found your hostname\r\n", 38},
{"NOTICE AUTH :*** Found your hostname, cached\r\n", 46},
{"NOTICE AUTH :*** Couldn't look up your hostname\r\n", 49},
{"NOTICE AUTH :*** Your forward and reverse DNS do not match, ignoring hostname.\r\n", 80},
{"NOTICE AUTH :*** Your hostname is too long, ignoring hostname\r\n", 63},
};
typedef enum {
REPORT_DO_DNS,
REPORT_FIN_DNS,
REPORT_FIN_DNSC,
REPORT_FAIL_DNS,
REPORT_IP_MISMATCH,
REPORT_HOST_TOOLONG,
} ReportType;
#ifdef HAVE_ENCRYPTION_ON
#define sendheader(c, r) \
if (IsSSL(c)) \
safe_SSL_write(c, ServerHeaderMessages[(r)].message, ServerHeaderMessages[(r)].length); \
else \
send((c)->fd, ServerHeaderMessages[(r)].message, ServerHeaderMessages[(r)].length, 0)
#define sendstring(c, t, l, n) \
if (IsSSL(c)) \
safe_SSL_write(c, t, l); \
else \
send((c)->fd, t, l, n);
#else
#define sendheader(c, r) send((c)->fd, ServerHeaderMessages[(r)].message, ServerHeaderMessages[(r)].length, 0)
#define sendstring(c, t, l, n) send((c)->fd, t, l, n)
#endif
/*
* lookup_dns_callback - called when resolver query finishes
* if the query resulted in a successful search, hp will contain
* a non-null pointer, otherwise hp will be null.
* set the client on it's way to a connection completion, regardless
* of success of failure
*/
static void lookup_dns_callback(void *vptr, adns_answer * reply)
{
struct Client *client_p = (struct Client *) vptr;
char *str = client_p->sockhost;
if (reply && (reply->status == adns_s_ok)) {
if (strlen(*reply->rrs.str) < HOSTLEN) {
strcpy(str, *reply->rrs.str);
sendheader(client_p, REPORT_FIN_DNS);
} else {
#ifdef IPV6
if (client_p->aftype == AF_INET6) {
if (*client_p->hostip == ':') {
strcpy(str, "0");
strcat(str, client_p->hostip);
} else {
strcpy(str, client_p->hostip);
}
strcat(str, ".");
} else
#endif
strcpy(str, client_p->hostip);
sendheader(client_p, REPORT_HOST_TOOLONG);
client_p->protoflags |= PFLAGS_NONRESOLVED;
}
} else {
#ifdef IPV6
if (client_p->aftype == AF_INET6) {
if (*client_p->hostip == ':') {
strcpy(str, "0");
strcat(str, client_p->hostip);
} else {
strcpy(str, client_p->hostip);
}
strcat(str, ".");
} else
#endif
strcpy(str, client_p->hostip);
sendheader(client_p, REPORT_FAIL_DNS);
client_p->protoflags |= PFLAGS_NONRESOLVED;
/* Used for the channelmode +N preventing
* non resolved addresses from joining */
}
MyFree(reply);
MyFree(client_p->dns_query);
client_p->dns_query = NULL;
client_p->allow_read = MAX_FLOOD_PER_SEC;
comm_setflush(client_p->fd, 1000, flood_recalc, client_p);
add_client_to_list(client_p);
read_client_packet(client_p->fd, client_p);
}
/*
* start_auth - starts auth (identd) and dns queries for a client
*/
void start_lookup(struct Client *client)
{
assert(0 != client);
if (client == NULL)
return;
client->dns_query = MyMalloc(sizeof(struct DNSQuery));
client->dns_query->ptr = client;
client->dns_query->callback = lookup_dns_callback;
sendheader(client, REPORT_DO_DNS);
/* No DNS cache now, remember? -- adrian */
adns_getaddr(&(client->ip), client->aftype, client->dns_query);
}
syntax highlighted by Code2HTML, v. 0.9.1