summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-06-07 02:57:54 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-06-07 02:57:54 +0000
commit885d37630ef4b5b69c26c6eb3fc97e9cd2e35eae (patch)
tree51624b6cb5e5bb06531bc127bb1d0cd465502641 /src
parent193acaa853fe0f3bbf4cd8d8bccbe480088d76cc (diff)
Allow SSL fingerprint-based server authentication
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11404 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp14
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp14
-rw-r--r--src/modules/m_spanningtree/hmac.cpp29
-rw-r--r--src/modules/m_spanningtree/link.h1
-rw-r--r--src/modules/m_spanningtree/netburst.cpp6
-rw-r--r--src/modules/m_spanningtree/server.cpp4
-rw-r--r--src/modules/m_spanningtree/treesocket.h9
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp9
-rw-r--r--src/modules/m_spanningtree/utils.cpp1
-rw-r--r--src/modules/transport.h9
10 files changed, 85 insertions, 11 deletions
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index c0cd05df5..1db4a84ca 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -402,6 +402,20 @@ class ModuleSSLGnuTLS : public Module
}
}
}
+ else if (strcmp("GET_FP", request->GetId()) == 0)
+ {
+ if (ISR->Sock->GetFd() > -1)
+ {
+ issl_session* session = &sessions[ISR->Sock->GetFd()];
+ if (session->sess)
+ {
+ Extensible* ext = ISR->Sock;
+ ssl_cert* certinfo;
+ if (ext->GetExt("ssl_cert",certinfo))
+ return certinfo->GetFingerprint().c_str();
+ }
+ }
+ }
return NULL;
}
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index 53a0e241f..f468e3c53 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -407,6 +407,20 @@ class ModuleSSLOpenSSL : public Module
return "OK";
}
}
+ else if (strcmp("GET_FP", request->GetId()) == 0)
+ {
+ if (ISR->Sock->GetFd() > -1)
+ {
+ issl_session* session = &sessions[ISR->Sock->GetFd()];
+ if (session->sess)
+ {
+ Extensible* ext = ISR->Sock;
+ ssl_cert* certinfo;
+ if (ext->GetExt("ssl_cert",certinfo))
+ return certinfo->GetFingerprint().c_str();
+ }
+ }
+ }
return NULL;
}
diff --git a/src/modules/m_spanningtree/hmac.cpp b/src/modules/m_spanningtree/hmac.cpp
index 31f384c63..50b7db9df 100644
--- a/src/modules/m_spanningtree/hmac.cpp
+++ b/src/modules/m_spanningtree/hmac.cpp
@@ -128,16 +128,33 @@ std::string TreeSocket::RandString(unsigned int ilength)
return out;
}
-bool TreeSocket::ComparePass(const std::string &ours, const std::string &theirs)
+bool TreeSocket::ComparePass(const Link& link, const std::string &theirs)
{
- if (Utils->ChallengeResponse && !ourchallenge.empty() && !theirchallenge.empty())
+ this->auth_fingerprint = !link.Fingerprint.empty();
+ this->auth_challenge = !ourchallenge.empty() && !theirchallenge.empty();
+
+ const char* fp = NULL;
+ if (GetHook())
+ fp = BufferedSocketFingerprintRequest(this, Utils->Creator, GetHook()).Send();
+
+ if (fp)
+ ServerInstance->Logs->Log("m_spanningtree", DEFAULT, std::string("Server SSL fingerprint ") + fp);
+
+ if (auth_fingerprint)
+ {
+ /* Require fingerprint to exist and match */
+ if (!fp || link.Fingerprint != std::string(fp))
+ return false;
+ }
+
+ if (auth_challenge)
{
- std::string our_hmac = this->MakePass(ours, ourchallenge);
+ std::string our_hmac = MakePass(link.RecvPass, ourchallenge);
/* Straight string compare of hashes */
return our_hmac == theirs;
}
- else
- /* Straight string compare of plaintext */
- return ours == theirs;
+
+ /* Straight string compare of plaintext */
+ return link.RecvPass == theirs;
}
diff --git a/src/modules/m_spanningtree/link.h b/src/modules/m_spanningtree/link.h
index 6883f7bbb..4805f978c 100644
--- a/src/modules/m_spanningtree/link.h
+++ b/src/modules/m_spanningtree/link.h
@@ -28,6 +28,7 @@ class Link : public classbase
int Port;
std::string SendPass;
std::string RecvPass;
+ std::string Fingerprint;
std::string AllowMask;
unsigned long AutoConnect;
time_t NextConnectTime;
diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp
index e31508cb2..6d26f13fc 100644
--- a/src/modules/m_spanningtree/netburst.cpp
+++ b/src/modules/m_spanningtree/netburst.cpp
@@ -31,7 +31,11 @@ void TreeSocket::DoBurst(TreeServer* s)
std::string name = s->GetName();
std::string burst = ":" + this->ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time());
std::string endburst = ":" + this->ServerInstance->Config->GetSID() + " ENDBURST";
- this->ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s).", name.c_str(), this->GetTheirChallenge().empty() ? "plaintext password" : "SHA256-HMAC challenge-response");
+ this->ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).",
+ name.c_str(),
+ this->auth_fingerprint ? "SSL Fingerprint and " : "",
+ this->auth_challenge ? "challenge-response" : "plaintext password");
+ this->CleanNegotiationInfo();
this->WriteLine(burst);
/* send our version string */
this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" VERSION :"+this->ServerInstance->GetVersionString());
diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp
index 0d9bd0a9e..fcf3bbfa0 100644
--- a/src/modules/m_spanningtree/server.cpp
+++ b/src/modules/m_spanningtree/server.cpp
@@ -128,7 +128,7 @@ bool TreeSocket::Outbound_Reply_Server(std::deque<std::string> &params)
if (x->Name != servername && x->Name != "*") // open link allowance
continue;
- if (!ComparePass(x->RecvPass, password))
+ if (!ComparePass(*x, password))
{
this->ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
continue;
@@ -224,7 +224,7 @@ bool TreeSocket::Inbound_Server(std::deque<std::string> &params)
if (x->Name != servername && x->Name != "*") // open link allowance
continue;
- if (!ComparePass(x->RecvPass, password))
+ if (!ComparePass(*x, password))
{
this->ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
continue;
diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h
index d4def42bc..ed408b008 100644
--- a/src/modules/m_spanningtree/treesocket.h
+++ b/src/modules/m_spanningtree/treesocket.h
@@ -82,7 +82,6 @@ class TreeSocket : public BufferedSocket
int num_lost_servers; /* Servers lost in split */
time_t NextPing; /* Time when we are due to ping this server */
bool LastPingWasGood; /* Responded to last ping we sent? */
- unsigned int keylength; /* Is this still used? */
std::string ModuleList; /* Module list of other server from CAPAB */
std::map<std::string,std::string> CapKeys; /* CAPAB keys from other server */
Module* Hook; /* I/O hooking module that we're attached to for this socket */
@@ -90,6 +89,8 @@ class TreeSocket : public BufferedSocket
std::string theirchallenge; /* Challenge recv for challenge/response */
std::string OutboundPass; /* Outbound password */
bool sentcapab; /* Have sent CAPAB already */
+ bool auth_fingerprint; /* Did we auth using SSL fingerprint */
+ bool auth_challenge; /* Did we auth using challenge/response */
public:
HandshakeTimer* hstimer; /* Handshake timer, needed to work around I/O hook buffering */
@@ -128,7 +129,11 @@ class TreeSocket : public BufferedSocket
/** Compare two passwords based on authentication scheme
*/
- bool ComparePass(const std::string &ours, const std::string &theirs);
+ bool ComparePass(const Link& link, const std::string &theirs);
+
+ /** Clean up information used only during server negotiation
+ */
+ void CleanNegotiationInfo();
/** Return the module which we are hooking to for I/O encapsulation
*/
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index d0db01dec..8b6ffb60e 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -83,6 +83,15 @@ Module* TreeSocket::GetHook()
return this->Hook;
}
+void TreeSocket::CleanNegotiationInfo()
+{
+ ModuleList.clear();
+ CapKeys.clear();
+ ourchallenge.clear();
+ theirchallenge.clear();
+ OutboundPass.clear();
+}
+
TreeSocket::~TreeSocket()
{
if (Hook)
diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp
index 8bef28b26..9ae6d4d14 100644
--- a/src/modules/m_spanningtree/utils.cpp
+++ b/src/modules/m_spanningtree/utils.cpp
@@ -531,6 +531,7 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind)
L.Port = Conf->ReadInteger("link", "port", j, true);
L.SendPass = Conf->ReadValue("link", "sendpass", j);
L.RecvPass = Conf->ReadValue("link", "recvpass", j);
+ L.Fingerprint = Conf->ReadValue("link", "fingerprint", j);
L.AutoConnect = Conf->ReadInteger("link", "autoconnect", j, true);
L.HiddenFromStats = Conf->ReadFlag("link", "statshidden", j);
L.Timeout = Conf->ReadInteger("link", "timeout", j, true);
diff --git a/src/modules/transport.h b/src/modules/transport.h
index d7164fa44..db2897508 100644
--- a/src/modules/transport.h
+++ b/src/modules/transport.h
@@ -227,4 +227,13 @@ class BufferedSocketNameRequest : public ISHRequest
}
};
+class BufferedSocketFingerprintRequest : public ISHRequest
+{
+ public:
+ /** Initialize request as a fingerprint message */
+ BufferedSocketFingerprintRequest(BufferedSocket* is, Module* Me, Module* Target) : ISHRequest(Me, Target, "GET_FP", is)
+ {
+ }
+};
+
#endif