Compare commits

..

No commits in common. "5c01fc8bd7f859e8af13c89d705510e59cb4270f" and "492d560ee13e71dc35403fd676e58c2d5bdcf2a9" have entirely different histories.

38 changed files with 158 additions and 387 deletions

View file

@ -26,8 +26,6 @@
#include "notice.h" #include "notice.h"
#include "provider.h" #include "provider.h"
#include <netinet/tcp.h> // TCP_NODELAY
#define SELF_PID (opm_provider.id) #define SELF_PID (opm_provider.id)
#define OPM_READSIZE 128 #define OPM_READSIZE 128

View file

@ -514,7 +514,7 @@ static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_sto
request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1); request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1);
} }
build_rdns(request->queryname, sizeof request->queryname, addr, NULL); build_rdns(request->queryname, IRCD_RES_HOSTLEN + 1, addr, NULL);
request->type = T_PTR; request->type = T_PTR;
query_name(request); query_name(request);

View file

@ -344,11 +344,6 @@ listen {
/* auth {}: allow users to connect to the ircd (OLD I:) */ /* auth {}: allow users to connect to the ircd (OLD I:) */
auth { auth {
/* description: descriptive text to help recognize this auth block in
* stats i output.
*/
description = "example oper";
/* user: the user@host allowed to connect. Multiple IPv4/IPv6 user /* user: the user@host allowed to connect. Multiple IPv4/IPv6 user
* lines are permitted per auth block. This is matched against the * lines are permitted per auth block. This is matched against the
* hostname and IP address (using :: shortening for IPv6 and * hostname and IP address (using :: shortening for IPv6 and

View file

@ -41,7 +41,7 @@ static int eb_extended(const char *data, struct Client *client_p,
if (data == NULL) if (data == NULL)
return EXTBAN_INVALID; return EXTBAN_INVALID;
snprintf(buf, sizeof buf, "%s!%s@%s#%s", snprintf(buf, BUFSIZE, "%s!%s@%s#%s",
client_p->name, client_p->username, client_p->host, client_p->info); client_p->name, client_p->username, client_p->host, client_p->info);
return match(data, buf) ? EXTBAN_MATCH : EXTBAN_NOMATCH; return match(data, buf) ? EXTBAN_MATCH : EXTBAN_NOMATCH;

View file

@ -134,7 +134,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
sendto_one(source_p, form_str(RPL_TOPIC), me.name, sendto_one(source_p, form_str(RPL_TOPIC), me.name,
source_p->name, chptr->chname, chptr->topic); source_p->name, chptr->chname, chptr->topic);
sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
source_p->name, chptr->chname, chptr->topic_info, (long long)chptr->topic_time); source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time);
} }
source_p->localClient->last_join_time = rb_current_time(); source_p->localClient->last_join_time = rb_current_time();

View file

@ -106,17 +106,17 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc.")) if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc."))
{ {
/* XXX */ /* XXX */
exit_client(client_p, source_p, &me, "Not a CGI:IRC auth block"); sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");
return; return;
} }
if (EmptyString(aconf->passwd)) if (EmptyString(aconf->passwd))
{ {
exit_client(client_p, source_p, &me, "CGI:IRC auth blocks must have a password"); sendto_one(source_p, "NOTICE * :CGI:IRC auth blocks must have a password");
return; return;
} }
if (!IsSecure(source_p) && aconf->flags & CONF_FLAGS_NEED_SSL) if (!IsSecure(source_p) && aconf->flags & CONF_FLAGS_NEED_SSL)
{ {
exit_client(client_p, source_p, &me, "Your CGI:IRC block requires TLS"); sendto_one(source_p, "NOTICE * :Your CGI:IRC block requires TLS");
return; return;
} }
@ -129,13 +129,13 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
if (encr == NULL || strcmp(encr, aconf->passwd)) if (encr == NULL || strcmp(encr, aconf->passwd))
{ {
exit_client(client_p, source_p, &me, "CGI:IRC password incorrect"); sendto_one(source_p, "NOTICE * :CGI:IRC password incorrect");
return; return;
} }
if (rb_inet_pton_sock(parv[4], &addr) <= 0) if (rb_inet_pton_sock(parv[4], &addr) <= 0)
{ {
exit_client(client_p, source_p, &me, "Invalid IP"); sendto_one(source_p, "NOTICE * :Invalid IP");
return; return;
} }

View file

@ -49,7 +49,7 @@
#define NUMERIC_STR_209 "Class %s %d" #define NUMERIC_STR_209 "Class %s %d"
#define NUMERIC_STR_212 "%s %u %lu :%u" #define NUMERIC_STR_212 "%s %u %lu :%u"
#define NUMERIC_STR_213 "C %s %s %s %d %s %s" #define NUMERIC_STR_213 "C %s %s %s %d %s %s"
#define NUMERIC_STR_215 "I %s %s %s@%s %d %s :%s" #define NUMERIC_STR_215 "I %s %s %s@%s %d %s"
#define NUMERIC_STR_216 "%c %s * %s :%s%s%s" #define NUMERIC_STR_216 "%c %s * %s :%s%s%s"
#define NUMERIC_STR_217 "%c %d %s :%s" #define NUMERIC_STR_217 "%c %d %s :%s"
#define NUMERIC_STR_218 "Y %s %d %d %d %u %d.%d %d.%d %u" #define NUMERIC_STR_218 "Y %s %d %d %d %u %d.%d %d.%d %u"
@ -101,11 +101,11 @@
#define NUMERIC_STR_323 ":%s 323 %s :End of /LIST" #define NUMERIC_STR_323 ":%s 323 %s :End of /LIST"
#define NUMERIC_STR_324 ":%s 324 %s %s %s" #define NUMERIC_STR_324 ":%s 324 %s %s %s"
#define NUMERIC_STR_325 ":%s 325 %s %s %s :is the current channel mode-lock" #define NUMERIC_STR_325 ":%s 325 %s %s %s :is the current channel mode-lock"
#define NUMERIC_STR_329 ":%s 329 %s %s %lld" #define NUMERIC_STR_329 ":%s 329 %s %s %lu"
#define NUMERIC_STR_330 "%s %s :is logged in as" #define NUMERIC_STR_330 "%s %s :is logged in as"
#define NUMERIC_STR_331 ":%s 331 %s %s :No topic is set." #define NUMERIC_STR_331 ":%s 331 %s %s :No topic is set."
#define NUMERIC_STR_332 ":%s 332 %s %s :%s" #define NUMERIC_STR_332 ":%s 332 %s %s :%s"
#define NUMERIC_STR_333 ":%s 333 %s %s %s %lld" #define NUMERIC_STR_333 ":%s 333 %s %s %s %lu"
#define NUMERIC_STR_337 "%s :%s" #define NUMERIC_STR_337 "%s :%s"
#define NUMERIC_STR_338 "%s %s :actually using host" #define NUMERIC_STR_338 "%s %s :actually using host"
#define NUMERIC_STR_341 ":%s 341 %s %s %s" #define NUMERIC_STR_341 ":%s 341 %s %s %s"

View file

@ -65,7 +65,6 @@ struct ConfItem
char *passwd; /* doubles as kline reason *ugh* */ char *passwd; /* doubles as kline reason *ugh* */
char *spasswd; /* Password to send. */ char *spasswd; /* Password to send. */
char *user; /* user part of user@host */ char *user; /* user part of user@host */
char *desc; /* description */
int port; int port;
time_t hold; /* Hold action until this time (calendar time) */ time_t hold; /* Hold action until this time (calendar time) */
time_t created; /* Creation time (for klines etc) */ time_t created; /* Creation time (for klines etc) */
@ -385,7 +384,7 @@ extern int detach_conf(struct Client *);
extern struct ConfItem *find_tkline(const char *, const char *, struct sockaddr *); extern struct ConfItem *find_tkline(const char *, const char *, struct sockaddr *);
extern char *show_iline_prefix(struct Client *, struct ConfItem *, char *); extern char *show_iline_prefix(struct Client *, struct ConfItem *, char *);
extern void get_printable_conf(struct ConfItem *, extern void get_printable_conf(struct ConfItem *,
char **, char **, const char **, char **, int *, char **, char **); char **, char **, const char **, char **, int *, char **);
extern char *get_user_ban_reason(struct ConfItem *aconf); extern char *get_user_ban_reason(struct ConfItem *aconf);
extern void get_printable_kline(struct Client *, struct ConfItem *, extern void get_printable_kline(struct Client *, struct ConfItem *,
char **, char **, char **, char **); char **, char **, char **, char **);

View file

@ -40,8 +40,6 @@
#include <openssl/rsa.h> #include <openssl/rsa.h>
#endif #endif
#define MAX_TEMP_TIME (52 * 7 * 24 * 60 * 60)
struct Client; struct Client;
struct ConfItem; struct ConfItem;

View file

@ -249,7 +249,9 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
char *realban = LOCAL_COPY(banid); char *realban = LOCAL_COPY(banid);
rb_dlink_node *ptr; rb_dlink_node *ptr;
/* dont let local clients overflow the banlist */ /* dont let local clients overflow the banlist, or set redundant
* bans
*/
if(MyClient(source_p)) if(MyClient(source_p))
{ {
if((rb_dlink_list_length(&chptr->banlist) + rb_dlink_list_length(&chptr->exceptlist) + rb_dlink_list_length(&chptr->invexlist) + rb_dlink_list_length(&chptr->quietlist)) >= (unsigned long)((chptr->mode.mode & MODE_EXLIMIT) ? ConfigChannel.max_bans_large : ConfigChannel.max_bans)) if((rb_dlink_list_length(&chptr->banlist) + rb_dlink_list_length(&chptr->exceptlist) + rb_dlink_list_length(&chptr->invexlist) + rb_dlink_list_length(&chptr->quietlist)) >= (unsigned long)((chptr->mode.mode & MODE_EXLIMIT) ? ConfigChannel.max_bans_large : ConfigChannel.max_bans))
@ -258,15 +260,25 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
me.name, source_p->name, chptr->chname, realban); me.name, source_p->name, chptr->chname, realban);
return false; return false;
} }
RB_DLINK_FOREACH(ptr, list->head)
{
actualBan = ptr->data;
if(mask_match(actualBan->banstr, realban))
return false;
}
}
/* dont let remotes set duplicates */
else
{
RB_DLINK_FOREACH(ptr, list->head)
{
actualBan = ptr->data;
if(!irccmp(actualBan->banstr, realban))
return false;
}
} }
/* don't let anyone set duplicate bans */
RB_DLINK_FOREACH(ptr, list->head)
{
actualBan = ptr->data;
if(!irccmp(actualBan->banstr, realban))
return false;
}
if(IsPerson(source_p)) if(IsPerson(source_p))
sprintf(who, "%s!%s@%s", source_p->name, source_p->username, source_p->host); sprintf(who, "%s!%s@%s", source_p->name, source_p->username, source_p->host);
@ -925,9 +937,9 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
} }
if (removed && removed->forward) if (removed && removed->forward)
removed_mask_pos += snprintf(buf + old_removed_mask_pos, sizeof(buf) - old_removed_mask_pos, "%s$%s", removed->banstr, removed->forward) + 1; removed_mask_pos += snprintf(buf + old_removed_mask_pos, sizeof(buf), "%s$%s", removed->banstr, removed->forward) + 1;
else else
removed_mask_pos += rb_strlcpy(buf + old_removed_mask_pos, removed ? removed->banstr : mask, sizeof(buf)) + 1; removed_mask_pos += rb_strlcpy(buf + old_removed_mask_pos, mask, sizeof(buf)) + 1;
if (removed) if (removed)
{ {
free_ban(removed); free_ban(removed);

View file

@ -1573,11 +1573,11 @@ exit_local_server(struct Client *client_p, struct Client *source_p, struct Clien
remove_dependents(client_p, source_p, from, IsPerson(from) ? newcomment : comment, comment1); remove_dependents(client_p, source_p, from, IsPerson(from) ? newcomment : comment, comment1);
sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s was connected" sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s was connected"
" for %lld seconds. %d/%d sendK/recvK.", " for %ld seconds. %d/%d sendK/recvK.",
source_p->name, (long long)(rb_current_time() - source_p->localClient->firsttime), sendk, recvk); source_p->name, (long) rb_current_time() - source_p->localClient->firsttime, sendk, recvk);
ilog(L_SERVER, "%s was connected for %lld seconds. %d/%d sendK/recvK.", ilog(L_SERVER, "%s was connected for %ld seconds. %d/%d sendK/recvK.",
source_p->name, (long long)(rb_current_time() - source_p->localClient->firsttime), sendk, recvk); source_p->name, (long) rb_current_time() - source_p->localClient->firsttime, sendk, recvk);
if(has_id(source_p)) if(has_id(source_p))
del_from_id_hash(source_p->id, source_p); del_from_id_hash(source_p->id, source_p);
@ -1844,7 +1844,7 @@ show_ip_conf(struct ConfItem *aconf, struct Client *source_p)
{ {
if(IsConfDoSpoofIp(aconf)) if(IsConfDoSpoofIp(aconf))
{ {
if(!ConfigFileEntry.hide_spoof_ips && IsOper(source_p)) if(!ConfigFileEntry.hide_spoof_ips && MyOper(source_p))
return 1; return 1;
return 0; return 0;
@ -1857,7 +1857,7 @@ int
show_ip_whowas(struct Whowas *whowas, struct Client *source_p) show_ip_whowas(struct Whowas *whowas, struct Client *source_p)
{ {
if(whowas->flags & WHOWAS_IP_SPOOFING) if(whowas->flags & WHOWAS_IP_SPOOFING)
if(ConfigFileEntry.hide_spoof_ips || !IsOper(source_p)) if(ConfigFileEntry.hide_spoof_ips || !MyOper(source_p))
return 0; return 0;
if(whowas->flags & WHOWAS_DYNSPOOF) if(whowas->flags & WHOWAS_DYNSPOOF)
if(!IsOper(source_p)) if(!IsOper(source_p))

View file

@ -723,7 +723,7 @@ show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, char *name)
void void
report_auth(struct Client *client_p) report_auth(struct Client *client_p)
{ {
char *name, *host, *user, *classname, *desc; char *name, *host, *user, *classname;
const char *pass; const char *pass;
struct AddressRec *arec; struct AddressRec *arec;
struct ConfItem *aconf; struct ConfItem *aconf;
@ -739,7 +739,7 @@ report_auth(struct Client *client_p)
continue; continue;
get_printable_conf(aconf, &name, &host, &pass, &user, &port, get_printable_conf(aconf, &name, &host, &pass, &user, &port,
&classname, &desc); &classname);
if(!EmptyString(aconf->spasswd)) if(!EmptyString(aconf->spasswd))
pass = aconf->spasswd; pass = aconf->spasswd;
@ -748,7 +748,7 @@ report_auth(struct Client *client_p)
form_str(RPL_STATSILINE), form_str(RPL_STATSILINE),
name, pass, show_iline_prefix(client_p, aconf, user), name, pass, show_iline_prefix(client_p, aconf, user),
show_ip_conf(aconf, client_p) ? host : "255.255.255.255", show_ip_conf(aconf, client_p) ? host : "255.255.255.255",
port, classname, desc); port, classname);
} }
} }

View file

@ -756,8 +756,8 @@ solanum_main(int argc, char * const argv[])
check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5); check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5);
if(server_state_foreground) if(server_state_foreground)
inotice("now running in foreground mode from %s as pid %ld ...", inotice("now running in foreground mode from %s as pid %d ...",
ConfigFileEntry.dpath, (long)getpid()); ConfigFileEntry.dpath, getpid());
rb_lib_loop(0); rb_lib_loop(0);

