Ejemplo n.º 1
0
Archivo: dns.c Proyecto: ahf/charybdis
/* Callback from gethost_byname_type */
static void
handle_lookup_ip_reply(void *data, struct DNSReply *reply)
{
	struct dns_query *query = data;
	char ip[HOSTIPLEN] = "*";

	if(query == NULL)
	{
		/* Shouldn't happen */
		warn_opers(L_CRIT, "DNS: handle_lookup_ip_reply: query == NULL!");
		exit(EX_DNS_ERROR);
	}

	if(reply == NULL)
		goto end;

	switch(query->type)
	{
	case QUERY_A:
		if(GET_SS_FAMILY(&reply->addr) == AF_INET)
			rb_inet_ntop_sock((struct sockaddr *)&reply->addr, ip, sizeof(ip));
		break;
	case QUERY_AAAA:
		if(GET_SS_FAMILY(&reply->addr) == AF_INET6)
		{
			rb_inet_ntop_sock((struct sockaddr *)&reply->addr, ip, sizeof(ip));
			if(ip[0] == ':')
			{
				memmove(&ip[1], ip, strlen(ip));
				ip[0] = '0';
			}
		}
		break;
	default:
		warn_opers(L_CRIT, "DNS: handle_lookup_ip_reply: unknown query type %d",
				query->type);
		exit(EX_DNS_ERROR);
	}

end:
	if(query->callback)
		query->callback(ip, ip[0] != '*', query->type, query->data);

	rb_free(query);
}
Ejemplo n.º 2
0
/*
 * add_connection - creates a client which has just connected to us on
 * the given fd. The sockhost field is initialized with the ip# of the host.
 * The client is sent to the auth module for verification, and not put in
 * any client list yet.
 */
static void
add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, struct sockaddr *lai)
{
	struct Client *new_client;
	s_assert(NULL != listener);

	/*
	 * get the client socket name from the socket
	 * the client has already been checked out in accept_connection
	 */
	new_client = make_client(NULL);

	if (listener->ssl)
	{
		rb_fde_t *xF[2];
		if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection") == -1)
		{
			free_client(new_client);
			return;
		}
		new_client->localClient->ssl_ctl = start_ssld_accept(F, xF[1], new_client->localClient->connid);        /* this will close F for us */
		if(new_client->localClient->ssl_ctl == NULL)
		{
			free_client(new_client);
			return;
		}
		F = xF[0];
		SetSSL(new_client);
	}

	memcpy(&new_client->localClient->ip, sai, sizeof(struct rb_sockaddr_storage));
	memcpy(&new_client->preClient->lip, lai, sizeof(struct rb_sockaddr_storage));

	/*
	 * copy address to 'sockhost' as a string, copy it to host too
	 * so we have something valid to put into error messages...
	 */
	rb_inet_ntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost,
		sizeof(new_client->sockhost));


	rb_strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host));

	new_client->localClient->F = F;
	new_client->localClient->listener = listener;

	++listener->ref_count;

	start_auth(new_client);
}
Ejemplo n.º 3
0
static void
report_nameservers(void)
{
	int i;
	char ipaddr[HOSTIPLEN + 1];
	char buf[512];
	buf[0] = '\0';
	for(i = 0; i < irc_nscount; i++)
	{
		if(!rb_inet_ntop_sock
		   ((struct sockaddr *)&(irc_nsaddr_list[i]), ipaddr, sizeof(ipaddr)))
		{
			rb_strlcpy(ipaddr, "?", sizeof(ipaddr));
		}
		rb_snprintf_append(buf, sizeof(buf), "%s ", ipaddr);
	}
	rb_helper_write(res_helper, "A %s", buf);

}
Ejemplo n.º 4
0
Archivo: dns.c Proyecto: ahf/charybdis
void
enumerate_nameservers(uint32_t rid, const char letter)
{
	char buf[(HOSTIPLEN + 1) * IRCD_MAXNS];
	size_t s = 0;

	if (!irc_nscount)
	{
		/* Shouldn't happen */
		warn_opers(L_CRIT, "DNS: no name servers!");
		stats_error(rid, letter, "NONAMESERVERS");
		exit(EX_DNS_ERROR);
	}

	for(int i = 0; i < irc_nscount; i++)
	{
		char addr[HOSTIPLEN];
		size_t addrlen;

		rb_inet_ntop_sock((struct sockaddr *)&irc_nsaddr_list[i], addr, sizeof(addr));

		if (!addr[0])
		{
			/* Shouldn't happen */
			warn_opers(L_CRIT, "DNS: bad nameserver!");
			stats_error(rid, letter, "INVALIDNAMESERVER");
			exit(EX_DNS_ERROR);
		}

		addrlen = strlen(addr) + 1;
		(void)snprintf(&buf[s], sizeof(buf) - s, "%s ", addr);
		s += addrlen;
	}

	if(s > 0)
		buf[--s] = '\0';

	stats_result(rid, letter, "%s", buf);
}
Ejemplo n.º 5
0
struct Client *make_local_person_full(const char *nick, const char *username, const char *hostname, const char *ip, const char *realname)
{
	struct Client *client;

