Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a usermode +R (block unauthed user messages) #33

Open
wants to merge 1 commit into
base: u2_10_12_branch
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions include/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ enum Flag
FLAG_INVISIBLE, /**< makes user invisible */
FLAG_WALLOP, /**< send wallops to them */
FLAG_DEAF, /**< Makes user deaf */
FLAG_BLOCK_UNAUTH_USERS, /**< Block msgs from unauthenticated users */
FLAG_CHSERV, /**< Disallow KICK or MODE -o on the user;
don't display channels in /whois */
FLAG_DEBUG, /**< send global debug/anti-hack info */
Expand Down Expand Up @@ -558,6 +559,8 @@ struct Client {
#define IsDead(x) HasFlag(x, FLAG_DEADSOCKET)
/** Return non-zero if the client has set mode +d (deaf). */
#define IsDeaf(x) HasFlag(x, FLAG_DEAF)
/** Return non-zero if the client has mode +R (block unauthed users). */
#define IsBlockUnauthUsers(x) HasFlag(x, FLAG_BLOCK_UNAUTH_USERS)
/** Return non-zero if the client has been IP-checked for clones. */
#define IsIPChecked(x) HasFlag(x, FLAG_IPCHECK)
/** Return non-zero if we have received an ident response for the client. */
Expand Down Expand Up @@ -608,6 +611,8 @@ struct Client {
#define SetChannelService(x) SetFlag(x, FLAG_CHSERV)
/** Mark a client as having mode +d (deaf). */
#define SetDeaf(x) SetFlag(x, FLAG_DEAF)
/** Mark a client as having mode +R (block unregistered users). */
#define SetBlockUnauthUsers(x) SetFlag(x, FLAG_BLOCK_UNAUTH_USERS)
/** Mark a client as having mode +g (debugging). */
#define SetDebug(x) SetFlag(x, FLAG_DEBUG)
/** Mark a client as having ident looked up. */
Expand Down Expand Up @@ -646,35 +651,37 @@ struct Client {
|| HasPriv(sptr, PRIV_SEE_OPERS)))

/** Clear the client's net.burst in-progress flag. */
#define ClearBurst(x) ClrFlag(x, FLAG_BURST)
#define ClearBurst(x) ClrFlag(x, FLAG_BURST)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you revise this to not touch whitespace on lines that don't have text changes?

/** Clear the client's between EOB and EOB ACK flag. */
#define ClearBurstAck(x) ClrFlag(x, FLAG_BURST_ACK)
#define ClearBurstAck(x) ClrFlag(x, FLAG_BURST_ACK)
/** Remove mode +k (channel service) from the client. */
#define ClearChannelService(x) ClrFlag(x, FLAG_CHSERV)
#define ClearChannelService(x) ClrFlag(x, FLAG_CHSERV)
/** Remove mode +d (deaf) from the client. */
#define ClearDeaf(x) ClrFlag(x, FLAG_DEAF)
#define ClearDeaf(x) ClrFlag(x, FLAG_DEAF)
/** Remove mode +R (block unregistered users) from the client. */
#define ClearBlockUnauthUsers(x) ClrFlag(x, FLAG_BLOCK_UNAUTH_USERS)
/** Remove mode +g (debugging) from the client. */
#define ClearDebug(x) ClrFlag(x, FLAG_DEBUG)
#define ClearDebug(x) ClrFlag(x, FLAG_DEBUG)
/** Remove the client's IP-checked flag. */
#define ClearIPChecked(x) ClrFlag(x, FLAG_IPCHECK)
#define ClearIPChecked(x) ClrFlag(x, FLAG_IPCHECK)
/** Remove mode +i (invisible) from the client. */
#define ClearInvisible(x) ClrFlag(x, FLAG_INVISIBLE)
#define ClearInvisible(x) ClrFlag(x, FLAG_INVISIBLE)
/** Remove mode +O (local operator) from the client. */
#define ClearLocOp(x) ClrFlag(x, FLAG_LOCOP)
#define ClearLocOp(x) ClrFlag(x, FLAG_LOCOP)
/** Remove mode +o (global operator) from the client. */
#define ClearOper(x) ClrFlag(x, FLAG_OPER)
#define ClearOper(x) ClrFlag(x, FLAG_OPER)
/** Clear the client's pending UDP ping flag. */
#define ClearUPing(x) ClrFlag(x, FLAG_UPING)
#define ClearUPing(x) ClrFlag(x, FLAG_UPING)
/** Remove mode +w (wallops) from the client. */
#define ClearWallops(x) ClrFlag(x, FLAG_WALLOP)
#define ClearWallops(x) ClrFlag(x, FLAG_WALLOP)
/** Remove mode +s (server notices) from the client. */
#define ClearServNotice(x) ClrFlag(x, FLAG_SERVNOTICE)
#define ClearServNotice(x) ClrFlag(x, FLAG_SERVNOTICE)
/** Remove mode +x (hidden host) from the client. */
#define ClearHiddenHost(x) ClrFlag(x, FLAG_HIDDENHOST)
#define ClearHiddenHost(x) ClrFlag(x, FLAG_HIDDENHOST)
/** Clear the client's pending PING flag. */
#define ClearPingSent(x) ClrFlag(x, FLAG_PINGSENT)
#define ClearPingSent(x) ClrFlag(x, FLAG_PINGSENT)
/** Clear the client's HUB flag. */
#define ClearHub(x) ClrFlag(x, FLAG_HUB)
#define ClearHub(x) ClrFlag(x, FLAG_HUB)

/* free flags */
#define FREEFLAG_SOCKET 0x0001 /**< socket needs to be freed */
Expand Down
3 changes: 3 additions & 0 deletions include/s_user.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ extern unsigned int umode_make_snomask(unsigned int oldmask, char *arg,
int what);
extern int send_supported(struct Client *cptr);

int should_block_unauth_user(struct Client *source, struct Client *dest);
int send_reply_blocked_unauth_user(struct Client *source, struct Client *dest);

#define NAMES_ALL 1 /**< List all users in channel */
#define NAMES_VIS 2 /**< List only visible users in non-secret channels */
#define NAMES_EON 4 /**< Add an 'End Of Names' reply to the end */
Expand Down
48 changes: 42 additions & 6 deletions ircd/ircd_relay.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ void relay_directed_message(struct Client* sptr, char* name, char* server, const
if (host)
*--host = '%';

if (should_block_unauth_user(sptr, acptr)) {
send_reply_blocked_unauth_user(sptr, acptr);
return;
}

if (!(is_silenced(sptr, acptr)))
sendcmdto_one(sptr, CMD_PRIVATE, acptr, "%s :%s", name, text);
}
Expand Down Expand Up @@ -374,6 +379,11 @@ void relay_directed_notice(struct Client* sptr, char* name, char* server, const
if (host)
*--host = '%';

if (should_block_unauth_user(sptr, acptr)) {
send_reply_blocked_unauth_user(sptr, acptr);
return;
}

if (!(is_silenced(sptr, acptr)))
sendcmdto_one(sptr, CMD_NOTICE, acptr, "%s :%s", name, text);
}
Expand All @@ -398,10 +408,17 @@ void relay_private_message(struct Client* sptr, const char* name, const char* te
send_reply(sptr, ERR_NOSUCHNICK, name);
return;
}

/* Note: X does silence users who flood it. */
if ((!IsChannelService(acptr) &&
check_target_limit(sptr, acptr, NULL)) ||
is_silenced(sptr, acptr))
if (!IsChannelService(acptr) && check_target_limit(sptr, acptr, NULL))
return;

if (should_block_unauth_user(sptr, acptr)) {
send_reply_blocked_unauth_user(sptr, acptr);
return;
}

if (is_silenced(sptr, acptr))
return;

/*
Expand Down Expand Up @@ -435,10 +452,18 @@ void relay_private_notice(struct Client* sptr, const char* name, const char* tex

if (0 == (acptr = FindUser(name)))
return;
if ((!IsChannelService(acptr) &&
check_target_limit(sptr, acptr, NULL)) ||
is_silenced(sptr, acptr))

if (!IsChannelService(acptr) && check_target_limit(sptr, acptr, NULL))
return;

if (should_block_unauth_user(sptr, acptr)) {
send_reply_blocked_unauth_user(sptr, acptr);
return;
}

if (is_silenced(sptr, acptr))
return;

/*
* deliver the message
*/
Expand Down Expand Up @@ -469,6 +494,12 @@ void server_relay_private_message(struct Client* sptr, const char* name, const c
text);
return;
}

