From 0ff7a48848945583f00671b1da9bbd9d16e1f33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 3 Nov 2011 20:18:00 +0100 Subject: [PATCH 1/3] Update stonesense --- plugins/stonesense | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/stonesense b/plugins/stonesense index afea122f2..b1b1414ab 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit afea122f225b309f1c7052766ff491c213cc421a +Subproject commit b1b1414ab7b46d9c408c9bdb1c561ee3684d86ed From af46b262b532400d1ff0ce176a969aa6d397193d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 4 Nov 2011 09:08:29 +0100 Subject: [PATCH 2/3] More init hardening. --- CMakeLists.txt | 2 +- library/Console-linux.cpp | 10 +++- library/Console-windows.cpp | 49 +++++++++++++++- library/Core.cpp | 63 +++++++++++++++++---- library/FakeSDL-linux.cpp | 5 ++ library/FakeSDL-windows.cpp | 3 + library/VersionInfoFactory.cpp | 10 +++- library/include/dfhack/Console.h | 1 + library/include/dfhack/Core.h | 11 ++-- library/include/dfhack/VersionInfoFactory.h | 3 +- plugins/devel/df2mc | 2 +- plugins/devel/rawdump.cpp | 10 ++-- plugins/prospector.cpp | 14 ++--- 13 files changed, 148 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1210b0c41..2a618aa4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,7 @@ set(DF_VERSION_MINOR "31") set(DF_VERSION_PATCH "25") set(DF_VERSION "${DF_VERSION_MAJOR}.${DF_VERSION_MINOR}.${DF_VERSION_PATCH}") -set(DFHACK_RELEASE "7d") +set(DFHACK_RELEASE "7e") ## where to install things (after the build is done, classic 'make install' or package structure) # the dfhack libraries will be installed here: diff --git a/library/Console-linux.cpp b/library/Console-linux.cpp index d74c48045..e15a6e9cb 100644 --- a/library/Console-linux.cpp +++ b/library/Console-linux.cpp @@ -640,7 +640,6 @@ bool Console::init(bool sharing) return false; } freopen("stdout.log", "w", stdout); - freopen("stderr.log", "w", stderr); d = new Private(); // make our own weird streams so our IO isn't redirected d->dfout_C = fopen("/dev/tty", "w"); @@ -690,11 +689,18 @@ int Console::printerr( const char* format, ... ) va_list args; lock_guard g(*wlock); int ret; - if(!inited) ret = -1; + // also mirror in error log + if(!inited) + { + va_start( args, format ); + ret = vfprintf(stderr, format, args); + va_end(args); + } else { va_start( args, format ); ret = d->vprinterr(format, args); + vfprintf(stderr, format, args); va_end(args); } return ret; diff --git a/library/Console-windows.cpp b/library/Console-windows.cpp index 92cfae5a6..4daab5c2f 100644 --- a/library/Console-windows.cpp +++ b/library/Console-windows.cpp @@ -378,6 +378,7 @@ namespace DFHack HANDLE console_in; HANDLE console_out; HWND ConsoleWindow; + HWND MainWindow; WORD default_attributes; // current state enum console_state @@ -402,7 +403,29 @@ Console::Console():std::ostream(0), std::ios(0) Console::~Console() { } +/* +// DOESN'T WORK - locks up DF! +void ForceForegroundWindow(HWND window) +{ + DWORD nForeThread, nAppThread; + + nForeThread = GetWindowThreadProcessId(GetForegroundWindow(), 0); + nAppThread = ::GetWindowThreadProcessId(window,0); + if(nForeThread != nAppThread) + { + AttachThreadInput(nForeThread, nAppThread, true); + BringWindowToTop(window); + ShowWindow(window,3); + AttachThreadInput(nForeThread, nAppThread, false); + } + else + { + BringWindowToTop(window); + ShowWindow(window,3); + } +} +*/ bool Console::init(bool) { d = new Private(); @@ -411,6 +434,21 @@ bool Console::init(bool) CONSOLE_SCREEN_BUFFER_INFO coninfo; FILE *fp; DWORD oldMode, newMode; + DWORD dwTheardId; + + HWND h = ::GetTopWindow(0 ); + while ( h ) + { + DWORD pid; + dwTheardId = ::GetWindowThreadProcessId( h,&pid); + if ( pid == GetCurrentProcessId() ) + { + // here h is the handle to the window + break; + } + h = ::GetNextWindow( h , GW_HWNDNEXT); + } + d->MainWindow = h; // Allocate a console! AllocConsole(); @@ -450,6 +488,8 @@ bool Console::init(bool) std::cin.tie(this); clear(); inited = true; + // DOESN'T WORK - locks up DF! + // ForceForegroundWindow(d->MainWindow); return true; } // FIXME: looks awfully empty, doesn't it? @@ -480,11 +520,18 @@ int Console::printerr( const char* format, ... ) va_list args; lock_guard g(*wlock); int ret; - if(!inited) ret = -1; + // also mirror in error log + if(!inited) + { + va_start( args, format ); + ret = vfprintf(stderr, format, args); + va_end(args); + } else { va_start( args, format ); ret = d->vprinterr(format, args); + vfprintf(stderr, format, args); va_end(args); } return ret; diff --git a/library/Core.cpp b/library/Core.cpp index 62f556e01..3a5df4541 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -174,6 +174,8 @@ void fIOthread(void * iodata) } string first = parts[0]; parts.erase(parts.begin()); + cerr << "Invoking: " << command << endl; + // let's see what we actually got if(first=="help" || first == "?") { @@ -351,7 +353,7 @@ void fIOthread(void * iodata) command_result res = plug_mgr->InvokeCommand(first, parts); if(res == CR_NOT_IMPLEMENTED) { - con.printerr("Invalid command.\n"); + con.printerr("%s is not a recognized command.\n", first.c_str()); clueless_counter ++; } /* @@ -393,6 +395,23 @@ Core::Core() misc_data_mutex=0; }; +void Core::fatal (std::string output, bool deactivate) +{ + stringstream out; + out << output ; + if(deactivate) + out << "DFHack will now deactivate.\n"; + if(con.isInited()) + { + con.printerr("%s", out.str().c_str()); + } + fprintf(stderr, "%s\n", out.str().c_str()); +#ifndef LINUX_BUILD + out << "Check file stderr.log for details\n"; + MessageBox(0,out.str().c_str(),"DFHack error!", MB_OK | MB_ICONERROR); +#endif +} + bool Core::Init() { if(started) @@ -406,30 +425,48 @@ bool Core::Init() #else const char * path = "hack\\Memory.xml"; #endif - vif = new DFHack::VersionInfoFactory(path); + vif = new DFHack::VersionInfoFactory(); + cerr << "Identifying DF version.\n"; + try + { + vif->loadFile(path); + } + catch(Error::All & err) + { + std::stringstream out; + out << "Error while reading Memory.xml:\n"; + out << err.what() << std::endl; + delete vif; + vif = nullptr; + errorstate = true; + fatal(out.str(), true); + return false; + } p = new DFHack::Process(vif); vinfo = p->getDescriptor(); if(!vinfo || !p->isIdentified()) { - cerr << "Not a known DF version. DFHack will now deactivate.\n"; + fatal ("Not a known DF version.\n", true); errorstate = true; delete p; p = NULL; return false; } + cerr << "Version: " << vinfo->getVersion() << endl; + cerr << "Initializing Console.\n"; // init the console. Gui * g = getGui(); - if(g->init) + bool is_text_mode = false; + if(g->init && g->init->graphics.flags.is_set(GRAPHICS_TEXT)) { - if(g->init->graphics.flags.is_set(GRAPHICS_TEXT)) - { - con.init(true); - } - else con.init(false); + is_text_mode = true; } - else con.init(false); + if(con.init(is_text_mode)) + cerr << "Console is running.\n"; + else + fatal ("Console has failed to initialize!\n", false); // dump offsets to a file std::ofstream dump("offsets.log"); @@ -444,18 +481,22 @@ bool Core::Init() AccessMutex = new mutex(); misc_data_mutex=new mutex(); core_cond = new Core::Cond(); + cerr << "Initializing Plugins.\n"; // create plugin manager plug_mgr = new PluginManager(this); + cerr << "Starting IO thread.\n"; // create IO thread IODATA *temp = new IODATA; temp->core = this; temp->plug_mgr = plug_mgr; thread * IO = new thread(fIOthread, (void *) temp); + cerr << "Starting DF input capture thread.\n"; // set up hotkey capture HotkeyMutex = new mutex(); HotkeyCond = new condition_variable(); thread * HK = new thread(fHKthread, (void *) temp); started = true; + cerr << "DFHack is running.\n"; return true; } /// sets the current hotkey command @@ -565,6 +606,8 @@ int Core::Update() // FIXME: needs to terminate the IO threads and properly dismantle all the machinery involved. int Core::Shutdown ( void ) { + if(errorstate) + return true; errorstate = 1; if(plug_mgr) { diff --git a/library/FakeSDL-linux.cpp b/library/FakeSDL-linux.cpp index a5f34e5f2..59ae1bbd4 100644 --- a/library/FakeSDL-linux.cpp +++ b/library/FakeSDL-linux.cpp @@ -132,6 +132,11 @@ DFhackCExport int wgetch(WINDOW *win) static int (*_SDL_Init)(uint32_t flags) = 0; DFhackCExport int SDL_Init(uint32_t flags) { + // reroute stderr + freopen("stderr.log", "w", stderr); + // we don't reroute stdout until we figure out if this should be done at all + // See: Console-linux.cpp + // find real functions _SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init"); _SDL_Quit = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_Quit"); diff --git a/library/FakeSDL-windows.cpp b/library/FakeSDL-windows.cpp index f1abe076a..ee569c83c 100644 --- a/library/FakeSDL-windows.cpp +++ b/library/FakeSDL-windows.cpp @@ -694,6 +694,9 @@ DFhackCExport uint32_t SDL_ThreadID(void) // FIXME: this has to be thread-safe. bool FirstCall() { + // reroute stdout and stderr + freopen("stdout.log", "w", stdout); + freopen("stderr.log", "w", stderr); HMODULE realSDLlib = LoadLibrary("SDLreal.dll"); if(!realSDLlib) { diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index 2c9bb3201..b2ec00d96 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -97,13 +97,16 @@ inline bool operator>=(const triple<_T1, _T2, _T3>& __x, const triple<_T1, _T2, return !(__x < __y); } -VersionInfoFactory::VersionInfoFactory(string path_to_xml) +VersionInfoFactory::VersionInfoFactory() { error = false; - loadFile(path_to_xml); } VersionInfoFactory::~VersionInfoFactory() +{ + clear(); +} +void VersionInfoFactory::clear(void) { // for each stored version, delete for(uint32_t i = 0; i < versions.size();i++) @@ -111,6 +114,8 @@ VersionInfoFactory::~VersionInfoFactory() delete versions[i]; } versions.clear(); + knownVersions.clear(); + error = false; } VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash) @@ -768,5 +773,6 @@ bool VersionInfoFactory::loadFile(string path_to_xml) } } error = false; + std::cerr << "Loaded " << versions.size() << " DF versions." << std::endl; return true; } diff --git a/library/include/dfhack/Console.h b/library/include/dfhack/Console.h index f6b09f9b2..e4e2c44f7 100644 --- a/library/include/dfhack/Console.h +++ b/library/include/dfhack/Console.h @@ -164,6 +164,7 @@ namespace DFHack //void beep (void); /// A simple line edit (raw mode) int lineedit(const std::string& prompt, std::string& output, CommandHistory & history ); + bool isInited (void) { return inited; }; private: Private * d; tthread::mutex * wlock; diff --git a/library/include/dfhack/Core.h b/library/include/dfhack/Core.h index 2cc9ff149..e4e2171ab 100644 --- a/library/include/dfhack/Core.h +++ b/library/include/dfhack/Core.h @@ -126,10 +126,10 @@ namespace DFHack /// removes the hotkey command and gives it to the caller thread std::string getHotkeyCmd( void ); - /// adds a named pointer (for later or between plugins) - void RegisterData(void *p,std::string key); - /// returns a named pointer. - void *GetData(std::string key); + /// adds a named pointer (for later or between plugins) + void RegisterData(void *p,std::string key); + /// returns a named pointer. + void *GetData(std::string key); DFHack::Process * p; DFHack::VersionInfo * vinfo; @@ -143,6 +143,9 @@ namespace DFHack bool ncurses_wgetch(int in, int & out); Core(Core const&); // Don't Implement void operator=(Core const&); // Don't implement + // report error to user while failing + void fatal (std::string output, bool will_deactivate); + // 1 = fatal failure bool errorstate; // regulate access to DF struct Cond; diff --git a/library/include/dfhack/VersionInfoFactory.h b/library/include/dfhack/VersionInfoFactory.h index ab3131305..0803a2c7f 100644 --- a/library/include/dfhack/VersionInfoFactory.h +++ b/library/include/dfhack/VersionInfoFactory.h @@ -39,7 +39,7 @@ namespace DFHack { friend class ProcessEnumerator; public: - VersionInfoFactory(std::string path_to_xml); + VersionInfoFactory(); ~VersionInfoFactory(); // memory info entries loaded from a file bool loadFile( std::string path_to_xml); @@ -47,6 +47,7 @@ namespace DFHack VersionInfo * getVersionInfoByMD5(std::string md5string); VersionInfo * getVersionInfoByPETimestamp(uint32_t timestamp); std::vector versions; + void clear( void ); private: void ParseVTable(TiXmlElement* vtable, VersionInfo* mem); void ParseBase (TiXmlElement* base, VersionInfo* mem); diff --git a/plugins/devel/df2mc b/plugins/devel/df2mc index 0f6389f41..ea35678fc 160000 --- a/plugins/devel/df2mc +++ b/plugins/devel/df2mc @@ -1 +1 @@ -Subproject commit 0f6389f4121d6cf3d447fb72a5b561d8d66b0de8 +Subproject commit ea35678fc408dadef196ed82f61c00709a23b914 diff --git a/plugins/devel/rawdump.cpp b/plugins/devel/rawdump.cpp index ba1edde22..0e6cac5bd 100644 --- a/plugins/devel/rawdump.cpp +++ b/plugins/devel/rawdump.cpp @@ -56,13 +56,13 @@ DFhackCExport command_result rawdump_i (Core * c, vector & parameters) { if( index < mats->df_inorganic->size()) { - df_inorganic_material * mat = mats->df_inorganic->at(index); + df_inorganic_type * mat = mats->df_inorganic->at(index); // dump single material con.print("%-3d : [%s] %s\n", index, - mat->Inorganic_ID.c_str(), - mat->STATE_NAME_SOLID.c_str()); - con.print("MAX EDGE: %d\n",mat->MAX_EDGE); + mat->ID.c_str(), + mat->mat.state_name[DFHack::state_solid].c_str()); + con.print("MAX EDGE: %d\n",mat->mat.MAX_EDGE); } else { @@ -74,7 +74,7 @@ DFhackCExport command_result rawdump_i (Core * c, vector & parameters) // dump all materials for(int i = 0; i < mats->df_inorganic->size();i++) { - con.print("%-3d : %s\n",i,mats->df_inorganic->at(i)->Inorganic_ID.c_str()); + con.print("%-3d : %s\n",i,mats->df_inorganic->at(i)->ID.c_str()); } } c->Resume(); diff --git a/plugins/prospector.cpp b/plugins/prospector.cpp index ba20dad2d..5e642ed5a 100644 --- a/plugins/prospector.cpp +++ b/plugins/prospector.cpp @@ -198,7 +198,7 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector & par DFHack::Maps *maps = c->getMaps(); if (!maps->Start()) { - con << "Cannot get map info!" << std::endl; + con.printerr("Cannot get map info!\n"); c->Resume(); return CR_FAILURE; } @@ -208,13 +208,13 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector & par DFHack::Materials *mats = c->getMaterials(); if (!mats->df_inorganic) { - con << "Unable to read inorganic material definitons!" << std::endl; + con.printerr("Unable to read inorganic material definitons!\n"); c->Resume(); return CR_FAILURE; } if (showPlants && !mats->df_organic) { - con << "Unable to read organic material definitons; plants won't be listed!" << std::endl; + con.printerr("Unable to read organic material definitons; plants won't be listed!\n"); showPlants = false; } @@ -234,21 +234,19 @@ DFhackCExport command_result prospector (DFHack::Core * c, vector & par if (!(showSlade && maps->ReadGlobalFeatures(globalFeatures))) { - con << "Unable to read global features; slade won't be listed!" << std::endl; + con.printerr("Unable to read global features; slade won't be listed!\n"); } if (!maps->ReadLocalFeatures(localFeatures)) { - con << "Unable to read local features; adamantine " - << (showTemple ? "and demon temples " : "") - << "won't be listed!" << std::endl; + con.printerr("Unable to read local features; adamantine and demon temples won't be listed.\n" ); } uint32_t vegCount = 0; DFHack::Vegetation *veg = c->getVegetation(); if (showPlants && !veg->Start()) { - con << "Unable to read vegetation; plants won't be listed!" << std::endl; + con.printerr("Unable to read vegetation; plants won't be listed!\n" ); } for(uint32_t z = 0; z < z_max; z++) From 321f9e589ea323ec6456fffe53ec17a2bfb66d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 4 Nov 2011 09:33:33 +0100 Subject: [PATCH 3/3] Switched out md5 implementation for a different one. --- library/depends/md5/md5.cpp | 505 ++++++++++++----------------- library/depends/md5/md5.h | 116 ++----- library/depends/md5/md5wrapper.cpp | 20 +- library/depends/md5/md5wrapper.h | 5 - 4 files changed, 245 insertions(+), 401 deletions(-) diff --git a/library/depends/md5/md5.cpp b/library/depends/md5/md5.cpp index c791893a4..e161868e2 100644 --- a/library/depends/md5/md5.cpp +++ b/library/depends/md5/md5.cpp @@ -1,332 +1,239 @@ /* - * This is the C++ implementation of the MD5 Message-Digest - * Algorithm desrcipted in RFC 1321. - * I translated the C code from this RFC to C++. - * There is now warranty. - * - * Feb. 12. 2005 - * Benjamin Grüdelbach + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. */ -/* - * Changed unsigned long int types into uint32_t to make this work on 64bit systems. - * Sep. 5. 2009 - * Petr Mrázek - */ - -/* - * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - * rights reserved. - * - * License to copy and use this software is granted provided that it - * is identified as the "RSA Data Security, Inc. MD5 Message-Digest - * Algorithm" in all material mentioning or referencing this software - * or this function. - * - * License is also granted to make and use derivative works provided - * that such works are identified as "derived from the RSA Data - * Security, Inc. MD5 Message-Digest Algorithm" in all material - * mentioning or referencing the derived work. - * - * RSA Data Security, Inc. makes no representations concerning either - * the merchantability of this software or the suitability of this - * software for any particular purpose. It is provided "as is" - * without express or implied warranty of any kind. - * - * These notices must be retained in any copies of any part of this - * documentation and/or software. - */ - -//md5 class include +#include /* for memcpy() */ #include "md5.h" -// Constants for MD5Transform routine. -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* -FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. -*/ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (unsigned long int)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (unsigned long int)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (unsigned long int)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (unsigned long int)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. */ -void MD5::MD5Init (MD5_CTX *context) -{ - context->count[0] = context->count[1] = 0; - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - +#ifndef HIGHFIRST +#define byteReverse(buf, len) /* Nothing */ +#else /* - MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. -*/ -void MD5::MD5Update (MD5_CTX *context, unsigned char *input, unsigned int inputLen) + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(unsigned char *buf, unsigned longs) { - unsigned int i, index, partLen; - - /* Compute number of bytes mod 64 */ - index = (unsigned int)((context->count[0] >> 3) & 0x3F); - - /* Update number of bits */ - if ( (context->count[0] += ((unsigned long int)inputLen << 3)) - < ((unsigned long int)inputLen << 3)) - context->count[1]++; - - context->count[1] += ((unsigned long int)inputLen >> 29); - partLen = 64 - index; - - /* - * Transform as many times as possible. - */ - if (inputLen >= partLen) - { - MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen); - MD5Transform (context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); - - index = 0; - } - else - i = 0; - - /* Buffer remaining input */ - MD5_memcpy ((POINTER)&context->buffer[index], - (POINTER)&input[i], - inputLen-i); + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); } +#endif /* - * MD5 finalization. Ends an MD5 message-digest operation, writing the - * the message digest and zeroizing the context. + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. */ -void MD5::MD5Final (unsigned char digest[16], MD5_CTX *context) +void MD5Init(MD5Context *ctx) { - unsigned char bits[8]; - unsigned int index, padLen; + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* - * Pad out to 56 mod 64. - */ - index = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - MD5Update (context, bits, 8); - - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* - * Zeroize sensitive information. - */ - MD5_memset ((POINTER)context, 0, sizeof (*context)); + ctx->bits[0] = 0; + ctx->bits[1] = 0; } /* - * MD5 basic transformation. Transforms state based on block. + * Update context to reflect the concatenation of another buffer full + * of bytes. */ -void MD5::MD5Transform (uint32_t state[4], unsigned char block[64]) +void MD5Update( MD5Context *ctx, unsigned char *buf, unsigned len) { - uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* - * Zeroize sensitive information. - */ - MD5_memset ((POINTER)x, 0, sizeof (x)); + uint32_t t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + if (t) + { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) + { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + while (len >= 64) + { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); } /* - * Encodes input (unsigned long int) into output (unsigned char). Assumes len is - * a multiple of 4. + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) */ -void MD5::Encode (unsigned char *output, uint32_t *input, unsigned int len) +void MD5Final(unsigned char digest[16], MD5Context *ctx) { - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } + else + { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32_t *) ctx->in)[14] = ctx->bits[0]; + ((uint32_t *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32_t *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ } -/* - * Decodes input (unsigned char) into output (unsigned long int). Assumes len is - * a multiple of 4. - */ -void MD5::Decode (uint32_t *output, unsigned char *input, unsigned int len) -{ - unsigned int i, j; - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((uint32_t)input[j]) | - (((uint32_t)input[j+1]) << 8) | - (((uint32_t)input[j+2]) << 16) | - (((uint32_t)input[j+3]) << 24); -} +/* The four core functions - F1 is optimized somewhat */ -/* - * Note: Replace "for loop" with standard memcpy if possible. - */ -void MD5::MD5_memcpy (POINTER output, POINTER input, unsigned int len) -{ - unsigned int i; +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) - for (i = 0; i < len; i++) - output[i] = input[i]; -} +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) /* - * Note: Replace "for loop" with standard memset if possible. + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. */ -void MD5::MD5_memset (POINTER output,int value,unsigned int len) +void MD5Transform(uint32_t buf[4], uint32_t in[16]) { - unsigned int i; - for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; } - -/* - * EOF - */ diff --git a/library/depends/md5/md5.h b/library/depends/md5/md5.h index 1c4b59690..0a04051bb 100644 --- a/library/depends/md5/md5.h +++ b/library/depends/md5/md5.h @@ -1,92 +1,36 @@ -/* - * This is the C++ implementation of the MD5 Message-Digest - * Algorithm desrcipted in RFC 1321. - * I translated the C code from this RFC to C++. - * There is now warranty. - * - * Feb. 12. 2005 - * Benjamin Grüdelbach - */ - -/* - * Changed unsigned long int types into uint32_t to make this work on 64bit systems. - * Sep. 5. 2009 - * Petr Mrázek - */ - -/* - * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - * rights reserved. - * - * License to copy and use this software is granted provided that it - * is identified as the "RSA Data Security, Inc. MD5 Message-Digest - * Algorithm" in all material mentioning or referencing this software - * or this function. - * - * License is also granted to make and use derivative works provided - * that such works are identified as "derived from the RSA Data - * Security, Inc. MD5 Message-Digest Algorithm" in all material - * mentioning or referencing the derived work. - * - * RSA Data Security, Inc. makes no representations concerning either - * the merchantability of this software or the suitability of this - * software for any particular purpose. It is provided "as is" - * without express or implied warranty of any kind. - * - * These notices must be retained in any copies of any part of this - * documentation and/or software. - */ - -//---------------------------------------------------------------------- -//include protection -#ifndef MD5_H -#define MD5_H +#pragma once + +/* The following tests optimise behaviour on little-endian + machines, where there is no need to reverse the byte order + of 32 bit words in the MD5 computation. By default, + HIGHFIRST is defined, which indicates we're running on a + big-endian (most significant byte first) machine, on which + the byteReverse function in md5.c must be invoked. However, + byteReverse is coded in such a way that it is an identity + function when run on a little-endian machine, so calling it + on such a platform causes no harm apart from wasting time. + If the platform is known to be little-endian, we speed + things up by undefining HIGHFIRST, which defines + byteReverse as a null macro. Doing things in this manner + insures we work on new platforms regardless of their byte + order. */ + +#define HIGHFIRST + +#ifdef __i386__ +#undef HIGHFIRST +#endif -//---------------------------------------------------------------------- -//STL includes -#include #include -//---------------------------------------------------------------------- -//typedefs -typedef unsigned char *POINTER; -/* - * MD5 context. - */ -typedef struct +struct MD5Context { - uint32_t state[4]; /* state (ABCD) */ - uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} MD5_CTX; - -/* - * MD5 class - */ -class MD5 -{ - - private: - - void MD5Transform (uint32_t state[4], unsigned char block[64]); - void Encode (unsigned char*, uint32_t*, unsigned int); - void Decode (uint32_t*, unsigned char*, unsigned int); - void MD5_memcpy (POINTER, POINTER, unsigned int); - void MD5_memset (POINTER, int, unsigned int); - - public: - - void MD5Init (MD5_CTX*); - void MD5Update (MD5_CTX*, unsigned char*, unsigned int); - void MD5Final (unsigned char [16], MD5_CTX*); - - MD5(){}; + uint32_t buf[4]; + uint32_t bits[2]; + unsigned char in[64]; }; -//---------------------------------------------------------------------- -//End of include protection -#endif - -/* - * EOF - */ +extern void MD5Init( MD5Context *ctx); +extern void MD5Update( MD5Context *ctx, unsigned char *buf, unsigned len); +extern void MD5Final(unsigned char digest[16], MD5Context *ctx); +extern void MD5Transform(uint32_t buf[4], uint32_t in[16]); diff --git a/library/depends/md5/md5wrapper.cpp b/library/depends/md5/md5wrapper.cpp index 68ac6fef5..e12b65780 100644 --- a/library/depends/md5/md5wrapper.cpp +++ b/library/depends/md5/md5wrapper.cpp @@ -38,18 +38,18 @@ */ std::string md5wrapper::hashit(std::string text) { - MD5_CTX ctx; + MD5Context ctx; //init md5 - md5->MD5Init(&ctx); + MD5Init(&ctx); //update with our string - md5->MD5Update(&ctx, + MD5Update(&ctx, (unsigned char*)text.c_str(), text.length()); //create the hash unsigned char buff[16] = ""; - md5->MD5Final((unsigned char*)buff,&ctx); + MD5Final((unsigned char*)buff,&ctx); //converte the hash to a string and return it return convToString(buff); @@ -80,14 +80,12 @@ std::string md5wrapper::convToString(unsigned char *bytes) //constructor md5wrapper::md5wrapper() { - md5 = new MD5(); } //destructor md5wrapper::~md5wrapper() { - delete md5; } /* @@ -111,7 +109,7 @@ std::string md5wrapper::getHashFromString(std::string text) std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length, char * first_kb) { FILE *file; - MD5_CTX context; + MD5Context context; int len; int saved = 0; @@ -124,7 +122,7 @@ std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length, } length = 0; //init md5 - md5->MD5Init (&context); + MD5Init (&context); //read the filecontent while (1) @@ -148,18 +146,18 @@ std::string md5wrapper::getHashFromFile(std::string filename, uint32_t & length, } if(feof(file)) { - md5->MD5Update (&context, buffer, len); + MD5Update (&context, buffer, len); break; } } - md5->MD5Update (&context, buffer, len); + MD5Update (&context, buffer, len); } /* generate hash, close the file and return the hash as std::string */ - md5->MD5Final (digest, &context); + MD5Final (digest, &context); fclose (file); return convToString(digest); } diff --git a/library/depends/md5/md5wrapper.h b/library/depends/md5/md5wrapper.h index 38197faf1..1a41192a1 100644 --- a/library/depends/md5/md5wrapper.h +++ b/library/depends/md5/md5wrapper.h @@ -24,14 +24,9 @@ #include #include -//forwards -class MD5; - class md5wrapper { private: - MD5 *md5; - /* * internal hash function, calling * the basic methods from md5.h