Cleanup, dead code removal, some pretty insignificant security stuff that's based on recommendations.

This commit is contained in:
Adam Ierymenko 2014-04-18 00:14:12 -07:00
parent 5f45977e3e
commit 7831c4bfef
6 changed files with 31 additions and 33 deletions

View file

@ -380,12 +380,12 @@ public:
} }
/** /**
* Unconditionally zero buffer's underlying memory * Unconditionally and securely zero buffer's underlying memory
*/ */
inline void zeroAll() inline void burn()
throw() throw()
{ {
memset(_b,0,sizeof(_b)); Utils::burn(_b,sizeof(_b));
} }
/** /**

View file

@ -67,6 +67,8 @@ public:
*/ */
Peer(); Peer();
~Peer() { Utils::burn(_key,sizeof(_key)); }
/** /**
* Construct a new peer * Construct a new peer
* *

View file

@ -239,13 +239,16 @@ void Topology::_dumpPeers()
if (fwrite(buf.data(),buf.size(),1,pd) != 1) { if (fwrite(buf.data(),buf.size(),1,pd) != 1) {
fclose(pd); fclose(pd);
Utils::rm(pdpath); Utils::rm(pdpath);
buf.burn();
return; return;
} }
buf.clear(); buf.clear();
buf.burn();
} }
} catch ( ... ) { } catch ( ... ) {
fclose(pd); fclose(pd);
Utils::rm(pdpath); Utils::rm(pdpath);
buf.burn();
return; return;
} }
} }
@ -254,12 +257,15 @@ void Topology::_dumpPeers()
if (fwrite(buf.data(),buf.size(),1,pd) != 1) { if (fwrite(buf.data(),buf.size(),1,pd) != 1) {
fclose(pd); fclose(pd);
Utils::rm(pdpath); Utils::rm(pdpath);
buf.burn();
return; return;
} }
buf.burn();
} }
fclose(pd); fclose(pd);
Utils::lockDownFile(pdpath.c_str(),false); Utils::lockDownFile(pdpath.c_str(),false);
buf.burn();
} }
void Topology::_loadPeers() void Topology::_loadPeers()
@ -301,6 +307,7 @@ void Topology::_loadPeers()
fclose(pd); fclose(pd);
Utils::rm(pdpath); Utils::rm(pdpath);
buf.burn();
} }
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -395,22 +395,6 @@ std::string Utils::trim(const std::string &s)
return s.substr(start,end - start); return s.substr(start,end - start);
} }
void Utils::stdsprintf(std::string &s,const char *fmt,...)
throw(std::bad_alloc,std::length_error)
{
char buf[65536];
va_list ap;
va_start(ap,fmt);
int n = vsnprintf(buf,sizeof(buf),fmt,ap);
va_end(ap);
if ((n >= (int)sizeof(buf))||(n < 0))
throw std::length_error("printf result too large");
s.append(buf);
}
unsigned int Utils::snprintf(char *buf,unsigned int len,const char *fmt,...) unsigned int Utils::snprintf(char *buf,unsigned int len,const char *fmt,...)
throw(std::length_error) throw(std::length_error)
{ {

View file

@ -85,6 +85,20 @@ public:
return (diff == 0ULL); return (diff == 0ULL);
} }
/**
* Securely zero memory
*
* This just uses volatile to ensure that it's never optimized out.
*/
static inline void burn(void *ptr,unsigned int len)
throw()
{
volatile unsigned char *p = (unsigned char *)ptr;
volatile unsigned char *e = p + len;
while (p != e)
*(p++) = (unsigned char)0;
}
/** /**
* Delete a file * Delete a file
* *
@ -432,21 +446,12 @@ public:
*/ */
static std::string trim(const std::string &s); static std::string trim(const std::string &s);
/**
* Like sprintf, but appends to std::string
*
* @param s String to append to
* @param fmt Printf format string
* @param ... Format arguments
* @throws std::bad_alloc Memory allocation failure
* @throws std::length_error Format + args exceeds internal buffer maximum
*/
static void stdsprintf(std::string &s,const char *fmt,...)
throw(std::bad_alloc,std::length_error);
/** /**
* Variant of snprintf that is portable and throws an exception * Variant of snprintf that is portable and throws an exception
* *
* This just wraps the local implementation whatever it's called, while
* performing a few other checks and adding exceptions for overflow.
*
* @param buf Buffer to write to * @param buf Buffer to write to
* @param len Length of buffer in bytes * @param len Length of buffer in bytes
* @param fmt Format string * @param fmt Format string

View file

@ -461,8 +461,8 @@ static int testPacket()
unsigned char salsaKey[32],hmacKey[32]; unsigned char salsaKey[32],hmacKey[32];
Packet a,b; Packet a,b;
a.zeroAll(); a.burn();
b.zeroAll(); b.burn();
for(unsigned int i=0;i<32;++i) { for(unsigned int i=0;i<32;++i) {
salsaKey[i] = (unsigned char)rand(); salsaKey[i] = (unsigned char)rand();