if (should_block_unauth_user(sptr, acptr)) {
send_reply_blocked_unauth_user(sptr, acptr);
return;
}

if (is_silenced(sptr, acptr))
return;

Expand Down Expand Up @@ -497,6 +528,11 @@ void server_relay_private_notice(struct Client* sptr, const char* name, const ch
if (0 == (acptr = findNUser(name)) || !IsUser(acptr))
return;

if (should_block_unauth_user(sptr, acptr)) {
send_reply_blocked_unauth_user(sptr, acptr);
return;
}

if (is_silenced(sptr, acptr))
return;

Expand Down
6 changes: 6 additions & 0 deletions ircd/m_invite.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
return 0;
}

if (should_block_unauth_user(sptr, acptr))
return send_reply_blocked_unauth_user(sptr, acptr);

if (is_silenced(sptr, acptr))
return 0;

Expand Down Expand Up @@ -276,6 +279,9 @@ int ms_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
return 0;
}

if (should_block_unauth_user(sptr, acptr))
return send_reply_blocked_unauth_user(sptr, acptr);

if (is_silenced(sptr, acptr))
return 0;

Expand Down
58 changes: 47 additions & 11 deletions ircd/s_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,16 +490,17 @@ static const struct UserMode {
unsigned int flag; /**< User mode constant. */
char c; /**< Character corresponding to the mode. */
} userModeList[] = {
{ FLAG_OPER, 'o' },
{ FLAG_LOCOP, 'O' },
{ FLAG_INVISIBLE, 'i' },
{ FLAG_WALLOP, 'w' },
{ FLAG_SERVNOTICE, 's' },
{ FLAG_DEAF, 'd' },
{ FLAG_CHSERV, 'k' },
{ FLAG_DEBUG, 'g' },
{ FLAG_ACCOUNT, 'r' },
{ FLAG_HIDDENHOST, 'x' }
{ FLAG_OPER, 'o' },
{ FLAG_LOCOP, 'O' },
{ FLAG_INVISIBLE, 'i' },
{ FLAG_WALLOP, 'w' },
{ FLAG_SERVNOTICE, 's' },
{ FLAG_DEAF, 'd' },
{ FLAG_CHSERV, 'k' },
{ FLAG_DEBUG, 'g' },
{ FLAG_ACCOUNT, 'r' },
{ FLAG_BLOCK_UNAUTH_USERS, 'R' },
{ FLAG_HIDDENHOST, 'x' }
};

