| 1 |
|
/* |
| 2 |
|
* ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) |
| 3 |
|
* |
| 4 |
< |
* Copyright (c) 1997-2015 ircd-hybrid development team |
| 4 |
> |
* Copyright (c) 1997-2017 ircd-hybrid development team |
| 5 |
|
* |
| 6 |
|
* This program is free software; you can redistribute it and/or modify |
| 7 |
|
* it under the terms of the GNU General Public License as published by |
| 53 |
|
#include "mempool.h" |
| 54 |
|
|
| 55 |
|
|
| 56 |
– |
static const char *const HeaderMessages[] = |
| 57 |
– |
{ |
| 58 |
– |
":*** Looking up your hostname", |
| 59 |
– |
":*** Found your hostname", |
| 60 |
– |
":*** Couldn't look up your hostname", |
| 61 |
– |
":*** Checking Ident", |
| 62 |
– |
":*** Got Ident response", |
| 63 |
– |
":*** No Ident response", |
| 64 |
– |
":*** Your forward and reverse DNS do not match, ignoring hostname", |
| 65 |
– |
":*** Your hostname is too long, ignoring hostname" |
| 66 |
– |
}; |
| 67 |
– |
|
| 56 |
|
enum |
| 57 |
|
{ |
| 58 |
|
REPORT_DO_DNS, |
| 65 |
|
REPORT_HOST_TOOLONG |
| 66 |
|
}; |
| 67 |
|
|
| 68 |
+ |
static const char *const HeaderMessages[] = |
| 69 |
+ |
{ |
| 70 |
+ |
[REPORT_DO_DNS] = ":*** Looking up your hostname", |
| 71 |
+ |
[REPORT_FIN_DNS] = ":*** Found your hostname", |
| 72 |
+ |
[REPORT_FAIL_DNS] = ":*** Couldn't look up your hostname", |
| 73 |
+ |
[REPORT_DO_ID] = ":*** Checking Ident", |
| 74 |
+ |
[REPORT_FIN_ID] = ":*** Got Ident response", |
| 75 |
+ |
[REPORT_FAIL_ID] = ":*** No Ident response", |
| 76 |
+ |
[REPORT_IP_MISMATCH] = ":*** Your forward and reverse DNS do not match, ignoring hostname", |
| 77 |
+ |
[REPORT_HOST_TOOLONG] = ":*** Your hostname is too long, ignoring hostname" |
| 78 |
+ |
}; |
| 79 |
+ |
|
| 80 |
|
#define sendheader(c, i) sendto_one_notice((c), &me, "%s", HeaderMessages[(i)]) |
| 81 |
|
|
| 82 |
< |
static dlink_list auth_pending_list; |
| 83 |
< |
static void read_auth_reply(fde_t *, void *); |
| 82 |
> |
static dlink_list auth_list; |
| 83 |
> |
static void auth_read_reply(fde_t *, void *); |
| 84 |
|
static void auth_connect_callback(fde_t *, int, void *); |
| 85 |
|
|
| 86 |
|
|
| 90 |
|
static struct AuthRequest * |
| 91 |
|
make_auth_request(struct Client *client) |
| 92 |
|
{ |
| 93 |
< |
struct AuthRequest *const request = &client->connection->auth; |
| 93 |
> |
struct AuthRequest *const auth = &client->connection->auth; |
| 94 |
|
|
| 95 |
< |
memset(request, 0, sizeof(*request)); |
| 95 |
> |
memset(auth, 0, sizeof(*auth)); |
| 96 |
|
|
| 97 |
< |
request->client = client; |
| 98 |
< |
request->timeout = CurrentTime + CONNECTTIMEOUT; |
| 97 |
> |
auth->client = client; |
| 98 |
> |
auth->timeout = CurrentTime + CONNECTTIMEOUT; |
| 99 |
|
|
| 100 |
< |
return request; |
| 100 |
> |
return auth; |
| 101 |
|
} |
| 102 |
|
|
| 103 |
|
/* |
| 115 |
|
|
| 116 |
|
if (IsInAuth(auth)) |
| 117 |
|
{ |
| 118 |
< |
dlinkDelete(&auth->node, &auth_pending_list); |
| 118 |
> |
dlinkDelete(&auth->node, &auth_list); |
| 119 |
|
ClearInAuth(auth); |
| 120 |
|
} |
| 121 |
|
|
| 156 |
|
const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)&auth->client->connection->ip; |
| 157 |
|
const struct sockaddr_in6 *const v6dns = (const struct sockaddr_in6 *)addr; |
| 158 |
|
|
| 159 |
< |
if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)) != 0) |
| 159 |
> |
if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr))) |
| 160 |
|
{ |
| 161 |
|
sendheader(auth->client, REPORT_IP_MISMATCH); |
| 162 |
|
release_auth_client(auth); |
| 215 |
|
* identifing process fail, it is aborted and the user is given a username |
| 216 |
|
* of "unknown". |
| 217 |
|
*/ |
| 218 |
< |
static int |
| 218 |
> |
static void |
| 219 |
|
start_auth_query(struct AuthRequest *auth) |
| 220 |
|
{ |
| 221 |
|
struct irc_ssaddr localaddr; |
| 227 |
|
SOCK_STREAM, 0, "ident") == -1) |
| 228 |
|
{ |
| 229 |
|
report_error(L_ALL, "creating auth stream socket %s:%s", |
| 230 |
< |
get_client_name(auth->client, SHOW_IP), errno); |
| 230 |
> |
client_get_name(auth->client, SHOW_IP), errno); |
| 231 |
|
++ServerStats.is_abad; |
| 232 |
< |
return 0; |
| 232 |
> |
return; |
| 233 |
|
} |
| 234 |
|
|
| 235 |
+ |
SetDoingAuth(auth); |
| 236 |
|
sendheader(auth->client, REPORT_DO_ID); |
| 237 |
|
|
| 238 |
|
/* |
| 252 |
|
(struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback, |
| 253 |
|
auth, auth->client->connection->ip.ss.ss_family, |
| 254 |
|
GlobalSetOptions.ident_timeout); |
| 254 |
– |
return 1; /* We suceed here for now */ |
| 255 |
|
} |
| 256 |
|
|
| 257 |
|
/* |
| 258 |
< |
* start_auth |
| 258 |
> |
* auth_start |
| 259 |
|
* |
| 260 |
|
* inputs - pointer to client to auth |
| 261 |
|
* output - NONE |
| 262 |
|
* side effects - starts auth (identd) and dns queries for a client |
| 263 |
|
*/ |
| 264 |
|
void |
| 265 |
< |
start_auth(struct Client *client_p) |
| 265 |
> |
auth_start(struct Client *client_p) |
| 266 |
|
{ |
| 267 |
|
struct AuthRequest *const auth = make_auth_request(client_p); |
| 268 |
|
|
| 269 |
|
SetInAuth(auth); |
| 270 |
< |
dlinkAddTail(auth, &auth->node, &auth_pending_list); |
| 270 |
> |
dlinkAddTail(auth, &auth->node, &auth_list); |
| 271 |
|
|
| 272 |
|
sendheader(client_p, REPORT_DO_DNS); |
| 273 |
|
|
| 274 |
|
SetDNSPending(auth); |
| 275 |
|
|
| 276 |
|
if (ConfigGeneral.disable_auth == 0) |
| 277 |
– |
{ |
| 278 |
– |
SetDoingAuth(auth); |
| 277 |
|
start_auth_query(auth); |
| 280 |
– |
} |
| 278 |
|
|
| 279 |
|
gethost_byaddr(auth_dns_callback, auth, &client_p->connection->ip); |
| 280 |
|
} |
| 286 |
|
static void |
| 287 |
|
timeout_auth_queries_event(void *notused) |
| 288 |
|
{ |
| 289 |
< |
dlink_node *node = NULL, *node_next = NULL; |
| 289 |
> |
dlink_node *node, *node_next; |
| 290 |
|
|
| 291 |
< |
DLINK_FOREACH_SAFE(node, node_next, auth_pending_list.head) |
| 291 |
> |
DLINK_FOREACH_SAFE(node, node_next, auth_list.head) |
| 292 |
|
{ |
| 293 |
|
struct AuthRequest *auth = node->data; |
| 294 |
|
|
| 332 |
|
struct irc_ssaddr us; |
| 333 |
|
struct irc_ssaddr them; |
| 334 |
|
char authbuf[16]; |
| 335 |
+ |
ssize_t len = 0; |
| 336 |
|
socklen_t ulen = sizeof(struct irc_ssaddr); |
| 337 |
|
socklen_t tlen = sizeof(struct irc_ssaddr); |
| 338 |
|
uint16_t uport, tport; |
| 348 |
|
getpeername(auth->client->connection->fd.fd, (struct sockaddr *)&them, &tlen)) |
| 349 |
|
{ |
| 350 |
|
report_error(L_ALL, "auth get{sock,peer}name error %s:%s", |
| 351 |
< |
get_client_name(auth->client, SHOW_IP), errno); |
| 351 |
> |
client_get_name(auth->client, SHOW_IP), errno); |
| 352 |
|
auth_error(auth); |
| 353 |
|
return; |
| 354 |
|
} |
| 357 |
|
uport = ntohs(v6->sin6_port); |
| 358 |
|
v6 = (struct sockaddr_in6 *)&them; |
| 359 |
|
tport = ntohs(v6->sin6_port); |
| 362 |
– |
remove_ipv6_mapping(&us); |
| 363 |
– |
remove_ipv6_mapping(&them); |
| 360 |
|
|
| 361 |
< |
snprintf(authbuf, sizeof(authbuf), "%u, %u\r\n", tport, uport); |
| 361 |
> |
len = snprintf(authbuf, sizeof(authbuf), "%u, %u\r\n", tport, uport); |
| 362 |
|
|
| 363 |
< |
if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1) |
| 363 |
> |
if (send(fd->fd, authbuf, len, 0) != len) |
| 364 |
|
{ |
| 365 |
|
auth_error(auth); |
| 366 |
|
return; |
| 367 |
|
} |
| 368 |
|
|
| 369 |
< |
comm_setselect(fd, COMM_SELECT_READ, read_auth_reply, auth, 0); |
| 369 |
> |
comm_setselect(fd, COMM_SELECT_READ, auth_read_reply, auth, 0); |
| 370 |
|
} |
| 371 |
|
|
| 372 |
|
/** Enum used to index ident reply fields in a human-readable way. */ |
| 388 |
|
{ |
| 389 |
|
char *token = NULL, *end = NULL; |
| 390 |
|
char *vector[USERID_TOKEN_COUNT]; |
| 391 |
< |
const int count = token_vector(reply, ':', vector, USERID_TOKEN_COUNT); |
| 391 |
> |
const unsigned int count = token_vector(reply, ':', vector, USERID_TOKEN_COUNT); |
| 392 |
|
|
| 393 |
|
if (USERID_TOKEN_COUNT != count) |
| 394 |
|
return NULL; |
| 460 |
|
} |
| 461 |
|
|
| 462 |
|
/* |
| 463 |
< |
* read_auth_reply - read the reply (if any) from the ident server |
| 463 |
> |
* auth_read_reply - read the reply (if any) from the ident server |
| 464 |
|
* we connected to. |
| 465 |
|
* We only give it one shot, if the reply isn't good the first time |
| 466 |
|
* fail the authentication entirely. --Bleep |
| 467 |
|
*/ |
| 468 |
|
static void |
| 469 |
< |
read_auth_reply(fde_t *fd, void *data) |
| 469 |
> |
auth_read_reply(fde_t *fd, void *data) |
| 470 |
|
{ |
| 471 |
|
struct AuthRequest *const auth = data; |
| 472 |
|
const char *username = NULL; |
| 493 |
|
strlcpy(auth->client->username, username, sizeof(auth->client->username)); |
| 494 |
|
sendheader(auth->client, REPORT_FIN_ID); |
| 495 |
|
++ServerStats.is_asuc; |
| 496 |
< |
SetGotId(auth->client); |
| 496 |
> |
AddFlag(auth->client, FLAGS_GOTID); |
| 497 |
|
} |
| 498 |
|
|
| 499 |
|
release_auth_client(auth); |
| 500 |
|
} |
| 501 |
|
|
| 502 |
|
/* |
| 503 |
< |
* delete_auth() |
| 503 |
> |
* auth_delete() |
| 504 |
|
*/ |
| 505 |
|
void |
| 506 |
< |
delete_auth(struct AuthRequest *auth) |
| 506 |
> |
auth_delete(struct AuthRequest *auth) |
| 507 |
|
{ |
| 508 |
|
if (IsDNSPending(auth)) |
| 509 |
|
delete_resolver_queries(auth); |
| 513 |
|
|
| 514 |
|
if (IsInAuth(auth)) |
| 515 |
|
{ |
| 516 |
< |
dlinkDelete(&auth->node, &auth_pending_list); |
| 516 |
> |
dlinkDelete(&auth->node, &auth_list); |
| 517 |
|
ClearInAuth(auth); |
| 518 |
|
} |
| 519 |
|
} |