View file

@ -572,6 +572,8 @@ accept_sslcallback(struct Client *client_p, int status)
return 0; /* use default handler if status != RB_OK */ return 0; /* use default handler if status != RB_OK */
} }
static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n";
static int static int
accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data) accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data)
{ {
@ -581,13 +583,6 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
static time_t last_oper_notice = 0; static time_t last_oper_notice = 0;
int len; int len;
static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n";
static const unsigned char sslerrcode[] = {
// SSLv3.0 Fatal Alert: Access Denied
0x15, 0x03, 0x00, 0x00, 0x02, 0x02, 0x31
};
if(listener->ssl && (!ircd_ssl_ok || !get_ssld_count())) if(listener->ssl && (!ircd_ssl_ok || !get_ssld_count()))
{ {
rb_close(F); rb_close(F);
@ -623,11 +618,7 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
{ {
ServerStats.is_ref++; ServerStats.is_ref++;
if(listener->ssl) if(ConfigFileEntry.dline_with_reason)
{
rb_write(F, sslerrcode, sizeof(sslerrcode));
}
else if(ConfigFileEntry.dline_with_reason)
{ {
len = snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", get_user_ban_reason(aconf)); len = snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", get_user_ban_reason(aconf));
if (len >= (int)(sizeof(buf)-1)) if (len >= (int)(sizeof(buf)-1))
@ -636,14 +627,11 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
buf[sizeof(buf) - 2] = '\n'; buf[sizeof(buf) - 2] = '\n';
buf[sizeof(buf) - 1] = '\0'; buf[sizeof(buf) - 1] = '\0';
} }
rb_write(F, buf, strlen(buf));
} }
else else
{
strcpy(buf, "ERROR :You have been D-lined.\r\n"); strcpy(buf, "ERROR :You have been D-lined.\r\n");
rb_write(F, buf, strlen(buf));
}
rb_write(F, buf, strlen(buf));
rb_close(F); rb_close(F);
return 0; return 0;
} }

View file

@ -1037,9 +1037,6 @@ conf_end_auth(struct TopConf *tc)
if(yy_aconf->className) if(yy_aconf->className)
yy_tmp->className = rb_strdup(yy_aconf->className); yy_tmp->className = rb_strdup(yy_aconf->className);
if(yy_aconf->desc)
yy_tmp->desc = rb_strdup(yy_aconf->desc);
yy_tmp->flags = yy_aconf->flags; yy_tmp->flags = yy_aconf->flags;
yy_tmp->port = yy_aconf->port; yy_tmp->port = yy_aconf->port;
@ -1175,13 +1172,6 @@ conf_set_auth_spoof(void *data)
yy_aconf->flags |= CONF_FLAGS_SPOOF_IP; yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
} }
static void
conf_set_auth_desc(void *data)
{
rb_free(yy_aconf->desc);
yy_aconf->desc = rb_strdup(data);
}
static void static void
conf_set_auth_flags(void *data) conf_set_auth_flags(void *data)
{ {
@ -2328,7 +2318,7 @@ conf_report_error(const char *fmt, ...)
char msg[BUFSIZE + 1] = { 0 }; char msg[BUFSIZE + 1] = { 0 };
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(msg, sizeof msg, fmt, ap); vsnprintf(msg, BUFSIZE, fmt, ap);
va_end(ap); va_end(ap);
if (testing_conf) if (testing_conf)
@ -2348,7 +2338,7 @@ conf_report_warning(const char *fmt, ...)
char msg[BUFSIZE + 1] = { 0 }; char msg[BUFSIZE + 1] = { 0 };
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(msg, sizeof msg, fmt, ap); vsnprintf(msg, BUFSIZE, fmt, ap);
va_end(ap); va_end(ap);
if (testing_conf) if (testing_conf)
@ -2650,7 +2640,6 @@ static struct ConfEntry conf_auth_table[] =
{ "redirport", CF_INT, conf_set_auth_redir_port, 0, NULL }, { "redirport", CF_INT, conf_set_auth_redir_port, 0, NULL },
{ "flags", CF_STRING | CF_FLIST, conf_set_auth_flags, 0, NULL }, { "flags", CF_STRING | CF_FLIST, conf_set_auth_flags, 0, NULL },
{ "umodes", CF_QSTRING, conf_set_auth_umodes, 0, NULL}, { "umodes", CF_QSTRING, conf_set_auth_umodes, 0, NULL},
{ "description",CF_QSTRING, conf_set_auth_desc, 0, NULL},
{ "\0", 0, NULL, 0, NULL } { "\0", 0, NULL, 0, NULL }
}; };