/** Length of #userModeList. */
Expand Down Expand Up @@ -799,9 +800,13 @@ int whisper(struct Client* source, const char* nick, const char* channel,
if (0 == membership || IsZombie(membership)) {
return send_reply(source, ERR_USERNOTINCHANNEL, cli_name(dest), chptr->chname);
}

if (should_block_unauth_user(source, dest))
return send_reply_blocked_unauth_user(source, dest);

if (is_silenced(source, dest))
return 0;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... although I think this whitespace cleanup is fine.

if (is_notice)
sendcmdto_one(source, CMD_NOTICE, dest, "%C :%s", dest, text);
else
Expand All @@ -813,6 +818,31 @@ int whisper(struct Client* source, const char* nick, const char* channel,
return 0;
}

/** Return true if the source client isn't authenticated to a registered
* username, and the dest client has mode +R (block unauthed users).
* @param[in] source Client sending the message.
* @param[in] dest Destination of the message.
*/
int should_block_unauth_user(struct Client *source, struct Client *dest)
{
// Only block regular users.
if (IsServer(source) || IsChannelService(source))
return 0;

return IsBlockUnauthUsers(dest) && !IsAccount(source);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably a little clearer and faster to write this whole function as (with line wrapping where appropriate):

return IsBlockUnauthUsers(dest) && !(IsAccount(source) || IsChannelService(source) || IsServer(source));

}

/** Sends an error message telling the source that the dest doesn't allow
* unauthed users to contact them.
* @param[in] source Client whose message was blocked.
* @param[in] dest Client who rejected the message.
*/
int send_reply_blocked_unauth_user(struct Client *source, struct Client *dest)
{
return send_reply(source, SND_EXPLICIT | ERR_NEEDREGGEDNICK,
"%s :You need to be identified to a registered account to contact this user -- you can obtain an account from %s",
cli_name(dest), feature_str(FEAT_URLREG));
}

/** Send a user mode change for \a cptr to neighboring servers.
* @param[in] cptr User whose mode is changing.
Expand Down Expand Up @@ -1056,6 +1086,12 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc,
else
ClearDeaf(sptr);
break;
case 'R':
if (what == MODE_ADD)
SetBlockUnauthUsers(sptr);
else
ClearBlockUnauthUsers(sptr);
break;
case 'k':
if (what == MODE_ADD)
SetChannelService(sptr);
Expand Down