summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c2
-rw-r--r--src/core/hs_off.c3
-rw-r--r--src/nickserv.c14
-rw-r--r--src/protocol/inspircd11.c21
-rw-r--r--src/protocol/inspircd12.cpp21
-rw-r--r--src/protocol/unreal32.c75
-rw-r--r--src/users.c45
7 files changed, 155 insertions, 26 deletions
diff --git a/src/actions.c b/src/actions.c
index 4f2d047d2..f6b8c7675 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -181,7 +181,7 @@ void common_unban(ChannelInfo * ci, char *nick)
for (ban = ci->c->bans->entries; ban; ban = next) {
next = ban->next;
if (entry_match(ban, u->nick, u->GetIdent().c_str(), u->host, ip) ||
- entry_match(ban, u->nick, u->GetIdent().c_str(), u->vhost, ip)) {
+ entry_match(ban, u->nick, u->GetIdent().c_str(), u->GetDisplayedHost().c_str(), ip)) {
ircdproto->SendMode(whosends(ci), ci->name, "-b %s", ban->mask);
if (ircdcap->tsmode)
av[3] = ban->mask;
diff --git a/src/core/hs_off.c b/src/core/hs_off.c
index b8aabfcc2..ec83c97bc 100644
--- a/src/core/hs_off.c
+++ b/src/core/hs_off.c
@@ -32,7 +32,10 @@ class CommandHSOff : public Command
if (!vhost && !vident)
notice_lang(s_HostServ, u, HOST_NOT_ASSIGNED);
else
+ {
ircdproto->SendVhostDel(u);
+ notice_lang(s_HostServ, u, HOST_OFF);
+ }
return MOD_CONT;
}
diff --git a/src/nickserv.c b/src/nickserv.c
index 555c18de1..01c90a07e 100644
--- a/src/nickserv.c
+++ b/src/nickserv.c
@@ -949,6 +949,7 @@ int is_on_access(User * u, NickCore * nc)
unsigned i;
char *buf;
char *buf2 = NULL;
+ char *buf3 = NULL;
if (nc->access.empty())
return 0;
@@ -962,13 +963,17 @@ int is_on_access(User * u, NickCore * nc)
buf2 = new char[u->GetIdent().length() + strlen(u->vhost) + 2];
sprintf(buf2, "%s@%s", u->GetIdent().c_str(), u->vhost);
}
+ if (!u->GetCloakedHost().empty())
+ {
+ buf3 = new char[u->GetIdent().length() + u->GetCloakedHost().length() + 2];
+ sprintf(buf3, "%s@%s", u->GetIdent().c_str(), u->GetCloakedHost().c_str());
+ }
}
for (i = 0; i < nc->access.size(); i++)
{
std::string access = nc->GetAccess(i);
- if (Anope::Match(buf, access, false)
- || (ircd->vhost ? Anope::Match(buf2, access, false) : 0))
+ if (Anope::Match(buf, access, false) || (buf2 && Anope::Match(buf2, access, false)) || (buf3 && Anope::Match(buf3, access, false)))
{
delete [] buf;
if (ircd->vhost)
@@ -977,6 +982,10 @@ int is_on_access(User * u, NickCore * nc)
{
delete [] buf2;
}
+ if (!u->GetCloakedHost().empty())
+ {
+ delete [] buf3;
+ }
}
return 1;
}
@@ -985,6 +994,7 @@ int is_on_access(User * u, NickCore * nc)
if (ircd->vhost)
{
delete [] buf2;
+ delete [] buf3;
}
return 0;
}
diff --git a/src/protocol/inspircd11.c b/src/protocol/inspircd11.c
index 7d3d2f287..977f05f1e 100644
--- a/src/protocol/inspircd11.c
+++ b/src/protocol/inspircd11.c
@@ -469,7 +469,21 @@ class InspIRCdProto : public IRCDProto
}
break;
case 'x':
- if (add) user->chost = user->vhost;
+ if (add && user->vhost)
+ {
+ /* If +x is recieved then User::vhost IS the cloaked host,
+ * set the cloaked host correctly and destroy the vhost - Adam
+ */
+ user->SetCloakedHost(user->vhost);
+ delete [] user->vhost;
+ user->vhost = NULL;
+ }
+ else
+ {
+ if (user->vhost)
+ delete [] user->vhost;
+ user->vhost = NULL;
+ }
update_host(user);
}
}
@@ -489,8 +503,7 @@ class InspIRCdProto : public IRCDProto
void SendVhostDel(User *u)
{
- inspircd_cmd_chghost(u->nick, (u->mode & umodes[static_cast<int>('x')] ? u->chost.c_str() : u->host));
- notice_lang(s_HostServ, u, HOST_OFF);
+ inspircd_cmd_chghost(u->nick, (u->mode & umodes[static_cast<int>('x')] ? u->GetCloakedHost().c_str() : u->host));
if (has_chgidentmod && u->GetIdent() != u->GetVIdent())
{
@@ -1102,7 +1115,7 @@ int anope_event_nick(const char *source, int ac, const char **av)
user->CheckAuthenticationToken(av[0]);
ircdproto->ProcessUsermodes(user, 1, &av[5]);
- user->chost = av[3];
+ user->SetCloakedHost(av[3]);
}
}
} else {
diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp
index 39abcfcb7..70afbfec4 100644
--- a/src/protocol/inspircd12.cpp
+++ b/src/protocol/inspircd12.cpp
@@ -471,7 +471,21 @@ class InspIRCdProto : public IRCDProto
}
break;
case 'x':
- if (add) user->chost = user->vhost;
+ if (add && user->vhost)
+ {
+ /* If +x is recieved then User::vhost IS the cloaked host,
+ * set the cloaked host correctly and destroy the vhost - Adam
+ */
+ user->SetCloakedHost(user->vhost);
+ delete [] user->vhost;
+ user->vhost = NULL;
+ }
+ else
+ {
+ if (user->vhost)
+ delete [] user->vhost;
+ user->vhost = NULL;
+ }
update_host(user);
}
}
@@ -492,8 +506,7 @@ class InspIRCdProto : public IRCDProto
void SendVhostDel(User *u)
{
- inspircd_cmd_chghost(u->nick, (u->mode & umodes[static_cast<int>('x')] ? u->chost.c_str() : u->host));
- notice_lang(s_HostServ, u, HOST_OFF);
+ inspircd_cmd_chghost(u->nick, (u->mode & umodes[static_cast<int>('x')] ? u->GetCloakedHost().c_str() : u->host));
if (has_chgidentmod && u->GetIdent() != u->GetVIdent())
{
@@ -1161,7 +1174,7 @@ int anope_event_uid(const char *source, int ac, const char **av)
if (user)
{
ircdproto->ProcessUsermodes(user, 1, &av[8]);
- user->chost = av[4];
+ user->SetCloakedHost(av[4]);
}
return MOD_CONT;
diff --git a/src/protocol/unreal32.c b/src/protocol/unreal32.c
index ee97a8ca6..6bad8959e 100644
--- a/src/protocol/unreal32.c
+++ b/src/protocol/unreal32.c
@@ -575,7 +575,30 @@ class UnrealIRCdProto : public IRCDProto
user->mode &= ~UMODE_r;
}
break;
+ case 't':
+ if (add && !user->vhost && !user->GetCloakedHost().empty())
+ {
+ /* The user was introduced with a vhost as their host, so we don't
+ * know their cloaked host.. Set their vhost correctly and clear
+ * the chost so we can request it later (if needed)
+ */
+ user->SetDisplayedHost(user->GetCloakedHost());
+ user->chost.clear();
+ }
+ break;
case 'x':
+ if (add)
+ {
+ /* We don't know their cloaked host.. get it */
+ if (user->GetCloakedHost().empty())
+ send_cmd(NULL, "USERHOST :%s", user->nick);
+ }
+ else
+ {
+ if (user->vhost)
+ delete [] user->vhost;
+ user->vhost = NULL;
+ }
update_host(user);
break;
default:
@@ -603,9 +626,8 @@ class UnrealIRCdProto : public IRCDProto
void SendVhostDel(User *u)
{
- send_cmd(s_HostServ, "v %s -xt", u->nick);
- send_cmd(s_HostServ, "v %s +x", u->nick);
- notice_lang(s_HostServ, u, HOST_OFF);
+ common_svsmode(u, "-xt", NULL);
+ common_svsmode(u, "+x", NULL);
}
void SendAkill(const char *user, const char *host, const char *who, time_t when, time_t expires, const char *reason)
@@ -1187,7 +1209,25 @@ int anope_event_sethost(const char *source, int ac, const char **av)
return MOD_CONT;
}
- u->SetDisplayedHost(av[0]);
+ /* If a user has a custom host and a server splits and reconnects
+ * Unreal does not send the users cloaked host to Anope.. so we do not know it.
+ * However, they will be +t if this is the case, so we will set their vhost
+ * to the sethost value (which really is their vhost) and clear the chost.
+ * The chost will be request later (if needed) - Adam
+ */
+ if (u->mode & UMODE_t)
+ {
+ u->SetDisplayedHost(av[0]);
+ u->chost.clear();
+ }
+ /* If the new host doesn't match the real host or ip.. set it
+ * else we will not set a cloaked host, and request it later if needed
+ */
+ else if ((u->host && strcmp(av[0], u->host)) || (u->hostip && strcmp(av[0], u->hostip)))
+ {
+ u->SetCloakedHost(av[0]);
+ }
+
return MOD_CONT;
}
@@ -1365,6 +1405,32 @@ int anope_event_sdesc(const char *source, int ac, const char **av)
return MOD_CONT;
}
+int anope_event_userhost(const char *source, int ac, const char **av)
+{
+ /** Hack to get around Unreal:
+ * This is the USERHOST reply, we only send a request if we do not know the users cloaked host
+ * (they got introducted using a vhost) - Adam
+ */
+ if (ac < 2)
+ return MOD_CONT;
+
+ std::string reply = av[1];
+ std::string user = std::string(reply.begin(), std::find(reply.begin(), reply.end(), '='));
+ if (user[user.length() - 1] == '*')
+ user.erase(user.length() - 1);
+ std::string host = std::string(std::find(reply.begin(), reply.end(), '@'), reply.end());
+ host.erase(host.begin());
+
+ User *u = finduser(user.c_str());
+ if (u)
+ {
+ u->SetCloakedHost(host);
+ update_host(u);
+ }
+
+ return MOD_CONT;
+}
+
int anope_event_sjoin(const char *source, int ac, const char **av)
{
do_sjoin(source, ac, av);
@@ -1438,6 +1504,7 @@ void moduleAddIRCDMsgs() {
m = createMessage("~", anope_event_sjoin); addCoreMessage(IRCD,m);
m = createMessage("SDESC", anope_event_sdesc); addCoreMessage(IRCD,m);
m = createMessage("AG", anope_event_sdesc); addCoreMessage(IRCD,m);
+ m = createMessage("302", anope_event_userhost); addCoreMessage(IRCD,m);
/* The non token version of these is in messages.c */
m = createMessage("2", m_stats); addCoreMessage(IRCD,m);
diff --git a/src/users.c b/src/users.c
index c019c136b..1431363ae 100644
--- a/src/users.c
+++ b/src/users.c
@@ -117,19 +117,42 @@ void User::SetDisplayedHost(const std::string &shost)
update_host(this);
}
-
+/** Get the displayed vhost of a user record.
+ * @return The displayed vhost of the user, where ircd-supported, or the user's real host.
+ */
const std::string User::GetDisplayedHost() const
{
- if (ircd->vhostmode && (this->mode & ircd->vhostmode))
- return this->vhost;
- else if (ircd->vhost && this->vhost)
+ if (ircd->vhost && this->vhost)
return this->vhost;
+ else if (ircd->vhostmode && (this->mode & ircd->vhostmode) && !this->GetCloakedHost().empty())
+ return this->GetCloakedHost();
else
return this->host;
}
+/** Update the cloaked host of a user
+ * @param host The cloaked host
+ */
+void User::SetCloakedHost(const std::string &newhost)
+{
+ if (newhost.empty())
+ throw "empty host in User::SetCloakedHost";
+
+ chost = newhost;
+ if (debug)
+ alog("debug: %s changed cloaked host to %s", this->nick, newhost.c_str());
+
+ update_host(this);
+}
+/** Get the cloaked host of a user
+ * @return The cloaked host
+ */
+const std::string &User::GetCloakedHost() const
+{
+ return chost;
+}
const std::string &User::GetUID() const
{
@@ -208,7 +231,7 @@ User::~User()
{
alog("LOGUSERS: %s (%s@%s => %s) (%s) left the network (%s).",
this->nick, this->GetIdent().c_str(), this->host,
- (this->vhost ? this->vhost : "(none)"), srealname, this->server->name);
+ this->GetDisplayedHost().c_str(), srealname, this->server->name);
}
else
{
@@ -232,9 +255,9 @@ User::~User()
if (debug >= 2)
alog("debug: User::~User(): free user data");
-
+
delete [] this->host;
-
+
if (this->vhost)
delete [] this->vhost;
@@ -599,7 +622,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
user->realname = sstrdup(realname);
user->timestamp = ts;
user->my_signon = time(NULL);
- user->vhost = vhost ? sstrdup(vhost) : sstrdup(host);
+ user->SetCloakedHost(vhost);
user->SetVIdent(username);
/* We now store the user's ip in the user_ struct,
* because we will use it in serveral places -- DrStein */
@@ -693,7 +716,7 @@ User *do_nick(const char *source, const char *nick, const char *username, const
if (LogUsers) {
logrealname = normalizeBuffer(user->realname);
if (ircd->vhost) {
- alog("LOGUSERS: %s (%s@%s => %s) (%s) changed nick to %s (%s).", user->nick, user->GetIdent().c_str(), user->host, (user->vhost ? user->vhost : "(none)"), logrealname, nick, user->server->name);
+ alog("LOGUSERS: %s (%s@%s => %s) (%s) changed nick to %s (%s).", user->nick, user->GetIdent().c_str(), user->host, user->GetDisplayedHost().c_str(), logrealname, nick, user->server->name);
} else {
alog("LOGUSERS: %s (%s@%s) (%s) changed nick to %s (%s).",
user->nick, user->GetIdent().c_str(), user->host, logrealname,
@@ -979,11 +1002,11 @@ int match_usermask(const char *mask, User * user)
result = Anope::Match(user->nick, nick, false)
&& Anope::Match(user->GetIdent().c_str(), username, false)
&& (Anope::Match(user->host, host, false)
- || Anope::Match(user->vhost, host, false));
+ || Anope::Match(user->GetDisplayedHost().c_str(), host, false));
} else {
result = Anope::Match(user->GetIdent().c_str(), username, false)
&& (Anope::Match(user->host, host, false)
- || Anope::Match(user->vhost, host, false));
+ || Anope::Match(user->GetDisplayedHost().c_str(), host, false));
}
delete [] mask2;