	client = make_client(NULL);
	rb_dlinkMoveNode(&client->localClient->tnode, &unknown_list, &lclient_list);
	client->servptr = &me;
	rb_dlinkAdd(client, &client->lnode, &client->servptr->serv->users);
	make_user(client);
	SetClient(client);

	rb_inet_pton_sock(ip, (struct sockaddr *)&client->localClient->ip);
	rb_strlcpy(client->name, nick, sizeof(client->name));
	rb_strlcpy(client->username, username, sizeof(client->username));
	rb_strlcpy(client->host, hostname, sizeof(client->host));
	rb_inet_ntop_sock((struct sockaddr *)&client->localClient->ip, client->sockhost, sizeof(client->sockhost));
	rb_strlcpy(client->info, realname, sizeof(client->info));

	add_to_client_hash(client->name, client);

	return client;
}
Ejemplo n.º 6
0
static int
eb_hostmask(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type)
{
    char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
    char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
    char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
    char src_ip4host[NICKLEN + USERLEN + HOSTLEN + 6];
    struct sockaddr_in ip4;
    char *s = src_host, *s2 = src_iphost, *s3 = NULL, *s4 = NULL;

    sprintf(src_host, "%s!%s@%s", client_p->name, client_p->username, client_p->host);
    sprintf(src_iphost, "%s!%s@%s", client_p->name, client_p->username, client_p->sockhost);

    /* handle hostmangling if necessary */
    if (client_p->localClient->mangledhost != NULL)
    {
        if (!strcmp(client_p->host, client_p->localClient->mangledhost))
            sprintf(src_althost, "%s!%s@%s", client_p->name, client_p->username, client_p->orighost);
        else if (!IsDynSpoof(client_p))
            sprintf(src_althost, "%s!%s@%s", client_p->name, client_p->username, client_p->localClient->mangledhost);

        s3 = src_althost;
    }

#ifdef RB_IPV6
    /* handle Teredo if necessary */
    if (client_p->localClient->ip.ss_family == AF_INET6 && ipv4_from_ipv6((const struct sockaddr_in6 *) &client_p->localClient->ip, &ip4))
    {
        sprintf(src_ip4host, "%s!%s@", client_p->name, client_p->username);
        s4 = src_ip4host + strlen(src_ip4host);
        rb_inet_ntop_sock((struct sockaddr *)&ip4,
                          s4, src_ip4host + sizeof src_ip4host - s4);
        s4 = src_ip4host;
    }
#endif

    return match(banstr, s) || match(banstr, s2) || (s3 != NULL && match(banstr, s3)) || (s4 != NULL && match(banstr, s4)) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
}
Ejemplo n.º 7
0
/*
 * add_connection - creates a client which has just connected to us on 
 * the given fd. The sockhost field is initialized with the ip# of the host.
 * The client is sent to the auth module for verification, and not put in
 * any client list yet.
 */
static void
add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, struct sockaddr *lai, void *ssl_ctl)
{
	struct Client *new_client;
	s_assert(NULL != listener);

	/* 
	 * get the client socket name from the socket
	 * the client has already been checked out in accept_connection
	 */
	new_client = make_client(NULL);

	memcpy(&new_client->localClient->ip, sai, sizeof(struct rb_sockaddr_storage));
	memcpy(&new_client->preClient->lip, lai, sizeof(struct rb_sockaddr_storage));

	/* 
	 * copy address to 'sockhost' as a string, copy it to host too
	 * so we have something valid to put into error messages...
	 */
	rb_inet_ntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost, 
		sizeof(new_client->sockhost));


	rb_strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host));

	new_client->localClient->F = F;
	add_to_cli_fd_hash(new_client);
	new_client->localClient->listener = listener;
	new_client->localClient->ssl_ctl = ssl_ctl;
	if(ssl_ctl != NULL || rb_fd_ssl(F))
		SetSSL(new_client);

	++listener->ref_count;

	start_auth(new_client);
}
Ejemplo n.º 8
0
struct Client *make_remote_person_full(struct Client *server, const char *nick, const char *username, const char *hostname, const char *ip, const char *realname)
{
	struct Client *client;
	struct sockaddr addr;

	client = make_client(server);
	make_user(client);
	SetRemoteClient(client);

	client->servptr = server;
	rb_dlinkAdd(server, &server->lnode, &server->servptr->serv->users);

	rb_inet_pton_sock(ip, &addr);
	rb_strlcpy(client->name, nick, sizeof(client->name));
	rb_strlcpy(client->username, username, sizeof(client->username));
	rb_strlcpy(client->host, hostname, sizeof(client->host));
	rb_inet_ntop_sock(&addr, client->sockhost, sizeof(client->sockhost));
	rb_strlcpy(client->info, realname, sizeof(client->info));

	add_to_client_hash(nick, client);
	add_to_hostname_hash(client->host, client);

