ZNC  trunk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Utils.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2014 ZNC, see the NOTICE file for details.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _UTILS_H
18 #define _UTILS_H
19 
20 #include <znc/zncconfig.h>
21 #include <znc/ZNCString.h>
22 #include <assert.h>
23 #include <cstdio>
24 #include <fcntl.h>
25 #include <map>
26 #include <sys/file.h>
27 #include <sys/time.h>
28 #include <unistd.h>
29 #include <vector>
30 
31 static inline void SetFdCloseOnExec(int fd)
32 {
33  int flags = fcntl(fd, F_GETFD, 0);
34  if (flags < 0)
35  return; // Ignore errors
36  // When we execve() a new process this fd is now automatically closed.
37  fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
38 }
39 
40 static const char g_HexDigits[] = "0123456789abcdef";
41 
42 class CUtils {
43 public:
44  CUtils();
45  ~CUtils();
46 
47  static CString GetIP(unsigned long addr);
48  static unsigned long GetLongIP(const CString& sIP);
49 
50  static void PrintError(const CString& sMessage);
51  static void PrintMessage(const CString& sMessage, bool bStrong = false);
52  static void PrintPrompt(const CString& sMessage);
53  static void PrintAction(const CString& sMessage);
54  static void PrintStatus(bool bSuccess, const CString& sMessage = "");
55 
56 #ifndef SWIGPERL
57  // TODO refactor this
58  static const CString sDefaultHash;
59 #endif
60 
61  static CString GetSaltedHashPass(CString& sSalt);
62  static CString GetSalt();
63  static CString SaltedMD5Hash(const CString& sPass, const CString& sSalt);
64  static CString SaltedSHA256Hash(const CString& sPass, const CString& sSalt);
65  static CString GetPass(const CString& sPrompt);
66  static bool GetInput(const CString& sPrompt, CString& sRet, const CString& sDefault = "", const CString& sHint = "");
67  static bool GetBoolInput(const CString& sPrompt, bool bDefault);
68  static bool GetBoolInput(const CString& sPrompt, bool *pbDefault = NULL);
69  static bool GetNumInput(const CString& sPrompt, unsigned int& uRet, unsigned int uMin = 0, unsigned int uMax = ~0, unsigned int uDefault = ~0);
70 
71  static unsigned long long GetMillTime() {
72  struct timeval tv;
73  unsigned long long iTime = 0;
74  gettimeofday(&tv, NULL);
75  iTime = (unsigned long long) tv.tv_sec * 1000;
76  iTime += ((unsigned long long) tv.tv_usec / 1000);
77  return iTime;
78  }
79 #ifdef HAVE_LIBSSL
80  static void GenerateCert(FILE *pOut, const CString& sHost = "");
81 #endif /* HAVE_LIBSSL */
82 
83  static CString CTime(time_t t, const CString& sTZ);
84  static CString FormatTime(time_t t, const CString& sFormat, const CString& sTZ);
85  static CString FormatServerTime(const timeval& tv);
86  static SCString GetTimezones();
87 
88  static MCString GetMessageTags(const CString& sLine);
89  static void SetMessageTags(CString& sLine, const MCString& mssTags);
90 
91 private:
92 protected:
93 };
94 
95 class CException {
96 public:
97  typedef enum {
100  } EType;
101 
103  m_eType = e;
104  }
105  virtual ~CException() {}
106 
107  EType GetType() const { return m_eType; }
108 private:
109 protected:
111 };
112 
113 
139 class CTable : protected std::vector<std::vector<CString> > {
140 public:
141  CTable() {}
142  virtual ~CTable() {}
143 
150  bool AddColumn(const CString& sName);
151 
156  size_type AddRow();
157 
165  bool SetCell(const CString& sColumn, const CString& sValue, size_type uRowIdx = ~0);
166 
172  bool GetLine(unsigned int uIdx, CString& sLine) const;
173 
180  CString::size_type GetColumnWidth(unsigned int uIdx) const;
181 
183  void Clear();
184 
186  using std::vector<std::vector<CString> >::size;
187 
189  using std::vector<std::vector<CString> >::empty;
190 private:
191  unsigned int GetColumnIndex(const CString& sName) const;
192 
193 protected:
194  std::vector<CString> m_vsHeaders;
195  std::map<CString, CString::size_type> m_msuWidths; // Used to cache the width of a column
196 };
197 
198 
199 #ifdef HAVE_LIBSSL
200 #include <openssl/aes.h>
201 #include <openssl/blowfish.h>
202 #include <openssl/md5.h>
204 class CBlowfish {
205 public:
211  CBlowfish(const CString & sPassword, int iEncrypt, const CString & sIvec = "");
212  ~CBlowfish();
213 
215  static unsigned char *MD5(const unsigned char *input, u_int ilen);
216 
218  static CString MD5(const CString & sInput, bool bHexEncode = false);
219 
221  void Crypt(unsigned char *input, unsigned char *output, u_int ibytes);
222 
224  unsigned char * Crypt(unsigned char *input, u_int ibytes);
225  CString Crypt(const CString & sData);
226 
227 private:
228  unsigned char *m_ivec;
229  BF_KEY m_bkey;
230  int m_iEncrypt, m_num;
231 };
232 
233 #endif /* HAVE_LIBSSL */
234 
240 template<typename K, typename V = bool>
241 class TCacheMap {
242 public:
243  TCacheMap(unsigned int uTTL = 5000) {
244  m_uTTL = uTTL;
245  }
246 
247  virtual ~TCacheMap() {}
248 
253  void AddItem(const K& Item) {
254  AddItem(Item, m_uTTL);
255  }
256 
262  void AddItem(const K& Item, unsigned int uTTL) {
263  AddItem(Item, V(), uTTL);
264  }
265 
271  void AddItem(const K& Item, const V& Val) {
272  AddItem(Item, Val, m_uTTL);
273  }
274 
281  void AddItem(const K& Item, const V& Val, unsigned int uTTL) {
282  if (!uTTL) { // If time-to-live is zero we don't want to waste our time adding it
283  RemItem(Item); // Remove the item incase it already exists
284  return;
285  }
286 
287  m_mItems[Item] = value(CUtils::GetMillTime() + uTTL, Val);
288  }
289 
295  bool HasItem(const K& Item) {
296  Cleanup();
297  return (m_mItems.find(Item) != m_mItems.end());
298  }
299 
305  V* GetItem(const K& Item) {
306  Cleanup();
307  iterator it = m_mItems.find(Item);
308  if (it == m_mItems.end())
309  return NULL;
310  return &it->second.second;
311  }
312 
318  bool RemItem(const K& Item) {
319  return (m_mItems.erase(Item) != 0);
320  }
321 
325  void Cleanup() {
326  iterator it = m_mItems.begin();
327 
328  while (it != m_mItems.end()) {
329  if (CUtils::GetMillTime() > (it->second.first)) {
330  m_mItems.erase(it++);
331  } else {
332  ++it;
333  }
334  }
335  }
336 
340  void Clear() {
341  m_mItems.clear();
342  }
343 
344  // Setters
345  void SetTTL(unsigned int u) { m_uTTL = u; }
346  // !Setters
347  // Getters
348  unsigned int GetTTL() const { return m_uTTL; }
349  // !Getters
350 protected:
351  typedef std::pair<unsigned long long, V> value;
352  typedef typename std::map<K, value>::iterator iterator;
353  std::map<K, value> m_mItems;
354  unsigned int m_uTTL;
355 };
356 
362 template<typename T>
363 class CSmartPtr {
364 public:
369  m_pType = NULL;
370  m_puCount = NULL;
371  }
372 
377  CSmartPtr(T* pRawPtr) {
378  m_pType = NULL;
379  m_puCount = NULL;
380 
381  Attach(pRawPtr);
382  }
383 
388  CSmartPtr(const CSmartPtr<T>& CopyFrom) {
389  m_pType = NULL;
390  m_puCount = NULL;
391 
392  *this = CopyFrom;
393  }
394 
399  Release();
400  }
401 
402  // Overloaded operators
403  T& operator *() const { assert(m_pType); return *m_pType; }
404  T* operator ->() const { assert(m_pType); return m_pType; }
405 
411  CSmartPtr<T>& operator =(T* pRawPtr) { Attach(pRawPtr); return *this; }
412 
419  if (&CopyFrom != this) { // Check for assignment to self
420  Release(); // Release the current pointer
421 
422  if (CopyFrom.IsNull()) { // If the source raw pointer is null
423  return *this; // Then just bail out
424  }
425 
426  m_pType = CopyFrom.m_pType; // Make our pointers reference the same raw pointer and counter
427  m_puCount = CopyFrom.m_puCount;
428 
429  assert(m_puCount); // We now point to something valid, so increment the counter
430  (*m_puCount)++;
431  }
432 
433  return *this;
434  }
435  // !Overloaded operators
436 
441  operator bool() const {
442  return !IsNull();
443  }
444 
449  bool IsNull() const {
450  return (m_pType == NULL);
451  }
452 
458  CSmartPtr<T>& Attach(T* pRawPtr) {
459  if (pRawPtr != m_pType) { // Check for assignment to self
460  Release(); // Release the current pointer
461  m_pType = pRawPtr; // Point to the passed raw pointer
462 
463  if (m_pType) { // If the passed pointer was valid
464  m_puCount = new unsigned int(1); // Create a new counter starting at 1 (us)
465  }
466  }
467 
468  return *this;
469  }
470 
474  void Release() {
475  if (m_pType) { // Only release if there is something to be released
476  assert(m_puCount);
477  (*m_puCount)--; // Decrement our counter
478 
479  if (!*m_puCount) { // If we were the last reference to this pointer, then clean up
480  delete m_puCount;
481  delete m_pType;
482  }
483 
484  m_pType = NULL; // Get rid of our references
485  m_puCount = NULL;
486  }
487  }
488 
489  // Getters
490  T* GetPtr() const { return m_pType; }
491  unsigned int GetCount() const { return (m_puCount) ? *m_puCount : 0; }
492  // !Getters
493 private:
494  T* m_pType;
495  unsigned int* m_puCount;
496 };
497 
498 template<typename T>
499 bool operator ==(T* lhs, const CSmartPtr<T>& rhs) { return (lhs == rhs.GetPtr()); }
500 
501 template<typename T>
502 bool operator ==(const CSmartPtr<T>& lhs, T* rhs) { return (lhs.GetPtr() == rhs); }
503 
504 template<typename T>
505 bool operator ==(const CSmartPtr<T>& lhs, const CSmartPtr<T>& rhs) { return (lhs.GetPtr() == rhs.GetPtr()); }
506 
507 #endif // !_UTILS_H
508 
void Release()
Releases the underlying raw pointer and cleans up if we were the last reference to said pointer...
Definition: Utils.h:474
bool operator==(T *lhs, const CSmartPtr< T > &rhs)
Definition: Utils.h:499
void Cleanup()
Cycles through the queue removing all of the stale entries.
Definition: Utils.h:325
bool HasItem(const K &Item)
Performs a Cleanup() and then checks to see if your item exists.
Definition: Utils.h:295
static void PrintMessage(const CString &sMessage, bool bStrong=false)
void AddItem(const K &Item)
This function adds an item to the cache using the default time-to-live value.
Definition: Utils.h:253
V * GetItem(const K &Item)
Performs a Cleanup() and returns a pointer to the object, or NULL.
Definition: Utils.h:305
EType m_eType
Definition: Utils.h:110
static CString GetSaltedHashPass(CString &sSalt)
Definition: Utils.h:99
does Blowfish w/64 bit feedback, no padding
Definition: Utils.h:204
unsigned int GetTTL() const
Definition: Utils.h:348
void Crypt(unsigned char *input, unsigned char *output, u_int ibytes)
output must be the same size as input
CSmartPtr< T > & Attach(T *pRawPtr)
Attach to a given raw pointer, it will Release() the current raw pointer and assign the new one...
Definition: Utils.h:458
std::map< CString, CString::size_type > m_msuWidths
Definition: Utils.h:195
virtual ~CTable()
Definition: Utils.h:142
bool IsNull() const
Check to see if the underlying raw pointer is null.
Definition: Utils.h:449
void SetTTL(unsigned int u)
Definition: Utils.h:345
static unsigned long long GetMillTime()
Definition: Utils.h:71
static void SetMessageTags(CString &sLine, const MCString &mssTags)
Definition: Utils.h:98
std::vector< CString > m_vsHeaders
Definition: Utils.h:194
static void PrintStatus(bool bSuccess, const CString &sMessage="")
Definition: Utils.h:42
static CString GetIP(unsigned long addr)
EType GetType() const
Definition: Utils.h:107
std::set< CString > SCString
Definition: ZNCString.h:34
static unsigned long GetLongIP(const CString &sIP)
static CString GetSalt()
CSmartPtr()
Standard constructor, points to nothing.
Definition: Utils.h:368
virtual ~CException()
Definition: Utils.h:105
static bool GetNumInput(const CString &sPrompt, unsigned int &uRet, unsigned int uMin=0, unsigned int uMax=~0, unsigned int uDefault=~0)
static const CString sDefaultHash
Definition: Utils.h:58
static MCString GetMessageTags(const CString &sLine)
CException(EType e)
Definition: Utils.h:102
static CString FormatTime(time_t t, const CString &sFormat, const CString &sTZ)
String class that is used inside ZNC.
Definition: ZNCString.h:67
bool AddColumn(const CString &sName)
Adds a new column to the table.
This is a standard reference counting pointer. Be careful not to have two of these point to the same ...
Definition: Utils.h:363
T * GetPtr() const
Definition: Utils.h:490
CSmartPtr(const CSmartPtr< T > &CopyFrom)
Copy constructor, will copy the raw pointer and counter locations and increment the reference counter...
Definition: Utils.h:388
virtual ~TCacheMap()
Definition: Utils.h:247
bool GetLine(unsigned int uIdx, CString &sLine) const
Get a line of the table&#39;s output.
static CString SaltedSHA256Hash(const CString &sPass, const CString &sSalt)
bool RemItem(const K &Item)
Removes a specific item from the cache.
Definition: Utils.h:318
T & operator*() const
Definition: Utils.h:403
static CString FormatServerTime(const timeval &tv)
static SCString GetTimezones()
~CSmartPtr()
Destructor will Release() the raw pointer and delete it if this was the last reference.
Definition: Utils.h:398
static bool GetBoolInput(const CString &sPrompt, bool bDefault)
std::map< K, value > m_mItems
Map of cached items.
Definition: Utils.h:353
CSmartPtr< T > & operator=(T *pRawPtr)
Attach() to a raw pointer.
Definition: Utils.h:411
static void PrintAction(const CString &sMessage)
static void PrintError(const CString &sMessage)
Definition: Utils.h:95
T * operator->() const
Definition: Utils.h:404
void AddItem(const K &Item, const V &Val)
This function adds an item to the cache using the default time-to-live value.
Definition: Utils.h:271
A dictionary for strings.
Definition: ZNCString.h:538
static CString GetPass(const CString &sPrompt)
std::pair< unsigned long long, V > value
Definition: Utils.h:351
void AddItem(const K &Item, unsigned int uTTL)
This function adds an item to the cache using a custom time-to-live value.
Definition: Utils.h:262
static CString CTime(time_t t, const CString &sTZ)
void AddItem(const K &Item, const V &Val, unsigned int uTTL)
This function adds an item to the cache using a custom time-to-live value.
Definition: Utils.h:281
static unsigned char * MD5(const unsigned char *input, u_int ilen)
output must be freed
void Clear()
Completely clear the table.
Insert an object with a time-to-live and check later if it still exists.
Definition: Utils.h:241
unsigned int m_uTTL
Default time-to-live duration.
Definition: Utils.h:354
TCacheMap(unsigned int uTTL=5000)
Definition: Utils.h:243
void Clear()
Clear all entries.
Definition: Utils.h:340
CBlowfish(const CString &sPassword, int iEncrypt, const CString &sIvec="")
CTable()
Definition: Utils.h:141
unsigned int GetCount() const
Definition: Utils.h:491
std::map< CString, value >::iterator iterator
Definition: Utils.h:352
EType
Definition: Utils.h:97
Generate a grid-like output from a given input.
Definition: Utils.h:139
size_type AddRow()
Adds a new row to the table.
static void GenerateCert(FILE *pOut, const CString &sHost="")
static CString SaltedMD5Hash(const CString &sPass, const CString &sSalt)
static bool GetInput(const CString &sPrompt, CString &sRet, const CString &sDefault="", const CString &sHint="")
CString::size_type GetColumnWidth(unsigned int uIdx) const
Return the width of the given column.
CSmartPtr(T *pRawPtr)
Attach to an existing raw pointer, be CAREFUL not to have more than one CSmartPtr attach to the same ...
Definition: Utils.h:377
static void PrintPrompt(const CString &sMessage)
bool SetCell(const CString &sColumn, const CString &sValue, size_type uRowIdx=~0)
Sets a given cell in the table to a value.