View file

@ -100,7 +100,7 @@ reject_exit(void *unused)
if (ddata->aconf) if (ddata->aconf)
{ {
snprintf(dynamic_reason, sizeof dynamic_reason, form_str(ERR_YOUREBANNEDCREEP) "\r\n", snprintf(dynamic_reason, BUFSIZE, form_str(ERR_YOUREBANNEDCREEP) "\r\n",
me.name, "*", get_user_ban_reason(ddata->aconf)); me.name, "*", get_user_ban_reason(ddata->aconf));
rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason)); rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason));
@ -108,7 +108,7 @@ reject_exit(void *unused)
} }
else if (ddata->reason) else if (ddata->reason)
{ {
snprintf(dynamic_reason, sizeof dynamic_reason, ":%s 465 %s :%s\r\n", snprintf(dynamic_reason, BUFSIZE, ":%s 465 %s :%s\r\n",
me.name, "*", ddata->reason); me.name, "*", ddata->reason);
rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason)); rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason));
} }

View file

@ -154,7 +154,6 @@ free_conf(struct ConfItem *aconf)
rb_free(aconf->className); rb_free(aconf->className);
rb_free(aconf->user); rb_free(aconf->user);
rb_free(aconf->host); rb_free(aconf->host);
rb_free(aconf->desc);
if(IsConfBan(aconf)) if(IsConfBan(aconf))
operhash_delete(aconf->info.oper); operhash_delete(aconf->info.oper);
@ -1347,8 +1346,7 @@ get_oper_name(struct Client *client_p)
*/ */
void void
get_printable_conf(struct ConfItem *aconf, char **name, char **host, get_printable_conf(struct ConfItem *aconf, char **name, char **host,
const char **pass, char **user, int *port, const char **pass, char **user, int *port, char **classname)
char **classname, char **desc)
{ {
static char null[] = "<NULL>"; static char null[] = "<NULL>";
static char zero[] = "default"; static char zero[] = "default";
@ -1358,7 +1356,6 @@ get_printable_conf(struct ConfItem *aconf, char **name, char **host,
*pass = EmptyString(aconf->passwd) ? null : aconf->passwd; *pass = EmptyString(aconf->passwd) ? null : aconf->passwd;
*user = EmptyString(aconf->user) ? null : aconf->user; *user = EmptyString(aconf->user) ? null : aconf->user;
*classname = EmptyString(aconf->className) ? zero : aconf->className; *classname = EmptyString(aconf->className) ? zero : aconf->className;
*desc = CheckEmpty(aconf->desc);
*port = (int) aconf->port; *port = (int) aconf->port;
} }

View file

@ -689,51 +689,40 @@ valid_temp_time(const char *p)
while (*p) { while (*p) {
char *endp; char *endp;
int mul;
errno = 0; errno = 0;
current = strtol(p, &endp, 10); current = strtol(p, &endp, 10);
if (endp == p) if (errno == ERANGE)
return -1; return -1;
if (current < 0) if (endp == p)
return -1; return -1;
switch (*endp) { switch (*endp) {
case '\0': /* No unit was given so send it back as minutes */ case '\0': /* No unit was given so send it back as minutes */
case 'm': case 'm':
mul = 60; result += current * 60;
break; break;
case 'h': case 'h':
mul = 3600; result += current * 3600;
break; break;
case 'd': case 'd':
mul = 86400; result += current * 86400;
break; break;
case 'w': case 'w':
mul = 604800; result += current * 604800;
break; break;
default: default:
return -1; return -1;
} }
if (current > LONG_MAX / mul)
return MAX_TEMP_TIME;
current *= mul;
if (current > MAX_TEMP_TIME - result)
return MAX_TEMP_TIME;
result += current;
if (*endp == '\0') if (*endp == '\0')
break; break;
p = endp + 1; p = endp + 1;
} }
return MIN(result, MAX_TEMP_TIME); return MIN(result, 60 * 60 * 24 * 7 * 52);
} }
/* Propagated bans are expired elsewhere. */ /* Propagated bans are expired elsewhere. */