	return client;
}
Ejemplo n.º 9
0
/*
 * mr_webirc - webirc message handler
 *      parv[1] = password
 *      parv[2] = fake username (we ignore this)
 *	parv[3] = fake hostname
 *	parv[4] = fake ip
 */
static void
mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct ConfItem *aconf;
	const char *encr;
	struct rb_sockaddr_storage addr;

	aconf = find_address_conf(client_p->host, client_p->sockhost,
				IsGotId(client_p) ? client_p->username : "******",
				IsGotId(client_p) ? client_p->username : "******",
				(struct sockaddr *) &client_p->localClient->ip,
				GET_SS_FAMILY(&client_p->localClient->ip), NULL);
	if (aconf == NULL || !(aconf->status & CONF_CLIENT))
		return;
	if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc."))
	{
		/* XXX */
		sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");
		return;
	}
	if (EmptyString(aconf->passwd))
	{
		sendto_one(source_p, "NOTICE * :CGI:IRC auth blocks must have a password");
		return;
	}

	if (EmptyString(parv[1]))
		encr = "";
	else if (IsConfEncrypted(aconf))
		encr = rb_crypt(parv[1], aconf->passwd);
	else
		encr = parv[1];

	if (encr == NULL || strcmp(encr, aconf->passwd))
	{
		sendto_one(source_p, "NOTICE * :CGI:IRC password incorrect");
		return;
	}

	if (rb_inet_pton_sock(parv[4], (struct sockaddr *)&addr) <= 0)
	{
		sendto_one(source_p, "NOTICE * :Invalid IP");
		return;
	}

	source_p->localClient->ip = addr;

	rb_inet_ntop_sock((struct sockaddr *)&source_p->localClient->ip, source_p->sockhost, sizeof(source_p->sockhost));

	if(strlen(parv[3]) <= HOSTLEN)
		rb_strlcpy(source_p->host, parv[3], sizeof(source_p->host));
	else
		rb_strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));

	/* Check dlines now, klines will be checked on registration */
	if((aconf = find_dline((struct sockaddr *)&source_p->localClient->ip,
			       GET_SS_FAMILY(&source_p->localClient->ip))))
	{
		if(!(aconf->status & CONF_EXEMPTDLINE))
		{
			exit_client(client_p, source_p, &me, "D-lined");
			return;
		}
	}

	sendto_one(source_p, "NOTICE * :CGI:IRC host/IP set to %s %s", parv[3], parv[4]);
}
Ejemplo n.º 10
0
static void
send_answer(void *vptr, struct DNSReply *reply)
{
	struct dns_request *req = (struct dns_request *)vptr;
	char response[64];
	int result = 0;
	int aftype = 0;
	strcpy(response, "FAILED");

	if(reply != NULL)
	{
		switch (req->revfwd)
		{
		case REQREV:
			{
				if(req->reqtype == REVIPV4)
				{
					struct sockaddr_in *ip, *ip_fwd;
					ip = (struct sockaddr_in *)&req->addr;
					ip_fwd = (struct sockaddr_in *)&reply->addr;
					aftype = 4;
					if(ip->sin_addr.s_addr != ip_fwd->sin_addr.s_addr)
					{
						result = 0;
						break;
					}
				}
#ifdef RB_IPV6
				else if(req->reqtype == REVIPV6)
				{
					struct sockaddr_in6 *ip, *ip_fwd;
					ip = (struct sockaddr_in6 *)&req->addr;
					ip_fwd = (struct sockaddr_in6 *)&reply->addr;
					aftype = 6;
					if(memcmp
					   (&ip->sin6_addr, &ip_fwd->sin6_addr,
					    sizeof(struct in6_addr)) != 0)
					{
						result = 0;
						break;
					}
				}
#endif
				else
				{
					/* uhh wut? */
					result = 0;
					break;
				}

				if(strlen(reply->h_name) < 63)
				{
					strcpy(response, reply->h_name);
					result = 1;
				}
				else
				{
					strcpy(response, "HOSTTOOLONG");
					result = 0;
				}
				break;
			}

		case REQFWD:
			{
#ifdef RB_IPV6
				if(GET_SS_FAMILY(&reply->addr) == AF_INET6)
				{
					char tmpres[65];
					rb_inet_ntop_sock((struct sockaddr *)&reply->addr,
						     tmpres, sizeof(tmpres) - 1);
					aftype = 6;
					if(*tmpres == ':')
					{
						strcpy(response, "0");
						strcat(response, tmpres);
					}
					else
						strcpy(response, tmpres);
					result = 1;
					break;
				}
				else
#endif
				if(GET_SS_FAMILY(&reply->addr) == AF_INET)
				{
					result = 1;
					aftype = 4;
					rb_inet_ntop_sock((struct sockaddr *)&reply->addr,
						     response, sizeof(response));
					break;
				}
				else
					break;
			}
		default:
			{
				exit(1);
			}
		}

	}
	rb_helper_write(res_helper, "R %s %d %d %s\n", req->reqid, result, aftype, response);
	rb_free(req);
}