From 3e3d367c98854bd8ce6397a2163d664bf8fa7b38 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Sun, 5 Aug 2012 00:39:06 -0700 Subject: [PATCH] Finalizations, cleanup, and security improvements. --- src/SNTPClient.cpp | 42 ++++++++++++++++++++++++++++++++---------- src/SNTPClient.h | 1 + 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/SNTPClient.cpp b/src/SNTPClient.cpp index 7f652fa401..e86edca76e 100644 --- a/src/SNTPClient.cpp +++ b/src/SNTPClient.cpp @@ -11,6 +11,24 @@ static uint8_t SNTPQueryData[48] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; +// NTP timestamp constant +#define NTP_UNIX_OFFSET 0x83AA7E80 + +// SNTP packet offsets +#define NTP_OFF_INFO 0 +#define NTP_OFF_ROOTDELAY 1 +#define NTP_OFF_ROOTDISP 2 +#define NTP_OFF_REFERENCEID 3 +#define NTP_OFF_REFTS_INT 4 +#define NTP_OFF_REFTS_FRAC 5 +#define NTP_OFF_ORGTS_INT 6 +#define NTP_OFF_ORGTS_FRAC 7 +#define NTP_OFF_RECVTS_INT 8 +#define NTP_OFF_RECVTS_FRAC 9 +#define NTP_OFF_XMITTS_INT 10 +#define NTP_OFF_XMITTS_FRAC 11 + + SNTPClient::SNTPClient(boost::asio::io_service& service) : mIOService(service), mSocket(service), mTimer(service), mResolver(service), mOffset(0), mLastOffsetUpdate((time_t) -1), mReceiveBuffer(256) @@ -45,7 +63,10 @@ void SNTPClient::resolveComplete(const boost::system::error_code& error, boost:: } query.mReceivedReply = false; query.mLocalTimeSent = now; - mSocket.async_send_to(boost::asio::buffer(SNTPQueryData, 256), *sel, + query.mQueryMagic = rand(); + reinterpret_cast(SNTPQueryData)[NTP_OFF_XMITTS_INT] = time(NULL) + NTP_UNIX_OFFSET; + reinterpret_cast(SNTPQueryData)[NTP_OFF_XMITTS_FRAC] = query.mQueryMagic; + mSocket.async_send_to(boost::asio::buffer(SNTPQueryData, 48), *sel, boost::bind(&SNTPClient::sendComplete, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } @@ -68,11 +89,12 @@ void SNTPClient::receivePacket(const boost::system::error_code& error, std::size query->second.mReceivedReply = true; if (time(NULL) > (query->second.mLocalTimeSent + 1)) Log(lsWARNING) << "SNTP: Late response"; + else if (bytes_xferd < 48) + Log(lsWARNING) << "SNTP: Short reply (" << bytes_xferd << ") " << mReceiveBuffer.size(); + else if (reinterpret_cast(&mReceiveBuffer[0])[NTP_OFF_ORGTS_FRAC] != query->second.mQueryMagic) + Log(lsWARNING) << "SNTP: Reply had wrong magic number"; else - if (bytes_xferd < 48) - Log(lsWARNING) << "SNTP: Short reply (" << bytes_xferd << ") " << mReceiveBuffer.size(); - else - processReply(); + processReply(); } } @@ -92,8 +114,8 @@ void SNTPClient::processReply() assert(mReceiveBuffer.size() >= 48); uint32 *recvBuffer = reinterpret_cast(&mReceiveBuffer.front()); - unsigned info = ntohl(recvBuffer[0]); - int64_t timev = ntohl(recvBuffer[8]); + unsigned info = ntohl(recvBuffer[NTP_OFF_INFO]); + int64_t timev = ntohl(recvBuffer[NTP_OFF_RECVTS_INT]); unsigned stratum = (info >> 16) & 0xff; if ((info >> 30) == 3) @@ -109,7 +131,7 @@ void SNTPClient::processReply() time_t now = time(NULL); timev -= now; - timev -= 0x83AA7E80ULL; + timev -= NTP_UNIX_OFFSET; Log(lsTRACE) << "SNTP: Offset is " << timev; if ((mLastOffsetUpdate == (time_t) -1) || (mLastOffsetUpdate < (now - 180))) @@ -181,7 +203,7 @@ bool SNTPClient::doQuery() time_t now = time(NULL); if ((best->second == now) || (best->second == (now - 1))) { - Log(lsINFO) << "SNTP: All servers recently queried"; + Log(lsTRACE) << "SNTP: All servers recently queried"; return false; } best->second = now; @@ -190,6 +212,6 @@ bool SNTPClient::doQuery() mResolver.async_resolve(query, boost::bind(&SNTPClient::resolveComplete, this, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); - Log(lsINFO) << "SNTP: Resolve pending for " << best->first; + Log(lsTRACE) << "SNTP: Resolve pending for " << best->first; return true; } diff --git a/src/SNTPClient.h b/src/SNTPClient.h index 8e6489a0a9..f8b00c071d 100644 --- a/src/SNTPClient.h +++ b/src/SNTPClient.h @@ -13,6 +13,7 @@ class SNTPQuery public: bool mReceivedReply; time_t mLocalTimeSent; + int mQueryMagic; SNTPQuery(time_t j = (time_t) -1) : mReceivedReply(false), mLocalTimeSent(j) { ; } };