2 * charybdis: A slightly useful ircd.
3 * blacklist.c: Manages DNS blacklist entries and lookups
5 * Copyright (C) 2006 charybdis development team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
32 #include "blacklist.h"
34 dlink_list blacklist_list
= { NULL
, NULL
, 0 };
36 /* private interfaces */
37 static struct Blacklist
*find_blacklist(char *name
)
41 DLINK_FOREACH(nptr
, blacklist_list
.head
)
43 struct Blacklist
*blptr
= (struct Blacklist
*) nptr
->data
;
45 if (!irccmp(blptr
->host
, name
))
52 static void blacklist_dns_callback(void *vptr
, struct DNSReply
*reply
)
54 struct BlacklistClient
*blcptr
= (struct BlacklistClient
*) vptr
;
56 if (blcptr
== NULL
|| blcptr
->client_p
== NULL
)
59 if (blcptr
->client_p
->preClient
== NULL
)
61 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
62 "blacklist_dns_callback(): blcptr->client_p->preClient (%s) is NULL", get_client_name(blcptr
->client_p
, HIDE_IP
));
67 /* they have a blacklist entry for this client */
68 if (reply
!= NULL
&& blcptr
->client_p
->preClient
->dnsbl_listed
== NULL
)
70 blcptr
->client_p
->preClient
->dnsbl_listed
= blcptr
->blacklist
;
71 /* reference to blacklist moves from blcptr to client_p->preClient... */
74 unref_blacklist(blcptr
->blacklist
);
76 dlinkDelete(&blcptr
->node
, &blcptr
->client_p
->preClient
->dnsbl_queries
);
78 /* yes, it can probably happen... */
79 if (dlink_list_length(&blcptr
->client_p
->preClient
->dnsbl_queries
) == 0 && blcptr
->client_p
->flags
& FLAGS_SENTUSER
&& !EmptyString(blcptr
->client_p
->name
))
82 strlcpy(buf
, blcptr
->client_p
->username
, USERLEN
);
83 register_local_user(blcptr
->client_p
, blcptr
->client_p
, buf
);
89 /* XXX: no IPv6 implementation, not to concerned right now though. */
90 static void initiate_blacklist_dnsquery(struct Blacklist
*blptr
, struct Client
*client_p
)
92 struct BlacklistClient
*blcptr
= MyMalloc(sizeof(struct BlacklistClient
));
93 char buf
[IRCD_BUFSIZE
];
96 blcptr
->blacklist
= blptr
;
97 blcptr
->client_p
= client_p
;
99 blcptr
->dns_query
.ptr
= blcptr
;
100 blcptr
->dns_query
.callback
= blacklist_dns_callback
;
102 /* XXX: yes I know this is bad, I don't really care right now */
103 sscanf(client_p
->sockhost
, "%d.%d.%d.%d", &ip
[3], &ip
[2], &ip
[1], &ip
[0]);
105 /* becomes 2.0.0.127.torbl.ahbl.org or whatever */
106 ircsnprintf(buf
, IRCD_BUFSIZE
, "%d.%d.%d.%d.%s", ip
[0], ip
[1], ip
[2], ip
[3], blptr
->host
);
108 gethost_byname_type(buf
, &blcptr
->dns_query
, T_A
);
110 dlinkAdd(blcptr
, &blcptr
->node
, &client_p
->preClient
->dnsbl_queries
);
114 /* public interfaces */
115 struct Blacklist
*new_blacklist(char *name
, char *reject_reason
)
117 struct Blacklist
*blptr
;
119 if (name
== NULL
|| reject_reason
== NULL
)
122 blptr
= find_blacklist(name
);
125 blptr
= MyMalloc(sizeof(struct Blacklist
));
126 dlinkAddAlloc(blptr
, &blacklist_list
);
129 blptr
->status
&= ~CONF_ILLEGAL
;
130 strlcpy(blptr
->host
, name
, HOSTLEN
);
131 strlcpy(blptr
->reject_reason
, reject_reason
, IRCD_BUFSIZE
);
136 void unref_blacklist(struct Blacklist
*blptr
)
139 if (blptr
->status
& CONF_ILLEGAL
&& blptr
->refcount
<= 0)
141 dlinkFindDestroy(blptr
, &blacklist_list
);
146 void lookup_blacklists(struct Client
*client_p
)
150 /* We don't do IPv6 right now, sorry! */
151 if (client_p
->localClient
->ip
.ss_family
== AF_INET6
)
154 DLINK_FOREACH(nptr
, blacklist_list
.head
)
156 struct Blacklist
*blptr
= (struct Blacklist
*) nptr
->data
;
158 if (!(blptr
->status
& CONF_ILLEGAL
))
159 initiate_blacklist_dnsquery(blptr
, client_p
);
163 void abort_blacklist_queries(struct Client
*client_p
)
165 dlink_node
*ptr
, *next_ptr
;
166 struct BlacklistClient
*blcptr
;
168 if (client_p
->preClient
== NULL
)
170 DLINK_FOREACH_SAFE(ptr
, next_ptr
, client_p
->preClient
->dnsbl_queries
.head
)
173 dlinkDelete(&blcptr
->node
, &client_p
->preClient
->dnsbl_queries
);
174 unref_blacklist(blcptr
->blacklist
);
175 delete_resolver_queries(&blcptr
->dns_query
);
180 void destroy_blacklists(void)
182 dlink_node
*ptr
, *next_ptr
;
183 struct Blacklist
*blptr
;
185 DLINK_FOREACH_SAFE(ptr
, next_ptr
, blacklist_list
.head
)
188 blptr
->hits
= 0; /* keep it simple and consistent */
189 if (blptr
->refcount
> 0)
190 blptr
->status
|= CONF_ILLEGAL
;
194 dlinkDestroy(ptr
, &blacklist_list
);