📄 provider.cpp
字号:
// provider.cc// code for provider.h// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#include "provider.h" // this module#include <stdio.h> // printf#include <stdlib.h> // malloc#include "missing.h" // missing_stricmp#include "sec_clr.h" // CleartextSecurity, Cleartext2#include "globrand.h" // global random generator#ifndef NO_SEC_DE3S #include "sec_de3s.h" // DE3S_Provider#endifSTATICDEF const char* const SecurityProvider::Mechanisms[] = { //"X-DSA-ELGAMAL-3DES-SHA1HMAC", "X-SafeTP1",#if !(defined(SAFETPC) && defined(NDEBUG)) // DOB: for security reasons, these two should not be // included in the production build of the client "X-CLEARTEXT2", "X-CLEARTEXT",#endif NULL};#ifdef __BORLANDC__# pragma argsused // unused arguments; applies only to next fn#endifSTATICDEF SecurityProvider *SecurityProvider:: findSecurityMechanism(char const *name, KeyEnvironment *env, IPAddress myAddress, IPAddress peerAddress){ // NOTE: RFC 2228 explicitly states (section3, AUTH subsection) // that names of security mechanisms are case *insensitive*. // Therefore, I use stricmp, not strcmp. if (0==missing_stricmp(name, "X-CLEARTEXT")) { // ClearTextSecurity does no transformations, therefore it // does not need to know whether it is client or server return new CleartextProvider(); } if (0==missing_stricmp(name, "X-CLEARTEXT2")) { return new CleartextProvider2(env != NULL /*isClient*/); }#ifndef NO_SEC_DE3S if (0==missing_stricmp(name, "X-SafeTP1")) { return new DE3S_Provider(env, myAddress, peerAddress); }#endif // name not found return NULL;}// get adat from source, give it to dest// return false if source has no more adats to givebool testAdatExchange(SecurityProvider *source, SecurityProvider *dest, bool echo){ if (source->control().hasOutgoingAdat()) { // get data from source DataBlock adat; source->control().getNextOutgoingAdat(adat); if (echo) { adat.print("ADAT"); } // give it to dest xassert(dest->control().expectingIncomingAdat()); dest->control().incomingAdat(adat); return true; } else { return false; }}void testAdatNegotiation(SecurityProvider *server, SecurityProvider *client, bool echo){ // do ADAT exchanges bool s2c, c2s; // server to client, client to server int s2c_ct=0, c2s_ct=0; // iteration counts do { s2c = testAdatExchange(server, client, echo); if (s2c) { s2c_ct++; } c2s = testAdatExchange(client, server, echo); if (c2s) { c2s_ct++; } } while (s2c || c2s); if (echo) { printf("(s2c_ct = %d, c2s_ct = %d) ", s2c_ct, c2s_ct); }}// -------------------- test code ----------------------#ifdef TEST_PROVIDER#include "datablok.h" // DataBlock#include "base64t.h" // base64pair, base64{enc,dec}ode#include "filkeydb.h" // KeyPolicy, FileKeyDB, KeyEnvironment#include <string.h> // memcmp#ifdef __BORLANDC__ #include <alloc.h> // heapwalk int heapBlocks() { xassert(heapcheck() == _HEAPOK); struct heapinfo hi; int ct=0; while (heapwalk(&hi) == _HEAPOK) { ct++; } return ct; }#else int heapBlocks() { return -1; }#endif// stub policy; silent and permissiveclass NullKeyPolicy : public KeyPolicy {public: virtual void keyReceived(IPAddress, DataBlock const &) {} virtual void keyMatched(IPAddress) {} virtual MismatchAction getMismatchAction( IPAddress, DataBlock const &, DataBlock const &, int, IPAddress const*) { return MA_ALLOW_ONCE; } virtual NewServerAction getNewServerAction( IPAddress, DataBlock const &) { return NSA_ACCEPT_ONCE; } void serverIPMismatch(IPAddress, IPAddress, DataBlock const &) {}};bool testSecurity(char const *name, int iters, bool echo){ NullKeyPolicy keyPolicy; FileKeyDB keyDB; KeyEnvironment keyEnv(keyPolicy, keyDB); // create security objects SecurityProvider *client = SecurityProvider:: findSecurityMechanism(name, &keyEnv /*(is client)*/, 0, 0); SecurityProvider *server = SecurityProvider:: findSecurityMechanism(name, NULL /*(is server)*/, 0, 0); if (!client || !server) { printf("mechanism %s not defined\n", name); return false; } if (echo) { printf("security negotiation: %s\n", name); } // do ADAT exchanges testAdatNegotiation(server, client, echo); if (echo) { printf("security data: %s\n", name); } // test both directions on the control channel if (!server->control().testWithEndpoint(client->control(), iters)) { return false; } // and both directions on the data channel, in all supported // protection levels int supportedLevels = 0; for (DataSecurityLevel level = DSL_CLEAR; level < DSL_ALL_LEVELS; level = (DataSecurityLevel)(level << 1)) { // only try the level if it is supported if (level & server->data().getSupportedProtLevels()) { supportedLevels++; // client and server both start a file... server->data().newFile(level); client->data().newFile(level); if (!server->data().testWithEndpoint(client->data(), iters)) { return false; } } } // check this because otherwise we might end up no-op'ing in here if (supportedLevels == 0) { printf("Mechanism %s has no supported protection levels!\n", name); return false; } // leaked on error but who cares, this is test code delete server; delete client; return true;}int startBlocks;void setup() { startBlocks = heapBlocks(); printf("startBlocks: %d\n", startBlocks); new char[4]; malloc(5); printf("now: %d\n", heapBlocks()); TransPair::initRandom(); readRandomSeed();}int doit(bool echo){ int const iters = 100;#if 1 // test all of the mechanisms for which we have implementations loopi(1000) { char const *name = SecurityProvider::Mechanisms[i]; if (!name) { break; } if (!testSecurity(name, iters, echo)) { return 4; // error } }#endif // 0 if (echo) { printf("base64\n"); } base64pair.test(iters); // test the other base64 interface, because lately // I've been uncovering bugs in it if (echo) { printf("base64 alternate interface\n"); } { DataBlock src("something to encode"); string b64 = base64encode(src); DataBlock dest; base64decode(dest, b64); xassert(src.getDataLen() == dest.getDataLen()); xassert(0==memcmp(src.getDataC(), dest.getDataC(), src.getDataLen())); } // decode something DataBlock block; base64decode(block, "MIIBigKBwQCXedjjp/PWgacA05dyaVXM" "tDZSLDK81U5AwjbumZEDY7swGz8so8po" "teTyRuIxu5N7HGd7aeDMtQ7tZYPsvrwW" "zF6BVi1sEHrDOHkAw/yIvdGBYuO52HHK" "5iX28Uht+PvQTCk4aA/sdDul+mPguTW/" "rsaqP6ldt3uPIyNBDYektjOceT2uoK00" "QYtGNmj15w9OkVl3MunlGcKOjc5N7FpR" "Zxo0sqCBm1qgG4BZ4LnKsxmfXoUJFgRl" "69HSKF/NQ/cCAQICgcB3ZPBph32O2Nrv" "u1KInt6MbUm88PaNic0QvHxGL7sQA8RQ" "g6FWB4cQPRVVFUPzgXZVpbP5F61HAOpH" "WDRlsA1UUq6mOkcXfrro7liAIb2WNirr" "pOtS8UbthFa/TwJP2KHw4wyvPYCA1o0p" "ajiD1eW0vxcI8yvYxK91UdZF72aMhOot" "gqkL4rUIanJj+MaPeF8Scbx/KJuzjVgH" "+GFb3LARG7gfh5EG8l+XQMt1WkbdupZa" "RUarX93YgyCYsfBKatM= "); return 0;}void teardown() { saveRandomSeed(); int endBlocks = heapBlocks(); printf("leaked blocks: %d\n", endBlocks-startBlocks); }#ifdef TEST_PROVIDER_MULTITHREADED #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <process.h> #include "nonport.h" #define NUM_THREADS 10 bool done[NUM_THREADS]; bool glbecho = false; void doit_wrapper(void *junk) { int myid = (int)junk; bool echo = glbecho; portableLock(); portableUnlock(); try { if (echo) { printf("Thread %i starting.\n", myid); } int retval = doit(echo); if (retval) { printf("FAILURE, doit in thread %i returned: %i\n", myid, retval); abort(); } if (echo) { printf("Thread %i completed successfully.\n", myid); } done[myid] = true; return; } catch (xBase &x) { printf("FAILURE, exception caught in thread %i: %s\n", myid, x.why()); abort(); } }#endifint main(){#ifdef TEST_PROVIDER_MULTITHREADED long start = GetTickCount(); setup(); for (int i = 0; i < NUM_THREADS; i++) { done[i] = false; if (_beginthread(&doit_wrapper, NULL, (void *)i) == -1) { printf("Error %i spawning thread. Exiting.\n", errno); abort(); } } bool alldone; do { alldone = true; for (int i = 0; i < NUM_THREADS; i++) alldone = (alldone && done[i]); Sleep(1); } while (!alldone); teardown(); long end = GetTickCount(); double secs = (end-start)/1000.0; printf("runtime: %8.3f threads: %i secs/thread:%8.3f\n", secs, NUM_THREADS, secs/NUM_THREADS);#else try { setup(); int retval = doit(true); if (retval) { printf("FAILURE, doit returned: %i\n", retval); return retval; } teardown(); } catch (xBase &x) { return printf("FAILURE, exception caught: %s\n", x.why()); }#endif printf("SUCCESS\n"); return 0;}#endif // TEST_PROVIDER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -