Merge with default Experimental_Callback_Events
authorMarkus Schaber <markus@pep-security.net>
Sat, 16 Jul 2016 10:03:48 +0200
branchExperimental_Callback_Events
changeset 1458aa1127b8288
parent 132 267c3fe7351c
parent 144 18208f2ec0bf
child 152 e6e3d95aced2
Merge with default
     1.1 --- a/GateKeeper.cpp	Tue Jun 28 21:22:10 2016 +0200
     1.2 +++ b/GateKeeper.cpp	Sat Jul 16 10:03:48 2016 +0200
     1.3 @@ -112,13 +112,15 @@
     1.4  
     1.5      const LPCTSTR GateKeeper::plugin_reg_path = _T("Software\\Microsoft\\Office\\Outlook\\Addins\\pEp");
     1.6      const LPCTSTR GateKeeper::plugin_reg_value_name = _T("LoadBehavior");
     1.7 -    const LPCTSTR GateKeeper::updater_reg_path = _T("Software\\pEp\\Updater";)
     1.8 +    const LPCTSTR GateKeeper::updater_reg_path = _T("Software\\pEp\\Updater");
     1.9  
    1.10      const time_t GateKeeper::cycle = 7200;   // 7200 sec is 2 h
    1.11 +    const time_t GateKeeper::fraction = 10;  // first update is at 10% of cycle
    1.12      const DWORD GateKeeper::waiting = 10000; // 10000 ms is 10 sec
    1.13  
    1.14      GateKeeper::GateKeeper(CpEpCOMServerAdapterModule * self)
    1.15 -        : _self(self), now(time(NULL)), next(now + time_diff()), hkUpdater(NULL), internet(NULL), hAES(NULL), hRSA(NULL)
    1.16 +        : _self(self), now(time(NULL)), next(now + time_diff()), hkUpdater(NULL), hkPluginStart(NULL),
    1.17 +            internet(NULL), hAES(NULL), hRSA(NULL)
    1.18      {
    1.19          LONG lResult = RegOpenCurrentUser(KEY_READ, &cu);
    1.20          assert(lResult == ERROR_SUCCESS);
    1.21 @@ -132,6 +134,12 @@
    1.22              assert(lResult == ERROR_SUCCESS);
    1.23              if (lResult != ERROR_SUCCESS)
    1.24                  return;
    1.25 +
    1.26 +            lResult = RegOpenKeyEx(cu, plugin_reg_path, 0, KEY_WRITE, &hkPluginStart);
    1.27 +            assert(lResult == ERROR_SUCCESS);
    1.28 +            if (lResult != ERROR_SUCCESS)
    1.29 +                return;
    1.30 +            RegCloseKey(hkPluginStart);
    1.31          }
    1.32      }
    1.33      
    1.34 @@ -150,7 +158,7 @@
    1.35              static random_device rd;
    1.36              static mt19937 gen(rd());
    1.37  
    1.38 -            uniform_int_distribution<time_t> dist(0, cycle);
    1.39 +            uniform_int_distribution<time_t> dist(0, cycle/fraction);
    1.40  
    1.41              return dist(gen);
    1.42          }
    1.43 @@ -182,22 +190,19 @@
    1.44  
    1.45      void GateKeeper::keep_plugin()
    1.46      {
    1.47 -        while (!_self->m_bComInitialized)
    1.48 -            Sleep(1);
    1.49 +        if (!hkPluginStart)
    1.50 +            return;
    1.51  
    1.52 -        //MessageBox(NULL, _T("test"), _T("keep_plugin"), MB_ICONINFORMATION | MB_TOPMOST);
    1.53 -
    1.54 -        DWORD value;
    1.55 -        DWORD size;
    1.56 -
    1.57 -        LONG lResult = RegGetValue(cu, plugin_reg_path, plugin_reg_value_name, RRF_RT_REG_DWORD, NULL, &value, &size);
    1.58 +        LONG lResult = RegOpenKeyEx(cu, plugin_reg_path, 0, KEY_WRITE, &hkPluginStart);
    1.59 +        assert(lResult == ERROR_SUCCESS);
    1.60          if (lResult != ERROR_SUCCESS)
    1.61              return;
    1.62  
    1.63 -        if (value != 3) {
    1.64 -            lResult = RegSetValue(cu, plugin_reg_path, RRF_RT_REG_DWORD, plugin_reg_value_name, 3);
    1.65 -            assert(lResult == ERROR_SUCCESS);
    1.66 -        }
    1.67 +        DWORD v = 3;
    1.68 +        lResult = RegSetValueEx(hkPluginStart, plugin_reg_value_name, 0, REG_DWORD, (const BYTE *) &v, sizeof(DWORD));
    1.69 +        assert(lResult == ERROR_SUCCESS);
    1.70 +
    1.71 +        RegCloseKey(hkPluginStart);
    1.72      }
    1.73  
    1.74      string GateKeeper::update_key()
    1.75 @@ -235,15 +240,18 @@
    1.76              key.dw_key[i] = (uint32_t) dist(gen);
    1.77  
    1.78          BCRYPT_KEY_HANDLE hKey;
    1.79 +
    1.80          NTSTATUS status = BCryptGenerateSymmetricKey(hAES, &hKey, NULL, 0, (PUCHAR) &key, (ULONG) sizeof(aeskey_t), 0);
    1.81          assert(status == 0);
    1.82          if (status)
    1.83              throw runtime_error("BCryptGenerateSymmetricKey");
    1.84  
    1.85 +#ifndef NDEBUG
    1.86          DWORD keylength = 0;
    1.87          ULONG copied = 0;
    1.88          status = BCryptGetProperty(hKey, BCRYPT_KEY_LENGTH, (PUCHAR) &keylength, sizeof(DWORD), &copied, 0);
    1.89          assert(keylength == 256);
    1.90 +#endif
    1.91  
    1.92          return hKey;
    1.93      }
    1.94 @@ -257,6 +265,7 @@
    1.95  
    1.96          PCERT_PUBLIC_KEY_INFO uk;
    1.97          DWORD uk_size;
    1.98 +
    1.99          BOOL bResult = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
   1.100                  (const BYTE *) _update_key.data(), _update_key.size(), CRYPT_DECODE_ALLOC_FLAG, NULL, &uk, &uk_size);
   1.101          if (!bResult)
   1.102 @@ -264,6 +273,7 @@
   1.103  
   1.104          PUBLIC_KEY_VALUES *_uk;
   1.105          DWORD _uk_size;
   1.106 +
   1.107          bResult = CryptDecodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
   1.108              uk->PublicKey.pbData, uk->PublicKey.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &_uk, &_uk_size);
   1.109          LocalFree(uk);
   1.110 @@ -338,19 +348,21 @@
   1.111          static product_list products;
   1.112  
   1.113          // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724872(v=vs.85).aspx
   1.114 -        static TCHAR value_name[16384];
   1.115 +        TCHAR value_name[16384];
   1.116          DWORD value_name_size;
   1.117 -        static TCHAR value[L_MAX_URL_LENGTH + 1];
   1.118 +        TCHAR value[L_MAX_URL_LENGTH + 1];
   1.119          DWORD value_size;
   1.120  
   1.121          products.empty();
   1.122  
   1.123          LONG lResult = ERROR_SUCCESS;
   1.124          for (DWORD i = 0; lResult == ERROR_SUCCESS; i++) {
   1.125 +            value_name_size = 16383;
   1.126              value_size = L_MAX_URL_LENGTH + 1;
   1.127 -            lResult = RegEnumValue(hkUpdater, 0, value_name, &value_name_size, NULL, NULL, (LPBYTE) value, &value_size);
   1.128 -            if (lResult == ERROR_SUCCESS)
   1.129 +            lResult = RegEnumValue(hkUpdater, i, value_name, &value_name_size, NULL, NULL, (LPBYTE) value, &value_size);
   1.130 +            if (lResult == ERROR_SUCCESS) {
   1.131                  products.push_back({ value_name, value });
   1.132 +            }
   1.133          }
   1.134  
   1.135          return products;
   1.136 @@ -358,7 +370,7 @@
   1.137  
   1.138      void GateKeeper::install_msi(tstring filename)
   1.139      {
   1.140 -
   1.141 +        ShellExecute(NULL, _T("open"), filename.c_str(), NULL, NULL, SW_SHOW);
   1.142      }
   1.143  
   1.144      void GateKeeper::update_product(product p, DWORD context)
   1.145 @@ -380,38 +392,40 @@
   1.146  
   1.147          string crypted;
   1.148          string unencrypted;
   1.149 +        UCHAR iv[12];
   1.150 +        UCHAR nonce[sizeof(iv)];
   1.151 +        UCHAR tag[16];
   1.152 +        tstring filename;
   1.153 +        HANDLE hFile = NULL;
   1.154 +        char *unencrypted_buffer = NULL;
   1.155  
   1.156          try {
   1.157 -            do {
   1.158 +            DWORD reading;
   1.159 +            InternetReadFile(hUrl, iv, sizeof(iv), &reading);
   1.160 +
   1.161 +            if (reading) do {
   1.162                  static char buffer[1024*1024];
   1.163 -                DWORD reading;
   1.164                  BOOL bResult = InternetReadFile(hUrl, buffer, 1024*1024, &reading);
   1.165                  if (!bResult || !reading)
   1.166                      break;
   1.167                  crypted += string(buffer, reading);
   1.168              } while (1);
   1.169          }
   1.170 -        catch (exception& e) {
   1.171 -            MessageBox(NULL, utility::utf16_string(e.what()).c_str(), _T("exception"), MB_ICONSTOP);
   1.172 +        catch (exception&) {
   1.173 +            goto closing;
   1.174          }
   1.175 +
   1.176          InternetCloseHandle(hUrl);
   1.177          hUrl = NULL;
   1.178  
   1.179 -        tstring filename;
   1.180 -        HANDLE hFile = NULL;
   1.181 -        char *unencrypted_buffer = NULL;
   1.182 -
   1.183 -        UCHAR nonce[12];
   1.184 -        memcpy(nonce, crypted.data(), sizeof(nonce));
   1.185 -        UCHAR iv[16];
   1.186 -        memset(iv, 0, sizeof(iv));
   1.187 -        memcpy(iv, crypted.data(), sizeof(nonce));
   1.188 +        memcpy(nonce, iv, sizeof(iv));
   1.189  
   1.190          BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo;
   1.191          BCRYPT_INIT_AUTH_MODE_INFO(authInfo);
   1.192 -
   1.193          authInfo.pbNonce = nonce;
   1.194          authInfo.cbNonce = sizeof(nonce);
   1.195 +        authInfo.pbTag = tag;
   1.196 +        authInfo.cbTag = sizeof(tag);
   1.197  
   1.198          ULONG unencrypted_size;
   1.199          NTSTATUS status = BCryptDecrypt(dk, (PUCHAR) crypted.data(), crypted.size(),
   1.200 @@ -421,13 +435,16 @@
   1.201          
   1.202          unencrypted_buffer = new char[unencrypted_size];
   1.203          PUCHAR crypted_data = (PUCHAR) crypted.data();
   1.204 -        ULONG crypted_size = (ULONG) crypted.size();
   1.205 -        
   1.206 +        ULONG crypted_size = (ULONG) crypted.size() - sizeof(tag);
   1.207 +        memcpy(tag, crypted_data + crypted_size, sizeof(tag));
   1.208 +
   1.209          status = BCryptDecrypt(dk, crypted_data, crypted_size,
   1.210 -            &authInfo, iv, 16, (PUCHAR) unencrypted_buffer, unencrypted_size, &unencrypted_size, 0);
   1.211 +            &authInfo, iv, sizeof(iv), (PUCHAR) unencrypted_buffer, unencrypted_size, &unencrypted_size, 0);
   1.212          if (status)
   1.213              goto closing;
   1.214  
   1.215 +        BCryptDestroyKey(dk);
   1.216 +
   1.217          TCHAR temp_path[MAX_PATH + 1];
   1.218          GetTempPath(MAX_PATH, temp_path);
   1.219          filename = temp_path;
   1.220 @@ -444,8 +461,6 @@
   1.221  
   1.222          install_msi(filename);
   1.223  
   1.224 -        DeleteFile(filename.c_str());
   1.225 -        BCryptDestroyKey(dk);
   1.226          return;
   1.227  
   1.228      closing:
   1.229 @@ -455,15 +470,11 @@
   1.230              CloseHandle(hFile);
   1.231          if (hUrl)
   1.232              InternetCloseHandle(hUrl);
   1.233 -        if (filename.length())
   1.234 -            DeleteFile(filename.c_str());
   1.235          BCryptDestroyKey(dk);
   1.236      }
   1.237  
   1.238      void GateKeeper::keep_updated()
   1.239      {
   1.240 -        return; // disabled for now
   1.241 -
   1.242          NTSTATUS status = BCryptOpenAlgorithmProvider(&hAES, BCRYPT_AES_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0);
   1.243          assert(status == 0);
   1.244          if (status)
   1.245 @@ -483,6 +494,7 @@
   1.246  
   1.247          product_list& products = registered_products();
   1.248          DWORD context = 0;
   1.249 +
   1.250          for (auto i = products.begin(); i != products.end(); i++) {
   1.251              try {
   1.252                  update_product(*i, context++);
     2.1 --- a/GateKeeper.h	Tue Jun 28 21:22:10 2016 +0200
     2.2 +++ b/GateKeeper.h	Sat Jul 16 10:03:48 2016 +0200
     2.3 @@ -37,6 +37,7 @@
     2.4          static const LPCTSTR updater_reg_path;
     2.5  
     2.6          static const time_t cycle;
     2.7 +        static const time_t fraction;
     2.8          static const DWORD waiting;
     2.9  
    2.10          static time_t time_diff();
    2.11 @@ -58,6 +59,7 @@
    2.12          bool cu_open;
    2.13          HKEY cu;
    2.14          HKEY hkUpdater;
    2.15 +        HKEY hkPluginStart;
    2.16          HINTERNET internet;
    2.17          BCRYPT_ALG_HANDLE hAES;
    2.18          BCRYPT_ALG_HANDLE hRSA;
     3.1 --- a/pEpCOMServerAdapter.h	Tue Jun 28 21:22:10 2016 +0200
     3.2 +++ b/pEpCOMServerAdapter.h	Sat Jul 16 10:03:48 2016 +0200
     3.3 @@ -26,6 +26,8 @@
     3.4  
     3.5      void start_gatekeeper()
     3.6      {
     3.7 +        this->Lock(); // never exit
     3.8 +
     3.9          try {
    3.10              gatekeeper_thread = new thread(gatekeeper, this);
    3.11              gatekeeper_thread->detach();
     4.1 --- a/pEp_utility.cpp	Tue Jun 28 21:22:10 2016 +0200
     4.2 +++ b/pEp_utility.cpp	Sat Jul 16 10:03:48 2016 +0200
     4.3 @@ -167,10 +167,12 @@
     4.4              CComSafeArray<BYTE> sa;
     4.5              sa.Create(tl->size);
     4.6  
     4.7 -            char *data;
     4.8 -            SafeArrayAccessData(sa, (void **) &data);
     4.9 -            memcpy(data, tl->value, tl->size);
    4.10 -            SafeArrayUnaccessData(sa);
    4.11 +            if (tl->size) {
    4.12 +                char *data;
    4.13 +                SafeArrayAccessData(sa, (void **) &data);
    4.14 +                memcpy(data, tl->value, tl->size);
    4.15 +                SafeArrayUnaccessData(sa);
    4.16 +            }
    4.17  
    4.18              blob *_blob = new blob();
    4.19  
    4.20 @@ -359,16 +361,24 @@
    4.21                  SafeArrayGetUBound(b.value, 1, &_ubound);
    4.22                  size_t size = _ubound - _lbound + 1;
    4.23  
    4.24 -                char *buffer = (char *) malloc(size);
    4.25 -                if (buffer == NULL)
    4.26 -                    throw bad_alloc();
    4.27 +                char *buffer;
    4.28 +                if (size) {
    4.29 +                    buffer = (char *) malloc(size);
    4.30 +                    if (buffer == NULL)
    4.31 +                        throw bad_alloc();
    4.32  
    4.33 -                char *data;
    4.34 +                    char *data;
    4.35  
    4.36 -                SafeArrayAccessData(b.value, (void **) &data);
    4.37 -                memcpy(buffer, data, size);
    4.38 -                SafeArrayUnaccessData(sa);
    4.39 +                    SafeArrayAccessData(b.value, (void **) &data);
    4.40 +                    memcpy(buffer, data, size);
    4.41 +                    SafeArrayUnaccessData(sa);
    4.42 +                }
    4.43 +                else {
    4.44 +                    buffer = _strdup("");
    4.45 +                    if (buffer == NULL)
    4.46 +                        throw bad_alloc();
    4.47  
    4.48 +                }
    4.49                  _bl = bloblist_add(_bl, buffer, size, str(b.mime_type), str(b.filename));
    4.50                  if (_bl == NULL) {
    4.51                      free(buffer);