#include "reject.h"
#include "sslproc.h"
#include "capability.h"
+#include "s_assert.h"
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned int) 0xffffffff)
void
init_builtin_capabs(void)
{
- serv_capindex = capability_index_create();
+ serv_capindex = capability_index_create("server capabilities");
+
+ /* These two are not set via CAPAB/GCAP keywords. */
+ CAP_CAP = capability_put_anonymous(serv_capindex);
+ CAP_TS6 = capability_put_anonymous(serv_capindex);
CAP_QS = capability_put(serv_capindex, "QS");
CAP_EX = capability_put(serv_capindex, "EX");
CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD");
CAP_BAN = capability_put(serv_capindex, "BAN");
CAP_MLOCK = capability_put(serv_capindex, "MLOCK");
+
+ capability_require(serv_capindex, "QS");
+ capability_require(serv_capindex, "EX");
+ capability_require(serv_capindex, "IE");
+ capability_require(serv_capindex, "ENCAP");
}
static CNCB serv_connect_callback;
struct server_conf *tmp_p;
rb_dlink_node *ptr;
int error = -1;
+ const char *encr;
s_assert(NULL != client_p);
if(client_p == NULL)
{
if(ServerConfEncrypted(tmp_p))
{
- if(!strcmp(tmp_p->passwd, rb_crypt(client_p->localClient->passwd,
- tmp_p->passwd)))
+ encr = rb_crypt(client_p->localClient->passwd,
+ tmp_p->passwd);
+ if(encr != NULL && !strcmp(tmp_p->passwd, encr))
{
server_p = tmp_p;
break;
* side effects - client is sent a list of +b, +e, or +I modes
*/
static void
-burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
+burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
rb_dlink_list *list, char flag)
{
rb_dlink_node *ptr;
{
banptr = ptr->data;
- tlen = strlen(banptr->banstr) + 1;
+ tlen = strlen(banptr->banstr) + (banptr->forward ? strlen(banptr->forward) + 1 : 0) + 1;
/* uh oh */
if(cur_len + tlen > BUFSIZE - 3)
t = buf + mlen;
}
- rb_sprintf(t, "%s ", banptr->banstr);
+ if (banptr->forward)
+ rb_sprintf(t, "%s$%s ", banptr->banstr, banptr->forward);
+ else
+ rb_sprintf(t, "%s ", banptr->banstr);
t += tlen;
cur_len += tlen;
}
/*
* burst_TS6
- *
+ *
* inputs - client (server) to send nick towards
* - client to send nick for
* output - NONE
static void
burst_TS6(struct Client *client_p)
{
- static char ubuf[12];
+ char ubuf[BUFSIZE];
struct Client *target_p;
struct Channel *chptr;
struct membership *msptr;
if(!IsPerson(target_p))
continue;
- send_umode(NULL, target_p, 0, 0, ubuf);
+ send_umode(NULL, target_p, 0, ubuf);
if(!*ubuf)
{
ubuf[0] = '+';
if(IsCapable(client_p, CAP_EUID))
sendto_one(client_p, ":%s EUID %s %d %ld %s %s %s %s %s %s %s :%s",
target_p->servptr->id, target_p->name,
- target_p->hopcount + 1,
+ target_p->hopcount + 1,
(long) target_p->tsinfo, ubuf,
target_p->username, target_p->host,
IsIPSpoof(target_p) ? "0" : target_p->sockhost,
else
sendto_one(client_p, ":%s UID %s %d %ld %s %s %s %s %s :%s",
target_p->servptr->id, target_p->name,
- target_p->hopcount + 1,
+ target_p->hopcount + 1,
(long) target_p->tsinfo, ubuf,
target_p->username, target_p->host,
IsIPSpoof(target_p) ? "0" : target_p->sockhost,
t = buf + mlen;
}
- rb_sprintf(t, "%s%s ", find_channel_status(msptr, 1),
+ rb_sprintf(t, "%s%s ", find_channel_status(msptr, 1),
use_id(msptr->client_p));
cur_len += tlen;
if(!IsServer(target_p) || !target_p->serv->caps) /* short circuit if no caps */
return msgbuf + 1;
+ rb_strlcat(msgbuf, " ", sizeof(msgbuf));
rb_strlcat(msgbuf, capability_index_list(serv_capindex, target_p->serv->caps), sizeof(msgbuf));
return msgbuf + 1;
if(IsUnknown(client_p))
{
/* the server may be linking based on certificate fingerprint now. --nenolod */
- sendto_one(client_p, "PASS %s TS %d :%s",
+ sendto_one(client_p, "PASS %s TS %d :%s",
EmptyString(server_p->spasswd) ? "*" : server_p->spasswd, TS_CURRENT, me.id);
/* pass info to new server */
if((rb_dlink_list_length(&lclient_list) + rb_dlink_list_length(&serv_list)) >
(unsigned long)MaxConnectionCount)
- MaxConnectionCount = rb_dlink_list_length(&lclient_list) +
+ MaxConnectionCount = rb_dlink_list_length(&lclient_list) +
rb_dlink_list_length(&serv_list);
/* Show the real host/IP to admins */
me.id, client_p->name, client_p->id,
IsHidden(client_p) ? "(H) " : "", client_p->info);
- if(IsCapable(target_p, CAP_ENCAP) &&
- !EmptyString(client_p->serv->fullcaps))
+ if(!EmptyString(client_p->serv->fullcaps))
sendto_one(target_p, ":%s ENCAP * GCAP :%s",
client_p->id, client_p->serv->fullcaps);
}
me.name, client_p->name,
IsHidden(client_p) ? "(H) " : "", client_p->info);
- if(IsCapable(target_p, CAP_ENCAP) &&
- !EmptyString(client_p->serv->fullcaps))
+ if(!EmptyString(client_p->serv->fullcaps))
sendto_one(target_p, ":%s ENCAP * GCAP :%s",
client_p->name, client_p->serv->fullcaps);
}
** there are no NICK's to be cancelled...). Of course,
** if cancellation occurs, all this info is sent anyway,
** and I guess the link dies when a read is attempted...? --msa
- **
+ **
** Note: Link cancellation to occur at this point means
** that at least two servers from my fragment are building
** up connection this other fragment at the same time, it's
target_p->name, target_p->hopcount + 1,
IsHidden(target_p) ? "(H) " : "", target_p->info);
- if(IsCapable(client_p, CAP_ENCAP) &&
- !EmptyString(target_p->serv->fullcaps))
+ if(!EmptyString(target_p->serv->fullcaps))
sendto_one(client_p, ":%s ENCAP * GCAP :%s",
get_id(target_p, client_p),
target_p->serv->fullcaps);
if(ServerConfVhosted(server_p))
{
- memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum));
+ memcpy(&myipnum, &server_p->my_ipnum, sizeof(server_p->my_ipnum));
((struct sockaddr_in *)&myipnum)->sin_port = 0;
myipnum.ss_family = server_p->aftype;
-
+
}
else if(server_p->aftype == AF_INET && ServerInfo.specific_ipv4_vhost)
{
- memcpy(&myipnum, &ServerInfo.ip, sizeof(myipnum));
+ memcpy(&myipnum, &ServerInfo.ip, sizeof(ServerInfo.ip));
((struct sockaddr_in *)&myipnum)->sin_port = 0;
myipnum.ss_family = AF_INET;
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in));
}
-
+
#ifdef RB_IPV6
else if((server_p->aftype == AF_INET6) && ServerInfo.specific_ipv6_vhost)
{
- memcpy(&myipnum, &ServerInfo.ip6, sizeof(myipnum));
+ memcpy(&myipnum, &ServerInfo.ip6, sizeof(ServerInfo.ip6));
((struct sockaddr_in6 *)&myipnum)->sin6_port = 0;
myipnum.ss_family = AF_INET6;
SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6));
if(ServerConfSSL(server_p))
{
rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
- NULL, 0, serv_connect_ssl_callback,
+ NULL, 0, serv_connect_ssl_callback,
client_p, ConfigFileEntry.connect_timeout);
}
else
rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip,
- NULL, 0, serv_connect_callback,
+ NULL, 0, serv_connect_callback,
client_p, ConfigFileEntry.connect_timeout);
return 1;
}
/*
* serv_connect() - initiate a server connection
*
- * inputs - pointer to conf
+ * inputs - pointer to conf
* - pointer to client doing the connet
* output -
* side effects -
make_server(client_p);
if(by && IsPerson(by))
{
- strcpy(client_p->serv->by, by->name);
+ rb_strlcpy(client_p->serv->by, by->name,
+ sizeof client_p->serv->by);
if(client_p->serv->user)
free_user(client_p->serv->user, NULL);
client_p->serv->user = by->user;
}
else
{
- strcpy(client_p->serv->by, "AutoConn.");
+ rb_strlcpy(client_p->serv->by, "AutoConn.",
+ sizeof client_p->serv->by);
if(client_p->serv->user)
free_user(client_p->serv->user, NULL);
client_p->serv->user = NULL;
ilog_error("rb_socketpair failed for server");
serv_connect_callback(F, RB_ERROR, data);
return;
-
+
}
del_from_cli_fd_hash(client_p);
client_p->localClient->F = xF[0];
/*
* serv_connect_callback() - complete a server connection.
- *
+ *
* This routine is called after the server connection attempt has
* completed. If unsucessful, an error is sent to ops and the client
* is closed. If sucessful, it goes through the initialisation/check
{
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
"Error connecting to %s[%s]: %s",
- client_p->name,
+ client_p->name,
"255.255.255.255",
rb_errstr(status));
ilog(L_SERVER, "Error connecting to %s[%s]: %s",
SetHandshake(client_p);
/* the server may be linking based on certificate fingerprint now. --nenolod */
- sendto_one(client_p, "PASS %s TS %d :%s",
+ sendto_one(client_p, "PASS %s TS %d :%s",
EmptyString(server_p->spasswd) ? "*" : server_p->spasswd, TS_CURRENT, me.id);
/* pass my info to the new server */
me.name,
ConfigServerHide.hidden ? "(H) " : "", me.info);
- /*
+ /*
* If we've been marked dead because a send failed, just exit
* here now and save everyone the trouble of us ever existing.
*/