View file

@ -1640,7 +1640,7 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
if(do_qjm) if(do_qjm)
{ {
va_start(ap, format); va_start(ap, format);
vsnprintf(reason, sizeof reason, format, ap); vsnprintf(reason, 255, format, ap);
va_end(ap); va_end(ap);
sendto_common_channels_local_butone(target_p, NOCAPS, CLICAP_CHGHOST, ":%s!%s@%s QUIT :%s", sendto_common_channels_local_butone(target_p, NOCAPS, CLICAP_CHGHOST, ":%s!%s@%s QUIT :%s",

View file

@ -26,7 +26,6 @@ else \
{ print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'` { print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'`
else else
creation="$EXTERNAL_BUILD_TIMESTAMP" creation="$EXTERNAL_BUILD_TIMESTAMP"
generation=1
fi fi
$spitshell >version.c <<!SUB!THIS! $spitshell >version.c <<!SUB!THIS!

View file

@ -112,7 +112,6 @@ whowas_add_history(struct Client *client_p, int online)
rb_strlcpy(who->hostname, client_p->host, sizeof(who->hostname)); rb_strlcpy(who->hostname, client_p->host, sizeof(who->hostname));
rb_strlcpy(who->realname, client_p->info, sizeof(who->realname)); rb_strlcpy(who->realname, client_p->info, sizeof(who->realname));
rb_strlcpy(who->sockhost, client_p->sockhost, sizeof(who->sockhost)); rb_strlcpy(who->sockhost, client_p->sockhost, sizeof(who->sockhost));
rb_strlcpy(who->suser, client_p->user->suser, sizeof(who->suser));
who->flags = (IsIPSpoof(client_p) ? WHOWAS_IP_SPOOFING : 0) | who->flags = (IsIPSpoof(client_p) ? WHOWAS_IP_SPOOFING : 0) |
(IsDynSpoof(client_p) ? WHOWAS_DYNSPOOF : 0); (IsDynSpoof(client_p) ? WHOWAS_DYNSPOOF : 0);

View file

@ -52,7 +52,7 @@ rb_crypt(const char *key, const char *salt)
return rb_sha512_crypt(key, salt); return rb_sha512_crypt(key, salt);
default: default:
return NULL; return NULL;
} };
} }
else else
return rb_des_crypt(key, salt); return rb_des_crypt(key, salt);

View file

@ -294,21 +294,23 @@ rb_event_init(void)
void void
rb_dump_events(void (*func) (char *, void *), void *ptr) rb_dump_events(void (*func) (char *, void *), void *ptr)
{ {
int len;
char buf[512]; char buf[512];
rb_dlink_node *dptr; rb_dlink_node *dptr;
struct ev_entry *ev; struct ev_entry *ev;
len = sizeof(buf);
snprintf(buf, sizeof buf, "Last event to run: %s", last_event_ran); snprintf(buf, len, "Last event to run: %s", last_event_ran);
func(buf, ptr); func(buf, ptr);
rb_strlcpy(buf, "Operation Next Execution", sizeof buf); rb_strlcpy(buf, "Operation Next Execution", len);
func(buf, ptr); func(buf, ptr);
RB_DLINK_FOREACH(dptr, event_list.head) RB_DLINK_FOREACH(dptr, event_list.head)
{ {
ev = dptr->data; ev = dptr->data;
snprintf(buf, sizeof buf, "%-28s %-4lld seconds (frequency=%d)", ev->name, snprintf(buf, len, "%-28s %-4ld seconds (frequency=%d)", ev->name,
(long long)(ev->when - rb_current_time()), (int)ev->frequency); ev->when - (long)rb_current_time(), (int)ev->frequency);
func(buf, ptr); func(buf, ptr);
} }
} }

View file

@ -172,7 +172,7 @@ int
rb_ports_supports_event(void) rb_ports_supports_event(void)
{ {
return 1; return 1;
} };
void void
rb_ports_init_event(void) rb_ports_init_event(void)

View file

@ -162,7 +162,7 @@ rb_path_to_self(void)
{ {
static char path_buf[4096]; static char path_buf[4096];
#if defined(HAVE_GETEXECNAME) #if defined(HAVE_GETEXECNAME)
const char *s = getexecname(); char *s = getexecname();
if (s == NULL) if (s == NULL)
return NULL; return NULL;
realpath(s, path_buf); realpath(s, path_buf);

View file

@ -51,12 +51,10 @@ chm_noctcp_process(void *data_)
{ {
hook_data_privmsg_channel *data = data_; hook_data_privmsg_channel *data = data_;
/* don't waste CPU if message is already blocked */ /* don't waste CPU if message is already blocked */
if (data->approved) if (data->approved || data->msgtype == MESSAGE_TYPE_NOTICE)
return; return;
if (*data->text == '\001' && if (*data->text == '\001' && rb_strncasecmp(data->text + 1, "ACTION ", 7) && data->chptr->mode.mode & mode_noctcp)
data->chptr->mode.mode & mode_noctcp &&
!(data->msgtype == MESSAGE_TYPE_PRIVMSG && !rb_strncasecmp(data->text + 1, "ACTION ", 7)))
{ {
sendto_one_numeric(data->source_p, ERR_CANNOTSENDTOCHAN, form_str(ERR_CANNOTSENDTOCHAN), data->chptr->chname); sendto_one_numeric(data->source_p, ERR_CANNOTSENDTOCHAN, form_str(ERR_CANNOTSENDTOCHAN), data->chptr->chname);
data->approved = ERR_CANNOTSENDTOCHAN; data->approved = ERR_CANNOTSENDTOCHAN;

View file

@ -374,7 +374,7 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
sendto_one(source_p, form_str(RPL_TOPICWHOTIME), sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
me.name, source_p->name, chptr->chname, me.name, source_p->name, chptr->chname,
chptr->topic_info, chptr->topic_info,
(long long)chptr->topic_time); (unsigned long)chptr->topic_time);
} }
channel_member_names(chptr, source_p, 1); channel_member_names(chptr, source_p, 1);

View file

@ -132,7 +132,7 @@ m_mode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
operspy ? channel_modes(chptr, &me) : channel_modes(chptr, source_p)); operspy ? channel_modes(chptr, &me) : channel_modes(chptr, source_p));
sendto_one(source_p, form_str(RPL_CREATIONTIME), sendto_one(source_p, form_str(RPL_CREATIONTIME),
me.name, source_p->name, parv[1], (long long)chptr->channelts); me.name, source_p->name, parv[1], chptr->channelts);
} }
else else
{ {

View file

@ -340,10 +340,20 @@ mo_masktrace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *so
const char *parv[]) const char *parv[])
{ {
char *name, *username, *hostname, *gecos; char *name, *username, *hostname, *gecos;
const char *mask;
int operspy = 0;
mask = parv[1];
name = LOCAL_COPY(parv[1]); name = LOCAL_COPY(parv[1]);
collapse(name); collapse(name);
if(IsOperSpy(source_p) && parv[1][0] == '!')
{
name++;
mask++;
operspy = 1;
}
if(parc > 2 && !EmptyString(parv[2])) if(parc > 2 && !EmptyString(parv[2]))
{ {
gecos = LOCAL_COPY(parv[2]); gecos = LOCAL_COPY(parv[2]);
@ -373,6 +383,21 @@ mo_masktrace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *so
return; return;
} }
match_masktrace(source_p, &global_client_list, username, hostname, name, gecos); if(operspy) {
if (!ConfigFileEntry.operspy_dont_care_user_info)
{
char buf[512];
rb_strlcpy(buf, mask, sizeof(buf));
if(!EmptyString(gecos)) {
rb_strlcat(buf, " ", sizeof(buf));
rb_strlcat(buf, gecos, sizeof(buf));
}
report_operspy(source_p, "MASKTRACE", buf);
}
match_masktrace(source_p, &global_client_list, username, hostname, name, gecos);
} else
match_masktrace(source_p, &lclient_list, username, hostname, name, gecos);
sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), me.name); sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), me.name);
} }

View file

@ -165,11 +165,6 @@ mo_kline(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
} }
reason = LOCAL_COPY(parv[loc]); reason = LOCAL_COPY(parv[loc]);
if(strlen(reason) > BANREASONLEN)
{
sendto_one_notice(source_p, ":K-Line reason exceeds %d characters", BANREASONLEN);
return;
}
if(parse_netmask_strict(host, NULL, NULL) == HM_ERROR) if(parse_netmask_strict(host, NULL, NULL) == HM_ERROR)
{ {
@ -239,6 +234,9 @@ mo_kline(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
aconf->port = 0; aconf->port = 0;
aconf->info.oper = operhash_add(get_oper_name(source_p)); aconf->info.oper = operhash_add(get_oper_name(source_p));
if(strlen(reason) > BANREASONLEN)
reason[BANREASONLEN] = '\0';
/* Look for an oper reason */ /* Look for an oper reason */
if((oper_reason = strchr(reason, '|')) != NULL) if((oper_reason = strchr(reason, '|')) != NULL)
{ {

View file

@ -108,7 +108,7 @@ dump_map(struct Client *client_p, struct Client *root_p, char *pbuf)
} }
frac = (1000 * rb_dlink_list_length(&root_p->serv->users) + Count.total / 2) / Count.total; frac = (1000 * rb_dlink_list_length(&root_p->serv->users) + Count.total / 2) / Count.total;
snprintf(buf + USER_COL, sizeof buf - USER_COL, snprintf(buf + USER_COL, BUFSIZE - USER_COL,
" | Users: %5lu (%2d.%1d%%)", rb_dlink_list_length(&root_p->serv->users), " | Users: %5lu (%2d.%1d%%)", rb_dlink_list_length(&root_p->serv->users),
frac / 10, frac % 10); frac / 10, frac % 10);
@ -172,7 +172,7 @@ flattened_map(struct Client *client_p)
} }
} }
snprintf(buf + USER_COL, sizeof buf - USER_COL, snprintf(buf + USER_COL, BUFSIZE - USER_COL,
" | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&me.serv->users), " | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&me.serv->users),
100 * (float) rb_dlink_list_length(&me.serv->users) / (float) Count.total); 100 * (float) rb_dlink_list_length(&me.serv->users) / (float) Count.total);
@ -210,7 +210,7 @@ flattened_map(struct Client *client_p)
} }
} }
snprintf(buf + USER_COL, sizeof buf - USER_COL, snprintf(buf + USER_COL, BUFSIZE - USER_COL,
" | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&target_p->serv->users), " | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&target_p->serv->users),
100 * (float) rb_dlink_list_length(&target_p->serv->users) / (float) Count.total); 100 * (float) rb_dlink_list_length(&target_p->serv->users) / (float) Count.total);

View file

@ -237,7 +237,7 @@ scan_umodes(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
if (mask != NULL) if (mask != NULL)
{ {
snprintf(maskbuf, sizeof maskbuf, "%s!%s@%s", snprintf(maskbuf, BUFSIZE, "%s!%s@%s",
target_p->name, target_p->username, target_p->host); target_p->name, target_p->username, target_p->host);
if (!match(mask, maskbuf)) if (!match(mask, maskbuf))

View file

@ -453,7 +453,7 @@ stats_deny (struct Client *source_p)
static void static void
stats_exempt(struct Client *source_p) stats_exempt(struct Client *source_p)
{ {
char *name, *host, *user, *classname, *desc; char *name, *host, *user, *classname;
const char *pass; const char *pass;
struct AddressRec *arec; struct AddressRec *arec;
struct ConfItem *aconf; struct ConfItem *aconf;
@ -474,7 +474,7 @@ stats_exempt(struct Client *source_p)
{ {
aconf = arec->aconf; aconf = arec->aconf;
get_printable_conf (aconf, &name, &host, &pass, get_printable_conf (aconf, &name, &host, &pass,
&user, &port, &classname, &desc); &user, &port, &classname);
sendto_one_numeric(source_p, RPL_STATSDLINE, sendto_one_numeric(source_p, RPL_STATSDLINE,
form_str(RPL_STATSDLINE), form_str(RPL_STATSDLINE),
@ -533,7 +533,7 @@ stats_auth (struct Client *source_p)
else if((ConfigFileEntry.stats_i_oper_only == 1) && !IsOperGeneral (source_p)) else if((ConfigFileEntry.stats_i_oper_only == 1) && !IsOperGeneral (source_p))
{ {
struct ConfItem *aconf; struct ConfItem *aconf;
char *name, *host, *user, *classname, *desc; char *name, *host, *user, *classname;
const char *pass = "*"; const char *pass = "*";
int port; int port;
@ -550,13 +550,13 @@ stats_auth (struct Client *source_p)
if(aconf == NULL) if(aconf == NULL)
return; return;
get_printable_conf (aconf, &name, &host, &pass, &user, &port, &classname, &desc); get_printable_conf (aconf, &name, &host, &pass, &user, &port, &classname);
if(!EmptyString(aconf->spasswd)) if(!EmptyString(aconf->spasswd))
pass = aconf->spasswd; pass = aconf->spasswd;
sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE), sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
name, pass, show_iline_prefix(source_p, aconf, user), name, pass, show_iline_prefix(source_p, aconf, user),
host, port, classname, desc); host, port, classname);
} }
/* Theyre opered, or allowed to see all auth blocks */ /* Theyre opered, or allowed to see all auth blocks */
@ -908,8 +908,8 @@ stats_ssld_foreach(void *data, pid_t pid, int cli_count, enum ssld_status status
struct Client *source_p = data; struct Client *source_p = data;
sendto_one_numeric(source_p, RPL_STATSDEBUG, sendto_one_numeric(source_p, RPL_STATSDEBUG,
"S :%ld %c %u :%s", "S :%u %c %u :%s",
(long)pid, pid,
status == SSLD_DEAD ? 'D' : (status == SSLD_SHUTDOWN ? 'S' : 'A'), status == SSLD_DEAD ? 'D' : (status == SSLD_SHUTDOWN ? 'S' : 'A'),
cli_count, cli_count,
version); version);
@ -960,8 +960,8 @@ stats_usage (struct Client *source_p)
(int) (rus.ru_stime.tv_sec % 60)); (int) (rus.ru_stime.tv_sec % 60));
sendto_one_numeric(source_p, RPL_STATSDEBUG, sendto_one_numeric(source_p, RPL_STATSDEBUG,
"R :RSS %ld ShMem %ld Data %ld Stack %ld", "R :RSS %ld ShMem %ld Data %ld Stack %ld",
rus.ru_maxrss, (long)(rus.ru_ixrss / rup), rus.ru_maxrss, (rus.ru_ixrss / rup),
(long)(rus.ru_idrss / rup), (long)(rus.ru_isrss / rup)); (rus.ru_idrss / rup), (rus.ru_isrss / rup));
sendto_one_numeric(source_p, RPL_STATSDEBUG, sendto_one_numeric(source_p, RPL_STATSDEBUG,
"R :Swaps %d Reclaims %d Faults %d", "R :Swaps %d Reclaims %d Faults %d",
(int) rus.ru_nswap, (int) rus.ru_minflt, (int) rus.ru_majflt); (int) rus.ru_nswap, (int) rus.ru_minflt, (int) rus.ru_majflt);

View file

@ -235,8 +235,7 @@ mo_testline(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE), sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
aconf->info.name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd, aconf->info.name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd,
show_iline_prefix(source_p, aconf, aconf->user), show_iline_prefix(source_p, aconf, aconf->user),
aconf->host, aconf->port, aconf->className, aconf->host, aconf->port, aconf->className);
CheckEmpty(aconf->desc));
return; return;
} }

View file

@ -173,7 +173,7 @@ m_topic(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
sendto_one(source_p, form_str(RPL_TOPICWHOTIME), sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
me.name, source_p->name, chptr->chname, me.name, source_p->name, chptr->chname,
chptr->topic_info, chptr->topic_info,
(long long)chptr->topic_time); (unsigned long)chptr->topic_time);
} }
} }
} }

View file

@ -367,12 +367,8 @@ who_global(struct Client *source_p, const char *mask, int server_oper, int opers
who_common_channel(source_p, msptr->chptr, mask, server_oper, &maxmatches, fmt); who_common_channel(source_p, msptr->chptr, mask, server_oper, &maxmatches, fmt);
} }
} }
else else if (!ConfigFileEntry.operspy_dont_care_user_info)
{ report_operspy(source_p, "WHO", mask);
maxmatches = INT_MAX;
if (!ConfigFileEntry.operspy_dont_care_user_info)
report_operspy(source_p, "WHO", mask);
}
/* second, list all matching visible clients and clear all marks /* second, list all matching visible clients and clear all marks
* on invisible clients * on invisible clients

View file

@ -44,78 +44,49 @@
#include "supported.h" #include "supported.h"
#include "logger.h" #include "logger.h"
static int
um_callerid_modinit(void)
{
user_modes['g'] = find_umode_slot();
if (!user_modes['g'])
{
ierror("um_callerid: unable to allocate usermode slot for +g; unloading module.");
return -1;
}
user_modes['G'] = find_umode_slot();
if (!user_modes['G'])
{
user_modes['g'] = 0;
ierror("um_callerid: unable to allocate usermode slot for +G; unloading module.");
return -1;
}
construct_umodebuf();
add_isupport("CALLERID", isupport_umode, "g");
return 0;
}
static void
um_callerid_moddeinit(void)
{
user_modes['g'] = 0;
user_modes['G'] = 0;
construct_umodebuf();
delete_isupport("CALLERID");
}
#define IsSetStrictCallerID(c) ((c->umodes & user_modes['g']) == user_modes['g']) #define IsSetStrictCallerID(c) ((c->umodes & user_modes['g']) == user_modes['g'])
#define IsSetRelaxedCallerID(c) ((c->umodes & user_modes['G']) == user_modes['G']) #define IsSetRelaxedCallerID(c) ((c->umodes & user_modes['G']) == user_modes['G'])
#define IsSetAnyCallerID(c) (IsSetStrictCallerID(c) || IsSetRelaxedCallerID(c)) #define IsSetAnyCallerID(c) (IsSetStrictCallerID(c) || IsSetRelaxedCallerID(c))
#define IsSetTalkThroughCallerID(c) ((c->umodes & user_modes['M']) == user_modes['M'])
static const char um_callerid_desc[] = static const char um_callerid_desc[] =
"Provides usermodes +g and +G which restrict messages from unauthorized users."; "Provides usermodes +g and +G which restrict messages from unauthorized users.";
struct CallerIDOverrideSession {
rb_dlink_node node;
struct Client *client;
time_t deadline;
};
static rb_dlink_list callerid_overriding_opers = { NULL, NULL, 0 };
struct ev_entry *expire_callerid_override_deadlines_ev = NULL;
static void
update_session_deadline(struct Client *source_p)
{
struct CallerIDOverrideSession *session_p = NULL;
rb_dlink_node *n;
RB_DLINK_FOREACH(n, callerid_overriding_opers.head)
{
struct CallerIDOverrideSession *s = n->data;
if (s->client == source_p)
{
session_p = s;
break;
}
}
if (session_p != NULL)
{
rb_dlinkDelete(&session_p->node, &callerid_overriding_opers);
}
else
{
session_p = rb_malloc(sizeof(struct CallerIDOverrideSession));
session_p->client = source_p;
}
session_p->deadline = rb_current_time() + 1800;
rb_dlinkAddTail(session_p, &session_p->node, &callerid_overriding_opers);
}
static void
expire_callerid_override_deadlines(void *unused)
{
rb_dlink_node *n, *tn;
RB_DLINK_FOREACH_SAFE(n, tn, callerid_overriding_opers.head)
{
struct CallerIDOverrideSession *session_p = n->data;
if (session_p->deadline >= rb_current_time())
{
break;
}
else
{
const char *parv[4] = {session_p->client->name, session_p->client->name, "-M", NULL};
user_mode(session_p->client, session_p->client, 3, parv);
}
}
}
static bool static bool
allow_message(struct Client *source_p, struct Client *target_p) allow_message(struct Client *source_p, struct Client *target_p)
{ {
@ -134,7 +105,7 @@ allow_message(struct Client *source_p, struct Client *target_p)
return true; return true;
/* XXX: controversial? allow opers to send through +g */ /* XXX: controversial? allow opers to send through +g */
if (IsSetTalkThroughCallerID(source_p) || MayHavePrivilege(source_p, "oper:always_message")) if (MayHavePrivilege(source_p, "oper:message"))
return true; return true;
if (accept_message(source_p, target_p)) if (accept_message(source_p, target_p))
@ -256,156 +227,11 @@ h_hdl_privmsg_user(void *vdata)
data->approved = ERR_TARGUMODEG; data->approved = ERR_TARGUMODEG;
} }
static void
check_umode_change(void *vdata)
{
hook_data_umode_changed *data = (hook_data_umode_changed *)vdata;
bool changed = false;
struct Client *source_p = data->client;
if (!MyClient(source_p))
return;
if (data->oldumodes & UMODE_OPER && !IsOper(source_p))
source_p->umodes &= ~user_modes['M'];
changed = ((data->oldumodes ^ source_p->umodes) & user_modes['M']);
if (changed && source_p->umodes & user_modes['M'])
{
if (!HasPrivilege(source_p, "oper:message"))
{
sendto_one_notice(source_p, ":*** You need oper:message privilege for +M");
source_p->umodes &= ~user_modes['M'];
return;
}
update_session_deadline(source_p);
}
else if (changed)
{
// Unsetting +M; remove the timeout session
rb_dlink_node *n, *tn;
RB_DLINK_FOREACH_SAFE(n, tn, callerid_overriding_opers.head)
{
struct CallerIDOverrideSession *session_p = n->data;
if (session_p->client != source_p)
continue;
rb_dlinkDelete(n, &callerid_overriding_opers);
rb_free(session_p);
}
}
}
static void check_priv_change(void *vdata)
{
hook_data_priv_change *data = (hook_data_priv_change*)vdata;
struct Client *source_p = data->client;
const char *fakeparv[4];
if (!MyClient(source_p))
return;
if (source_p->umodes & user_modes['M'] && !HasPrivilege(source_p, "oper:message"))
{
sendto_one_notice(source_p, ":*** You need oper:message privilege for +M");
fakeparv[0] = fakeparv[1] = source_p->name;
fakeparv[2] = "-M";
fakeparv[3] = NULL;
user_mode(source_p, source_p, 3, fakeparv);
}
}
static void
handle_client_exit(void *vdata)
{
hook_data_client_exit *data = (hook_data_client_exit *) vdata;
rb_dlink_node *n, *tn;
struct Client *source_p = data->target;
RB_DLINK_FOREACH_SAFE(n, tn, callerid_overriding_opers.head)
{
struct CallerIDOverrideSession *session_p = n->data;
if (session_p->client != source_p)
continue;
rb_dlinkDelete(n, &callerid_overriding_opers);
rb_free(session_p);
}
}
static mapi_hfn_list_av1 um_callerid_hfnlist[] = { static mapi_hfn_list_av1 um_callerid_hfnlist[] = {
{ "umode_changed", check_umode_change },
{ "priv_change", check_priv_change },
{ "invite", h_hdl_invite }, { "invite", h_hdl_invite },
{ "privmsg_user", h_hdl_privmsg_user }, { "privmsg_user", h_hdl_privmsg_user },
{ "client_exit", handle_client_exit },
{ NULL, NULL } { NULL, NULL }
}; };
static int
um_callerid_modinit(void)
{
rb_dlink_node *ptr;
user_modes['g'] = find_umode_slot();
if (!user_modes['g'])
{
ierror("um_callerid: unable to allocate usermode slot for +g; unloading module.");
return -1;
}
user_modes['G'] = find_umode_slot();
if (!user_modes['G'])
{
user_modes['g'] = 0;
ierror("um_callerid: unable to allocate usermode slot for +G; unloading module.");
return -1;
}
user_modes['M'] = find_umode_slot();
if (!user_modes['M'])
{
user_modes['g'] = 0;
user_modes['G'] = 0;
ierror("um_callerid: unable to allocate usermode slot for +M; unloading module.");
return -1;
}
construct_umodebuf();
add_isupport("CALLERID", isupport_umode, "g");
RB_DLINK_FOREACH(ptr, lclient_list.head)
{
struct Client *client_p = ptr->data;
if (IsPerson(client_p) && (client_p->umodes & user_modes['M']))
update_session_deadline(client_p);
}
expire_callerid_override_deadlines_ev = rb_event_add("expire_callerid_override_deadlines", expire_callerid_override_deadlines, NULL, 60);
return 0;
}
static void
um_callerid_moddeinit(void)
{
user_modes['g'] = 0;
user_modes['G'] = 0;
user_modes['M'] = 0;
construct_umodebuf();
delete_isupport("CALLERID");
rb_event_delete(expire_callerid_override_deadlines_ev);
}
DECLARE_MODULE_AV2(um_callerid, um_callerid_modinit, um_callerid_moddeinit, DECLARE_MODULE_AV2(um_callerid, um_callerid_modinit, um_callerid_moddeinit,
NULL, NULL, um_callerid_hfnlist, NULL, NULL, um_callerid_desc); NULL, NULL, um_callerid_hfnlist, NULL, NULL, um_callerid_desc);

View file

@ -42,47 +42,11 @@ static void valid_temp_time1(void)
is_int(52 * WEEK, t, MSG); is_int(52 * WEEK, t, MSG);
} }
static void valid_temp_time_invalid(void)
{
time_t t;
t = valid_temp_time("-2w");
is_int(-1, t, MSG);
t = valid_temp_time("hello");
is_int(-1, t, MSG);
t = valid_temp_time("m");
is_int(-1, t, MSG);
t = valid_temp_time("1w-1w");
is_int(-1, t, MSG);
}
static void valid_temp_time_overflow(void)
{
char s[100];
time_t t;
snprintf(s, sizeof s, "%" PRIuMAX "m", UINTMAX_MAX / 60 + 2);
t = valid_temp_time(s);
is_int(52 * WEEK, t, MSG);
snprintf(s, sizeof s, "%ldm", LONG_MAX / 60 + 2);
t = valid_temp_time(s);
is_int(52 * WEEK, t, MSG);
snprintf(s, sizeof s, "%ldm%ldm", LONG_MAX / 60 - 1, LONG_MAX / 60 - 1);
t = valid_temp_time(s);
is_int(52 * WEEK, t, MSG);
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
plan_lazy(); plan_lazy();
valid_temp_time1(); valid_temp_time1();
valid_temp_time_invalid();
valid_temp_time_overflow();
return 0; return 0;
} }