diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-06-07 02:57:54 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-06-07 02:57:54 +0000 |
commit | 885d37630ef4b5b69c26c6eb3fc97e9cd2e35eae (patch) | |
tree | 51624b6cb5e5bb06531bc127bb1d0cd465502641 | |
parent | 193acaa853fe0f3bbf4cd8d8bccbe480088d76cc (diff) |
Allow SSL fingerprint-based server authentication
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11404 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 14 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_openssl.cpp | 14 | ||||
-rw-r--r-- | src/modules/m_spanningtree/hmac.cpp | 29 | ||||
-rw-r--r-- | src/modules/m_spanningtree/link.h | 1 | ||||
-rw-r--r-- | src/modules/m_spanningtree/netburst.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_spanningtree/server.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket.h | 9 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket1.cpp | 9 | ||||
-rw-r--r-- | src/modules/m_spanningtree/utils.cpp | 1 | ||||
-rw-r--r-- | src/modules/transport.h | 9 |
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> ¶ms) 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> ¶ms) 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 |