Merge branch 'login_save_crypt'

This commit is contained in:
Jyrki Vesterinen 2017-05-22 20:10:09 +03:00
commit 56433d12a3
48 changed files with 578 additions and 994 deletions

View file

@ -50,6 +50,9 @@ before_install:
install:
- travis_wait ./utils/travis/install_deps.sh
- if [ "$TRAVIS_OS_NAME" = osx ]; then
export CXXFLAGS="-I/usr/local/opt/openssl/include $CFLAGS" LDFLAGS="-L/usr/local/opt/openssl/lib $LDFLAGS";
fi
script:
- ./utils/travis/check_utf8.sh

View file

@ -74,6 +74,7 @@ else()
find_package(SDL2 2.0.4 REQUIRED)
endif()
find_package(Crypto 1.0 REQUIRED)
find_package(Boost 1.48 REQUIRED COMPONENTS iostreams program_options regex system thread random)
# no, gettext executables are not required when NLS is deactivated
@ -642,7 +643,7 @@ if(ENABLE_GAME OR ENABLE_TESTS)
pkg_check_modules( CAIRO REQUIRED cairo>=1.10 )
pkg_check_modules( PANGOCAIRO REQUIRED pangocairo>=1.21.3 )
pkg_check_modules( FONTCONFIG REQUIRED fontconfig>=2.4.1 )
pkg_check_modules( SYSTEMD systemd )
pkg_check_modules( SYSTEMD systemd )
endif(NOT MSVC)
endif(ENABLE_GAME OR ENABLE_TESTS)

View file

@ -37,6 +37,7 @@ order to build Wesnoth:
* Vorbisfile
* libbz2
* libz
* libcrypto (from OpenSSL)
The following libraries are optional dependencies that enable additional
features:

View file

@ -363,6 +363,7 @@ if env["prereqs"]:
have_server_prereqs = (\
CheckIEEE754(conf) & \
conf.CheckCPlusPlus(gcc_version = "4.8") & \
conf.CheckLib("libcrypto") & \
conf.CheckBoost("iostreams", require_version = boost_version) & \
conf.CheckBoostIostreamsGZip() & \
conf.CheckBoostIostreamsBZip2() & \

11
cmake/FindCrypto.cmake Normal file
View file

@ -0,0 +1,11 @@
# OpenSSL crypto library
find_path(CRYPTO_INCLUDE_DIR openssl/md5.h)
find_library(CRYPTO_LIBRARY crypto)
# handle the QUIETLY and REQUIRED arguments and set XXX_FOUND to TRUE if all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CRYPTO DEFAULT_MSG CRYPTO_LIBRARY CRYPTO_INCLUDE_DIR)
mark_as_advanced(CRYPTO_INCLUDE_DIR CRYPTO_LIBRARY)

View file

@ -52,7 +52,7 @@
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>..\..\..\external\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Shlwapi.lib;libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -70,7 +70,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>..\..\..\external\lib</AdditionalLibraryDirectories>
<AdditionalDependencies>Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Shlwapi.lib;libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
@ -85,7 +85,6 @@
<ClInclude Include="..\..\src\campaign_server\campaign_server.hpp" />
<ClInclude Include="..\..\src\campaign_server\control.hpp" />
<ClInclude Include="..\..\src\hash.hpp" />
<ClInclude Include="..\..\src\md5.hpp" />
<ClInclude Include="..\..\src\server\server_base.hpp" />
<ClInclude Include="..\..\src\server\simple_wml.hpp" />
</ItemGroup>
@ -105,9 +104,6 @@
<ClCompile Include="..\..\src\hash.cpp">
<ObjectFileName>$(IntDir)</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\md5.cpp">
<ObjectFileName>$(IntDir)</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\server\server_base.cpp">
<ObjectFileName>$(IntDir)Server\</ObjectFileName>
</ClCompile>

View file

@ -34,7 +34,6 @@
<Filter>Campaign_Server</Filter>
</ClInclude>
<ClInclude Include="..\..\src\hash.hpp" />
<ClInclude Include="..\..\src\md5.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\addon\validation.cpp">
@ -56,6 +55,5 @@
<Filter>Campaign_Server</Filter>
</ClCompile>
<ClCompile Include="..\..\src\hash.cpp" />
<ClCompile Include="..\..\src\md5.cpp" />
</ItemGroup>
</Project>

View file

@ -137,7 +137,7 @@
</ResourceCompile>
<Link>
<AdditionalOptions>/SAFESEH:NO %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\..\..\external\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>MSVCR90;MSVCRT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -177,7 +177,7 @@
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
<Link>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\..\..\external\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@ -218,7 +218,7 @@
<PreprocessorDefinitions>_MSC_VER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Link>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;Debug\liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;Debug\liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)test.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\external\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -258,7 +258,7 @@
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
<Link>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;Release\liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;Release\liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)test.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\..\external\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
@ -305,7 +305,7 @@
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
<Link>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>SDL2main.lib;SDL2.lib;SDL2_image.lib;SDL2_ttf.lib;SDL2_mixer.lib;SDL2_net.lib;libeay32.lib;cairo.lib;winmm.lib;ws2_32.lib;pango-1.0.lib;pangocairo-1.0.lib;gobject-2.0.lib;glib-2.0.lib;libpng.lib;$(IntDir)liblua.lib;Shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\..\..\external\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@ -743,6 +743,7 @@
<ClCompile Include="..\..\src\config_cache.cpp" />
<ClCompile Include="..\..\src\controller_base.cpp" />
<ClCompile Include="..\..\src\countdown_clock.cpp" />
<ClCompile Include="..\..\src\preferences\credentials.cpp" />
<ClCompile Include="..\..\src\cursor.cpp" />
<ClCompile Include="..\..\src\desktop\clipboard.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)Desktop\</ObjectFileName>
@ -2482,7 +2483,6 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|Win32'">$(IntDir)Map\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|Win32'">$(IntDir)Map\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\md5.cpp" />
<ClCompile Include="..\..\src\menu_events.cpp" />
<ClCompile Include="..\..\src\minimap.cpp" />
<ClCompile Include="..\..\src\mouse_events.cpp" />
@ -3285,13 +3285,6 @@
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|Win32'">$(IntDir)utils\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|Win32'">$(IntDir)utils\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\utils\sha1.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)utils\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='ReleaseDEBUG|Win32'">$(IntDir)utils\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)utils\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Debug|Win32'">$(IntDir)utils\</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Test_Release|Win32'">$(IntDir)utils\</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\src\variable.cpp" />
<ClCompile Include="..\..\src\variable_info.cpp" />
<ClCompile Include="..\..\src\video.cpp" />
@ -3444,6 +3437,7 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\preferences\credentials.hpp" />
<ClInclude Include="..\..\src\about.hpp" />
<ClInclude Include="..\..\src\actions\advancement.hpp" />
<ClInclude Include="..\..\src\actions\attack.hpp" />
@ -3837,7 +3831,6 @@
<ClInclude Include="..\..\src\map\location.hpp" />
<ClInclude Include="..\..\src\map\map.hpp" />
<ClInclude Include="..\..\src\map_command_handler.hpp" />
<ClInclude Include="..\..\src\md5.hpp" />
<ClInclude Include="..\..\src\menu_events.hpp" />
<ClInclude Include="..\..\src\minimap.hpp" />
<ClInclude Include="..\..\src\mouse_events.hpp" />
@ -3997,7 +3990,6 @@
<ClInclude Include="..\..\src\utils\name_generator.hpp" />
<ClInclude Include="..\..\src\utils\name_generator_factory.hpp" />
<ClInclude Include="..\..\src\utils\reference_counter.hpp" />
<ClInclude Include="..\..\src\utils\sha1.hpp" />
<ClInclude Include="..\..\src\utils\smart_list.hpp" />
<ClInclude Include="..\..\src\variable.hpp" />
<ClInclude Include="..\..\src\variable_info.hpp" />

View file

@ -998,9 +998,6 @@
<ClCompile Include="..\..\src\utils\name_generator_factory.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\utils\sha1.cpp">
<Filter>utils</Filter>
</ClCompile>
<ClCompile Include="..\..\src\serialization\tag.cpp">
<Filter>serialization</Filter>
</ClCompile>
@ -1435,7 +1432,6 @@
<ClCompile Include="..\..\src\key.cpp" />
<ClCompile Include="..\..\src\language.cpp" />
<ClCompile Include="..\..\src\lua_jailbreak_exception.cpp" />
<ClCompile Include="..\..\src\md5.cpp" />
<ClCompile Include="..\..\src\menu_events.cpp" />
<ClCompile Include="..\..\src\minimap.cpp" />
<ClCompile Include="..\..\src\mouse_events.cpp" />
@ -1536,6 +1532,9 @@
<ClCompile Include="..\..\src\game_events\wmi_manager.cpp">
<Filter>Game_Events</Filter>
</ClCompile>
<ClCompile Include="..\..\src\preferences\credentials.cpp">
<Filter>Preferences</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\addon\client.hpp">
@ -2474,9 +2473,6 @@
<ClInclude Include="..\..\src\utils\reference_counter.hpp">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\utils\sha1.hpp">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\utils\smart_list.hpp">
<Filter>utils</Filter>
</ClInclude>
@ -2845,7 +2841,6 @@
<ClInclude Include="..\..\src\language.hpp" />
<ClInclude Include="..\..\src\lua_jailbreak_exception.hpp" />
<ClInclude Include="..\..\src\map_command_handler.hpp" />
<ClInclude Include="..\..\src\md5.hpp" />
<ClInclude Include="..\..\src\menu_events.hpp" />
<ClInclude Include="..\..\src\minimap.hpp" />
<ClInclude Include="..\..\src\mouse_events.hpp" />
@ -2981,6 +2976,9 @@
<ClInclude Include="..\..\src\game_events\wmi_manager.hpp">
<Filter>Game_Events</Filter>
</ClInclude>
<ClInclude Include="..\..\src\preferences\credentials.hpp">
<Filter>Preferences</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\tests\test_sdl_utils.hpp">
@ -3002,4 +3000,4 @@
<Filter>Tests\Utils</Filter>
</CustomBuild>
</ItemGroup>
</Project>
</Project>

View file

@ -28,6 +28,7 @@ hotkey/hotkey_item.cpp
hotkey/hotkey_manager.cpp
image.cpp
image_modifications.cpp
preferences/credentials.cpp
preferences/general.cpp
joystick.cpp
key.cpp

View file

@ -11,7 +11,6 @@ hash.cpp
log.cpp
map/location.cpp
map/map.cpp
md5.cpp
mt_rng.cpp
seed_rng.cpp
serialization/binary_or_text.cpp

View file

@ -388,7 +388,6 @@ units/unit.cpp
utils/context_free_grammar_generator.cpp
utils/markov_generator.cpp
utils/name_generator_factory.cpp
utils/sha1.cpp
variable.cpp
variable_info.cpp
wesnothd_connection.cpp

View file

@ -93,6 +93,7 @@ set(common-external-libs
set(game-external-libs
${common-external-libs}
${CRYPTO_LIBRARY}
${Boost_SYSTEM_LIBRARIES}
${Boost_RANDOM_LIBRARY}
${Boost_THREAD_LIBRARY}

View file

@ -70,7 +70,7 @@ namespace {
/* Secure password storage functions */
bool authenticate(config& campaign, const config::attribute_value& passphrase)
{
return utils::create_hash(passphrase, campaign["passsalt"]) == campaign["passhash"];
return utils::md5(passphrase, campaign["passsalt"]).hex_digest() == campaign["passhash"];
}
std::string generate_salt(size_t len)
@ -92,7 +92,7 @@ void set_passphrase(config& campaign, std::string passphrase)
{
std::string salt = generate_salt(16);
campaign["passsalt"] = salt;
campaign["passhash"] = utils::create_hash(passphrase, salt);
campaign["passhash"] = utils::md5(passphrase, salt).hex_digest();
}
} // end anonymous namespace

View file

@ -19,6 +19,7 @@
#include "log.hpp"
#include "map_command_handler.hpp"
#include "chat_command_handler.hpp"
#include "preferences/credentials.hpp"
#include "preferences/general.hpp"
#include "preferences/game.hpp"

View file

@ -19,7 +19,7 @@
#include "gettext.hpp"
#include "game_config.hpp"
#include "log.hpp"
#include "utils/sha1.hpp"
#include "hash.hpp"
#include "serialization/binary_or_text.hpp"
#include "serialization/parser.hpp"
#include "serialization/string_utils.hpp"
@ -166,7 +166,7 @@ void config_cache::read_cache(const std::string& file_path, config& cfg)
// Use a hash for a shorter display of the defines.
const std::string fname = cache_path + "/" +
cache_file_prefix_ +
sha1_hash(defines_string.str()).display();
utils::sha1(defines_string.str()).hex_digest();
const std::string fname_checksum = fname + ".checksum" + extension;
filesystem::file_tree_checksum dir_checksum;

View file

@ -24,6 +24,7 @@
#include "mp_ui_alerts.hpp"
#include "serialization/string_utils.hpp"
#include "color.hpp"
#include "preferences/credentials.hpp"
#include <SDL_timer.h>

View file

@ -73,6 +73,7 @@ std::string get_dir(const std::string &dir);
// The location of various important files:
std::string get_prefs_file();
std::string get_credentials_file();
std::string get_default_prefs_file();
std::string get_save_index_file();
std::string get_saves_dir();

View file

@ -34,6 +34,11 @@ std::string get_prefs_file()
return get_user_config_dir() + "/preferences";
}
std::string get_credentials_file()
{
return get_user_config_dir() + "/credentials";
}
std::string get_default_prefs_file()
{
#ifdef HAS_RELATIVE_DEFPREF

View file

@ -17,6 +17,7 @@
#include "mp_game_settings.hpp"
#include "settings.hpp"
#include "tod_manager.hpp"
#include "preferences/credentials.hpp"
#include <cassert>
#include <sstream>

View file

@ -17,6 +17,7 @@
#include "formula/string_utils.hpp"
#include "game_initialization/mp_game_utils.hpp"
#include "game_initialization/playcampaign.hpp"
#include "preferences/credentials.hpp"
#include "preferences/game.hpp"
#include "gettext.hpp"
#include "log.hpp"

View file

@ -17,6 +17,7 @@
#include "filesystem.hpp"
#include "formula/string_utils.hpp"
#include "game_config_manager.hpp"
#include "preferences/credentials.hpp"
#include "preferences/game.hpp"
#include "generators/map_create.hpp"
#include "gui/dialogs/campaign_difficulty.hpp"

View file

@ -15,6 +15,7 @@
#include "game_initialization/lobby_data.hpp"
#include "config.hpp"
#include "preferences/credentials.hpp"
#include "preferences/game.hpp"
#include "gui/dialogs/campaign_difficulty.hpp"
#include "filesystem.hpp"

View file

@ -19,6 +19,7 @@
#include "game_config_manager.hpp"
#include "game_initialization/mp_game_utils.hpp"
#include "game_initialization/playcampaign.hpp"
#include "preferences/credentials.hpp"
#include "preferences/game.hpp"
#include "gettext.hpp"
#include "gui/dialogs/lobby/lobby.hpp"
@ -190,7 +191,7 @@ static std::unique_ptr<wesnothd_connection> open_connection(CVideo& video, const
if(!*error) break;
do {
std::string password = preferences::password();
std::string password = preferences::password(host, login);
bool fall_through = (*error)["force_confirmation"].to_bool() ?
(gui2::show_message(video, _("Confirm"), (*error)["message"], gui2::dialogs::message::ok_cancel_buttons) == gui2::window::CANCEL) :
@ -224,8 +225,8 @@ static std::unique_ptr<wesnothd_connection> open_connection(CVideo& video, const
throw wesnothd_error(_("Bad data received from server"));
}
sp["password"] = utils::create_hash(utils::create_hash(password, utils::get_salt(salt),
utils::get_iteration_count(salt)), salt.substr(12, 8));
sp["password"] = utils::md5(utils::md5(password, utils::md5::get_salt(salt),
utils::md5::get_iteration_count(salt)).hex_digest(), salt.substr(12, 8)).hex_digest();
} else {
sp["password"] = password;
@ -288,7 +289,7 @@ static std::unique_ptr<wesnothd_connection> open_connection(CVideo& video, const
error_message = (*error)["message"].str();
}
gui2::dialogs::mp_login dlg(error_message, !((*error)["password_request"].empty()));
gui2::dialogs::mp_login dlg(host, error_message, !((*error)["password_request"].empty()));
dlg.show(video);
switch(dlg.get_retval()) {

View file

@ -15,6 +15,7 @@
#include "game_launcher.hpp"
#include "game_errors.hpp"
#include "preferences/credentials.hpp"
#include "commandline_options.hpp" // for commandline_options
#include "config.hpp" // for config, etc
#include "cursor.hpp" // for set, CURSOR_TYPE::NORMAL
@ -238,14 +239,14 @@ game_launcher::game_launcher(const commandline_options& cmdline_opts, const char
else
multiplayer_server_ = "";
}
}
if (cmdline_opts_.username) {
preferences::disable_preferences_save();
preferences::set_login(*cmdline_opts_.username);
}
if (cmdline_opts_.password) {
preferences::disable_preferences_save();
preferences::set_password(*cmdline_opts_.password);
if (cmdline_opts_.username) {
preferences::disable_preferences_save();
preferences::set_login(*cmdline_opts_.username);
if (cmdline_opts_.password) {
preferences::disable_preferences_save();
preferences::set_password(*cmdline_opts.server, *cmdline_opts.username, *cmdline_opts_.password);
}
}
}
if (cmdline_opts_.test)
{

View file

@ -22,7 +22,7 @@
#include "formula/string_utils.hpp"
#include "game_board.hpp"
#include "game_display.hpp"
#include "preferences/game.hpp"
#include "preferences/credentials.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/dialogs/helper.hpp"
#include "gui/widgets/label.hpp"

View file

@ -21,7 +21,7 @@
#include "game_config.hpp"
#include "game_config_manager.hpp"
#include "game_initialization/mp_game_utils.hpp"
#include "preferences/game.hpp"
#include "preferences/credentials.hpp"
#include "gettext.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/dialogs/helper.hpp"

View file

@ -16,8 +16,9 @@
#include "gui/dialogs/multiplayer/mp_login.hpp"
#include "preferences/game.hpp"
#include "preferences/credentials.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/auxiliary/field.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/password_box.hpp"
#include "gui/widgets/settings.hpp"
@ -64,24 +65,32 @@ namespace dialogs
REGISTER_DIALOG(mp_login)
mp_login::mp_login(const std::string& label, const bool focus_password)
mp_login::mp_login(const std::string& host, const std::string& label, const bool focus_password)
: host_(host), focus_password_(focus_password)
{
register_label("login_label", false, label);
register_text("user_name", true,
username_ = register_text("user_name", true,
&preferences::login,
&preferences::set_login,
!focus_password);
register_text("password", true,
&preferences::password,
nullptr /* The password box returns '*' as value. */,
focus_password);
register_bool("remember_password", false,
&preferences::remember_password,
&preferences::set_remember_password);
}
void mp_login::load_password(window& win) const
{
text_box& pwd = find_widget<text_box>(&win, "password", false);
pwd.set_value(preferences::password(host_, username_->get_widget_value(win)));
}
void mp_login::save_password(window& win) const
{
password_box& pwd = find_widget<password_box>(&win, "password", false);
preferences::set_password(host_, username_->get_widget_value(win), pwd.get_real_value());
}
void mp_login::pre_show(window& win)
{
if(button* btn = find_widget<button>(&win, "password_reminder", false, false)) {
@ -94,14 +103,22 @@ void mp_login::pre_show(window& win)
btn->set_retval(2);
}
win.add_to_tab_order(find_widget<text_box>(&win, "user_name", false, false));
text_box& login = find_widget<text_box>(&win, "user_name", false);
login.connect_signal<event::RECEIVE_KEYBOARD_FOCUS>(std::bind(&mp_login::load_password, this, std::ref(win)));
load_password(win);
if(focus_password_) {
win.keyboard_capture(find_widget<text_box>(&win, "password", false, true));
}
win.add_to_tab_order(&login);
win.add_to_tab_order(find_widget<text_box>(&win, "password", false, false));
}
void mp_login::post_show(window& win)
{
void mp_login::post_show(window& win) {
if(get_retval() == window::OK) {
preferences::set_password(find_widget<password_box>(&win, "password", false).get_real_value());
save_password(win);
}
}

View file

@ -18,13 +18,15 @@
namespace gui2
{
class field_text;
namespace dialogs
{
class mp_login : public modal_dialog
{
public:
mp_login(const std::string& label, const bool focus_password);
mp_login(const std::string& host, const std::string& label, const bool focus_password);
private:
/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
@ -35,6 +37,13 @@ private:
/** Inherited from modal_dialog. */
virtual void post_show(window& window) override;
void load_password(window& win) const;
void save_password(window& win) const;
const std::string host_;
field_text* username_;
bool focus_password_;
};
} // namespace dialogs

View file

@ -16,7 +16,7 @@
#include "gui/dialogs/multiplayer/mp_method_selection.hpp"
#include "preferences/game.hpp"
#include "preferences/credentials.hpp"
#include "gui/auxiliary/find_widget.hpp"
#ifdef GUI2_EXPERIMENTAL_LISTBOX
#include "gui/widgets/list.hpp"

View file

@ -24,6 +24,7 @@
#include "preferences/game.hpp"
#include "hotkey/hotkey_command.hpp"
#include "hotkey/hotkey_item.hpp"
#include "preferences/credentials.hpp"
#include "preferences/lobby.hpp"
#include "preferences/general.hpp"
#include "preferences/display.hpp"

View file

@ -33,6 +33,7 @@
#include "formula/string_utils.hpp"
#include "gettext.hpp"
#include "wesnothd_connection.hpp"
#include "preferences/credentials.hpp"
#include "preferences/game.hpp"
#include "preferences/lobby.hpp"
#include "log.hpp"

View file

@ -12,33 +12,66 @@
See the COPYING file for more details.
*/
#include "hash.hpp"
#include <iostream>
#include <string>
#include "md5.hpp"
#include "hash.hpp"
#include <openssl/sha.h>
#include <openssl/md5.h>
namespace utils {
static_assert(utils::md5::DIGEST_SIZE == MD5_DIGEST_LENGTH, "Constants mismatch");
static_assert(utils::sha1::DIGEST_SIZE == SHA_DIGEST_LENGTH, "Constants mismatch");
namespace {
const std::string itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ;
const std::string hash_prefix = "$H$";
std::array<uint8_t, 16> md5(const std::string& input) {
MD5 md5_worker;
md5_worker.update(reinterpret_cast<const uint8_t*>(input.data()), input.size());
md5_worker.finalize();
return md5_worker.raw_digest();
template<size_t len>
std::string encode_hash(const std::array<uint8_t, len>& input) {
std::string encoded_hash;
unsigned int i = 0;
do {
unsigned value = input[i++];
encoded_hash.append(itoa64.substr(value & 0x3f,1));
if(i < len)
value |= static_cast<int>(input[i]) << 8;
encoded_hash.append(itoa64.substr((value >> 6) & 0x3f,1));
if(i++ >= len)
break;
if(i < len)
value |= static_cast<int>(input[i]) << 16;
encoded_hash.append(itoa64.substr((value >> 12) & 0x3f,1));
if(i++ >= len)
break;
encoded_hash.append(itoa64.substr((value >> 18) & 0x3f,1));
} while (i < len);
return encoded_hash;
}
int get_iteration_count(const std::string& hash) {
}
namespace utils {
md5::md5(const std::string& input) {
MD5_CTX md5_worker;
MD5_Init(&md5_worker);
MD5_Update(&md5_worker, input.data(), input.size());
MD5_Final(hash.data(), &md5_worker);
}
int md5::get_iteration_count(const std::string& hash) {
return itoa64.find_first_of(hash[3]);
}
std::string get_salt(const std::string& hash) {
std::string md5::get_salt(const std::string& hash) {
return hash.substr(4,8);
}
bool is_valid_hash(const std::string& hash) {
bool md5::is_valid_hash(const std::string& hash) {
if(hash.size() != 34) return false;
if(hash.substr(0,3) != hash_prefix) return false;
@ -48,38 +81,32 @@ bool is_valid_hash(const std::string& hash) {
return true;
}
std::string encode_hash(const std::array<uint8_t, 16>& input) {
std::string encoded_hash;
unsigned int i = 0;
do {
unsigned value = input[i++];
encoded_hash.append(itoa64.substr(value & 0x3f,1));
if(i < 16)
value |= static_cast<int>(input[i]) << 8;
encoded_hash.append(itoa64.substr((value >> 6) & 0x3f,1));
if(i++ >= 16)
break;
if(i < 16)
value |= static_cast<int>(input[i]) << 16;
encoded_hash.append(itoa64.substr((value >> 12) & 0x3f,1));
if(i++ >= 16)
break;
encoded_hash.append(itoa64.substr((value >> 18) & 0x3f,1));
} while (i < 16);
return encoded_hash;
}
std::string create_hash(const std::string& password, const std::string& salt, int iteration_count) {
md5::md5(const std::string& password, const std::string& salt, int iteration_count)
{
iteration_count = 1 << iteration_count;
std::array<uint8_t, 16> output = md5(salt + password);
hash = md5(salt + password).raw_digest();
do {
output = md5(std::string(output.begin(), output.end()).append(password));
hash = md5(std::string(hash.begin(), hash.end()).append(password)).raw_digest();
} while(--iteration_count);
}
return encode_hash(output);
std::string md5::hex_digest() const
{
return encode_hash<DIGEST_SIZE>(hash);
}
sha1::sha1(const std::string& str)
{
SHA_CTX hasher;
SHA1_Init(&hasher);
SHA1_Update(&hasher, str.data(), str.size());
SHA1_Final(hash.data(), &hasher);
}
std::string sha1::hex_digest() const
{
return encode_hash<DIGEST_SIZE>(hash);
}
} // namespace utils

View file

@ -18,20 +18,43 @@
#include <cstdint>
#include <string>
#include "global.hpp"
namespace utils {
/**
* Returns the MD5 digest for the specified input.
*
* @note The returned value points to a fixed-size 16 bytes array representing
* the raw MD5 value, not a null-terminated string. Use encode_hash if
* you need the text representation instead.
*/
std::array<uint8_t, 16> md5(const std::string& input);
int get_iteration_count(const std::string& hash);
std::string get_salt(const std::string& hash);
bool is_valid_hash(const std::string& hash);
std::string encode_hash(const std::array<uint8_t, 16>& input);
std::string create_hash(const std::string& password, const std::string& salt, int iteration_count =10);
class hash_base
{
public:
virtual std::string hex_digest() const = 0;
virtual ~hash_base() {}
};
template<size_t sz>
class hash_digest : public hash_base
{
protected:
std::array<uint8_t, sz> hash;
public:
static const int DIGEST_SIZE = sz;
std::array<uint8_t, sz> raw_digest() const {return hash;}
};
class md5 : public hash_digest<16>
{
public:
static int get_iteration_count(const std::string& hash);
static std::string get_salt(const std::string& hash);
static bool is_valid_hash(const std::string& hash);
explicit md5(const std::string& input);
md5(const std::string& input, const std::string& salt, int iteration_count = 10);
virtual std::string hex_digest() const override;
};
class sha1 : public hash_digest<20>
{
public:
explicit sha1(const std::string& input);
virtual std::string hex_digest() const override;
};
} // namespace utils

View file

@ -1,393 +0,0 @@
// MD5.CC - source code for the C++/object oriented translation and
// modification of MD5.
// Translation and modification (c) 1995 by Mordechai T. Abzug
// This translation/ modification is provided "as is," without express or
// implied warranty of any kind.
// The translator/ modifier does not claim (1) that MD5 will do what you think
// it does; (2) that this translation/ modification is accurate; or (3) that
// this software is "merchantible." (Language for this disclaimer partially
// copied from the disclaimer below).
/* based on:
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
MDDRIVER.C - test driver for MD2, MD4 and MD5
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 "md5.hpp"
#include <cassert>
#include <iostream>
#include <cstring> // Edit: needed for strlen() (strings.h should
// include it but apparently does not for me)
// C4351 is a warning about default-initializing arrays in the initializer list.
// Since it's desired behavior, suppress the warning.
#ifdef _MSC_VER
#pragma warning(disable:4351)
#endif
// MD5 simple initialization method
MD5::MD5()
: state()
, count()
, buffer()
, digest()
, finalized(0)
{
init();
}
// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block, and updating the
// context.
void MD5::update (const uint1* input, uint4 input_length) {
uint4 input_index, buffer_index;
uint4 buffer_space; // how much space is left in buffer
if (finalized){ // so we can't update!
std::cerr << "MD5::update: Can't update a finalized digest!" << std::endl;
return;
}
// Compute number of bytes mod 64
buffer_index = ((count[0] >> 3) & 0x3F);
// Update number of bits
if ( (count[0] += (input_length << 3))<(input_length << 3) )
count[1]++;
count[1] += (input_length >> 29);
buffer_space = 64 - buffer_index; // how much space is left in buffer
// Transform as many times as possible.
if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
// fill the rest of the buffer and transform
memcpy (buffer + buffer_index, input, buffer_space);
transform (buffer);
// now, transform each 64-byte piece of the input, bypassing the buffer
for (input_index = buffer_space; input_index + 63 < input_length;
input_index += 64)
transform (input+input_index);
buffer_index = 0; // so we can buffer remaining
}
else
input_index=0; // so we can buffer the whole input
// and here we do the buffering:
memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
}
// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
void MD5::finalize (){
uint1 bits[8];
uint4 index, padLen;
static uint1 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
};
if (finalized){
std::cerr << "MD5::finalize: Already finalized this digest!" << std::endl;
return;
}
// Save number of bits
encode (bits, count, 8);
// Pad out to 56 mod 64.
index = (count[0] >> 3) & 0x3f;
padLen = (index < 56) ? (56 - index) : (120 - index);
update (PADDING, padLen);
// Append length (before padding)
update (bits, 8);
// Store state in digest
encode (digest, state, 16);
// Zeroize sensitive information
memset (buffer, 0, sizeof(*buffer));
finalized=1;
}
std::array<uint8_t, 16> MD5::raw_digest()
{
std::array<uint8_t, 16> s;
if (!finalized){
std::cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
"finalized the digest!" <<std::endl;
throw std::logic_error("MD5::raw_digest: attempted to obtain digest before finalizing it");
}
memcpy(s.data(), digest, 16);
return s;
}
// PRIVATE METHODS:
void MD5::init(){
finalized=0; // we just started!
// Nothing counted, so count=0
count[0] = 0;
count[1] = 0;
// Load magic initialization constants.
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
}
// Constants for MD5Transform routine.
// Although we could use C++ style constants, defines are actually better,
// since they let us easily evade scope clashes.
#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
// MD5 basic transformation. Transforms state based on block.
void MD5::transform (const uint1 block[64]){
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
decode (x, block, 64);
assert(!finalized); // not just a user error, since the method is private
/* 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.
memset ( reinterpret_cast<uint1*>(x), 0, sizeof(x));
}
// Encodes input (UINT4) into output (uint1). Assumes len is
// a multiple of 4.
void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
uint4 i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = static_cast<uint1> (input[i] & 0xff);
output[j+1] = static_cast<uint1>((input[i] >> 8) & 0xff);
output[j+2] = static_cast<uint1>((input[i] >> 16) & 0xff);
output[j+3] = static_cast<uint1>((input[i] >> 24) & 0xff);
}
}
// Decodes input (uint1) into output (UINT4). Assumes len is
// a multiple of 4.
void MD5::decode (uint4 *output, const uint1 *input, uint4 len){
uint4 i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = (static_cast<uint4>(input[j]))
| ((static_cast<uint4>(input[j+1])) << 8)
| ((static_cast<uint4>(input[j+2])) << 16)
| ((static_cast<uint4>(input[j+3])) << 24);
}
// ROTATE_LEFT rotates x left n bits.
inline MD5::uint4 MD5::rotate_left (uint4 x, uint4 n){
return (x << n) | (x >> (32-n)) ;
}
// F, G, H and I are basic MD5 functions.
inline MD5::uint4 MD5::F (uint4 x, uint4 y, uint4 z){
return (x & y) | (~x & z);
}
inline MD5::uint4 MD5::G (uint4 x, uint4 y, uint4 z){
return (x & z) | (y & ~z);
}
inline MD5::uint4 MD5::H (uint4 x, uint4 y, uint4 z){
return x ^ y ^ z;
}
inline MD5::uint4 MD5::I (uint4 x, uint4 y, uint4 z){
return y ^ (x | ~z);
}
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += F(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += G(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += H(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac){
a += I(b, c, d) + x + ac;
a = rotate_left (a, s) +b;
}

View file

@ -1,95 +0,0 @@
// MD5.CC - source code for the C++/object oriented translation and
// modification of MD5.
// Translation and modification (c) 1995 by Mordechai T. Abzug
// This translation/ modification is provided "as is," without express or
// implied warranty of any kind.
// The translator/ modifier does not claim (1) that MD5 will do what you think
// it does; (2) that this translation/ modification is accurate; or (3) that
// this software is "merchantible." (Language for this disclaimer partially
// copied from the disclaimer below).
/* based on:
MD5.H - header file for MD5C.C
MDDRIVER.C - test driver for MD2, MD4 and MD5
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.
*/
#pragma once
#include <array>
#include <cstdint>
class MD5 {
public:
// methods for controlled operation:
MD5 (); // simple initializer
void update (const uint8_t* input, const uint32_t input_length);
void finalize ();
// methods to acquire finalized result
std::array<uint8_t, 16> raw_digest (); // digest as a 16-byte binary array
private:
// first, some types:
typedef uint32_t uint4;
typedef uint16_t uint2;
typedef uint8_t uint1;
// next, the private data:
uint4 state[4];
uint4 count[2]; // number of *bits*, mod 2^64
uint1 buffer[64]; // input buffer
uint1 digest[16];
uint1 finalized;
// last, the private methods, mostly static:
void init (); // called by all constructors
void transform (const uint1 buffer[64]); // does the real update work. Note
// that length is implied to be 64.
static void encode (uint1 *dest, uint4 *src, uint4 length);
static void decode (uint4 *dest, const uint1 *src, uint4 length);
static inline uint4 rotate_left (uint4 x, uint4 n);
static inline uint4 F (uint4 x, uint4 y, uint4 z);
static inline uint4 G (uint4 x, uint4 y, uint4 z);
static inline uint4 H (uint4 x, uint4 y, uint4 z);
static inline uint4 I (uint4 x, uint4 y, uint4 z);
static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
uint4 s, uint4 ac);
};

View file

@ -68,6 +68,7 @@
#include "mouse_events.hpp"
#include "play_controller.hpp"
#include "playsingle_controller.hpp"
#include "preferences/credentials.hpp"
#include "preferences/display.hpp"
#include "replay.hpp"
#include "replay_helper.hpp"

View file

@ -26,6 +26,7 @@
#include "actions/vision.hpp"
#include "ai/manager.hpp"
#include "ai/testing.hpp"
#include "preferences/credentials.hpp"
#include "display_chat_manager.hpp"
#include "formula/string_utils.hpp"
#include "game_events/menu_item.hpp"

View file

@ -0,0 +1,327 @@
/*
Copyright (C) 2017 by the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "credentials.hpp"
#include "preferences/general.hpp"
#include "serialization/unicode.hpp"
#include "filesystem.hpp"
#include "log.hpp"
#include "serialization/string_utils.hpp"
#include <algorithm>
#include <memory>
#include <openssl/rc4.h>
#ifdef _WIN32
#include <boost/range/iterator_range.hpp>
#include <windows.h>
#endif
static lg::log_domain log_config("config");
#define ERR_CFG LOG_STREAM(err , log_config)
class secure_buffer : public std::vector<unsigned char>
{
public:
template<typename... T> secure_buffer(T&&... args)
: vector<unsigned char>(std::forward<T>(args)...)
{}
~secure_buffer()
{
std::fill(begin(), end(), '\0');
}
};
struct login_info
{
std::string username, server;
secure_buffer key;
login_info(const std::string& username, const std::string& server, const secure_buffer& key)
: username(username), server(server), key(key)
{}
login_info(const std::string& username, const std::string& server)
: username(username), server(server), key()
{}
size_t size() const
{
return 3 + username.size() + server.size() + key.size();
}
};
static std::vector<login_info> credentials;
// Separate password entries with formfeed
static const unsigned char CREDENTIAL_SEPARATOR = '\f';
static secure_buffer encrypt(const secure_buffer& text, const secure_buffer& key);
static secure_buffer decrypt(const secure_buffer& text, const secure_buffer& key);
static secure_buffer build_key(const std::string& server, const std::string& login);
static secure_buffer escape(const secure_buffer& text);
static secure_buffer unescape(const secure_buffer& text);
static std::string get_system_username()
{
std::string res;
#ifdef _WIN32
wchar_t buffer[300];
DWORD size = 300;
if(GetUserNameW(buffer, &size)) {
//size includes a terminating null character.
assert(size > 0);
res = unicode_cast<utf8::string>(boost::iterator_range<wchar_t*>(buffer, buffer + size - 1));
}
#else
if(char* const login = getenv("USER")) {
res = login;
}
#endif
return res;
}
static void clear_credentials()
{
// Zero them before clearing.
// Probably overly paranoid, but doesn't hurt?
for(auto& cred : credentials) {
std::fill(cred.username.begin(), cred.username.end(), '\0');
std::fill(cred.server.begin(), cred.server.end(), '\0');
}
credentials.clear();
}
static const std::string EMPTY_LOGIN = "@@";
namespace preferences
{
std::string login()
{
std::string name = preferences::get("login", EMPTY_LOGIN);
if(name == EMPTY_LOGIN) {
name = get_system_username();
} else if(name.size() > 2 && name[0] == '@' && name[name.size() - 1] == '@') {
name = name.substr(1, name.size() - 2);
} else {
ERR_CFG << "malformed user credentials (did you manually edit the preferences file?)" << std::endl;
}
if(name.empty()) {
return "player";
}
return name;
}
void set_login(const std::string& login)
{
preferences::set("login", '@' + login + '@');
}
bool remember_password()
{
return preferences::get("remember_password", false);
}
void set_remember_password(bool remember)
{
preferences::set("remember_password", remember);
if(remember) {
load_credentials();
} else {
clear_credentials();
}
}
std::string password(const std::string& server, const std::string& login)
{
if(!remember_password()) {
if(!credentials.empty() && credentials[0].username == login && credentials[0].server == server) {
auto temp = decrypt(credentials[0].key, build_key(server, login));
return std::string(temp.begin(), temp.end());
} else {
return "";
}
}
auto cred = std::find_if(credentials.begin(), credentials.end(), [&](const login_info& cred) {
return cred.server == server && cred.username == login;
});
if(cred == credentials.end()) {
return "";
}
auto temp = decrypt(cred->key, build_key(server, login));
return std::string(temp.begin(), temp.end());
}
void set_password(const std::string& server, const std::string& login, const std::string& key)
{
secure_buffer temp(key.begin(), key.end());
if(!remember_password()) {
clear_credentials();
credentials.emplace_back(login, server, encrypt(temp, build_key(server, login)));
return;
}
auto cred = std::find_if(credentials.begin(), credentials.end(), [&](const login_info& cred) {
return cred.server == server && cred.username == login;
});
if(cred == credentials.end()) {
// This is equivalent to emplace_back, but also returns the iterator to the new element
cred = credentials.emplace(credentials.end(), login, server);
}
cred->key = encrypt(temp, build_key(server, login));
}
void load_credentials()
{
if(!remember_password()) {
return;
}
clear_credentials();
std::string cred_file = filesystem::get_credentials_file();
if(!filesystem::file_exists(cred_file)) {
return;
}
filesystem::scoped_istream stream = filesystem::istream_file(cred_file, false);
// Credentials file is a binary blob, so use streambuf iterator
secure_buffer data((std::istreambuf_iterator<char>(*stream)), (std::istreambuf_iterator<char>()));
data = decrypt(data, build_key("global", get_system_username()));
if(data.empty() || data[0] != CREDENTIAL_SEPARATOR) {
ERR_CFG << "Invalid data in credentials file\n";
return;
}
for(const std::string& elem : utils::split(std::string(data.begin(), data.end()), CREDENTIAL_SEPARATOR, utils::REMOVE_EMPTY)) {
size_t at = elem.find_last_of('@');
size_t eq = elem.find_first_of('=', at + 1);
if(at != std::string::npos && eq != std::string::npos) {
secure_buffer key(elem.begin() + eq + 1, elem.end());
credentials.emplace_back(elem.substr(0, at), elem.substr(at + 1, eq - at - 1), unescape(key));
}
}
}
void save_credentials()
{
if(!remember_password()) {
filesystem::delete_file(filesystem::get_credentials_file());
return;
}
secure_buffer credentials_data(1, CREDENTIAL_SEPARATOR);
size_t offset = 1;
for(const auto& cred : credentials) {
credentials_data.resize(credentials_data.size() + cred.size(), CREDENTIAL_SEPARATOR);
std::copy(cred.username.begin(), cred.username.end(), credentials_data.begin() + offset);
offset += cred.username.size();
credentials_data[offset++] = '@';
std::copy(cred.server.begin(), cred.server.end(), credentials_data.begin() + offset);
offset += cred.server.size();
credentials_data[offset++] = '=';
secure_buffer key_escaped = escape(cred.key);
// Escaping may increase the length, so resize again if so
credentials_data.resize(credentials_data.size() + key_escaped.size() - cred.key.size());
std::copy(key_escaped.begin(), key_escaped.end(), credentials_data.begin() + offset);
offset += key_escaped.size() + 1;
}
try {
filesystem::scoped_ostream credentials_file = filesystem::ostream_file(filesystem::get_credentials_file());
secure_buffer encrypted = encrypt(credentials_data, build_key("global", get_system_username()));
credentials_file->write(reinterpret_cast<const char*>(encrypted.data()), encrypted.size());
} catch(filesystem::io_exception&) {
ERR_CFG << "error writing to credentials file '" << filesystem::get_credentials_file() << "'" << std::endl;
}
}
}
// TODO: Key-stretching (bcrypt was recommended)
secure_buffer build_key(const std::string& server, const std::string& login)
{
std::string sysname = get_system_username();
secure_buffer result(std::max<size_t>(server.size() + login.size() + sysname.size(), 32));
size_t i = 0;
std::generate(result.begin(), result.end(), [&i]() {return 'x' ^ i++;});
std::copy(login.begin(), login.end(), result.begin());
std::copy(sysname.begin(), sysname.end(), result.begin() + login.size());
std::copy(server.begin(), server.end(), result.begin() + login.size() + sysname.size());
return result;
}
static secure_buffer rc4_crypt(const secure_buffer& text, const secure_buffer& key)
{
RC4_KEY cipher_key;
RC4_set_key(&cipher_key, key.size(), key.data());
const size_t block_size = key.size();
const size_t blocks = text.size() / block_size;
const size_t extra = text.size() % block_size;
secure_buffer result(text.size(), '\0');
for(size_t i = 0; i < blocks * block_size; i += block_size) {
RC4(&cipher_key, block_size, text.data() + i, result.data() + i);
}
if(extra) {
size_t i = blocks * block_size;
RC4(&cipher_key, extra, text.data() + i, result.data() + i);
}
return result;
}
secure_buffer encrypt(const secure_buffer& text, const secure_buffer& key)
{
return rc4_crypt(text, key);
}
secure_buffer decrypt(const secure_buffer& text, const secure_buffer& key)
{
return rc4_crypt(text, key);
}
secure_buffer unescape(const secure_buffer& text)
{
secure_buffer unescaped;
unescaped.reserve(text.size());
bool escaping = false;
for(char c : text) {
if(escaping) {
if(c == '\xa') {
unescaped.push_back('\xc');
} else if(c == '.') {
unescaped.push_back('@');
} else {
unescaped.push_back(c);
}
escaping = false;
} else if(c == '\x1') {
escaping = true;
} else {
unescaped.push_back(c);
}
}
assert(!escaping);
return unescaped;
}
secure_buffer escape(const secure_buffer& text)
{
secure_buffer escaped;
escaped.reserve(text.size());
for(char c : text) {
if(c == '\x1') {
escaped.push_back('\x1');
escaped.push_back('\x1');
} else if(c == '\xc') {
escaped.push_back('\x1');
escaped.push_back('\xa');
} else if(c == '@') {
escaped.push_back('\x1');
escaped.push_back('.');
} else {
escaped.push_back(c);
}
}
return escaped;
}

View file

@ -0,0 +1,30 @@
/*
Copyright (C) 2017 by the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
#include <string>
namespace preferences {
std::string login();
void set_login(const std::string& login);
std::string password(const std::string& server, const std::string& login);
void set_password(const std::string& server, const std::string& login, const std::string& key);
bool remember_password();
void set_remember_password(bool remember);
void load_credentials();
void save_credentials();
}

View file

@ -28,20 +28,6 @@
#include "wml_exception.hpp"
#include <cassert>
#ifdef _WIN32
#include <boost/range/iterator_range.hpp>
#ifdef INADDR_ANY
#undef INADDR_ANY
#endif
#ifdef INADDR_BROADCAST
#undef INADDR_BROADCAST
#endif
#ifdef INADDR_NONE
#undef INADDR_NONE
#endif
#include <windows.h> //GetUserName
#endif
static lg::log_domain log_config("config");
#define ERR_CFG LOG_STREAM(err , log_config)
@ -72,28 +58,6 @@ bool options_initialized = false;
bool authenticated = false;
const char WRAP_CHAR = '@';
const std::string EMPTY_WRAPPED_STRING = "@@";
std::string wrap_credentials_field_value(const std::string& value)
{
return WRAP_CHAR + value + WRAP_CHAR;
}
std::string parse_wrapped_credentials_field(const std::string& raw)
{
if(raw.empty() || raw == EMPTY_WRAPPED_STRING) {
// empty (wrapped or not)
return raw;
} else if(raw.length() < 2 || raw[0] != WRAP_CHAR || raw[raw.length() - 1] != WRAP_CHAR ) {
// malformed/not wrapped (shouldn't happen)
ERR_CFG << "malformed user credentials (did you manually edit the preferences file?)" << std::endl;
return raw;
}
return raw.substr(1, raw.length() - 2);
}
void initialize_modifications(bool mp = true)
{
if (mp) {
@ -453,117 +417,6 @@ void set_campaign_server(const std::string& host)
preferences::set("campaign_server", host);
}
bool wrap_password()
{
const bool have_old_password_format =
(!preferences::have_setting("password_is_wrapped")) && preferences::have_setting("password");
return have_old_password_format ? false : preferences::get("password_is_wrapped", true);
}
void set_wrap_password(bool wrap)
{
preferences::set("password_is_wrapped", wrap);
}
bool wrap_login()
{
const bool have_old_login_format =
(!preferences::have_setting("login_is_wrapped")) && preferences::have_setting("login");
return have_old_login_format ? false : preferences::get("login_is_wrapped", true);
}
void set_wrap_login(bool wrap)
{
preferences::set("login_is_wrapped", wrap);
}
static std::string get_system_username()
{
std::string res;
#ifdef _WIN32
wchar_t buffer[300];
DWORD size = 300;
if(GetUserNameW(buffer,&size)) {
//size includes a terminating null character.
assert(size > 0);
res = unicode_cast<utf8::string>(boost::iterator_range<wchar_t*>(buffer, buffer + size - 1));
}
#else
if(char* const login = getenv("USER")) {
res = login;
}
#endif
return res;
}
std::string login()
{
const std::string res = preferences::get("login");
if(res.empty() || res == EMPTY_WRAPPED_STRING) {
const std::string& login = get_system_username();
if(!login.empty()) {
return login;
}
if(res.empty()) {
return _("player");
}
}
if(!wrap_login()) {
return res;
} else {
return parse_wrapped_credentials_field(res);
}
}
void set_login(const std::string& username)
{
set_wrap_login(true);
preferences::set("login", wrap_credentials_field_value(username));
}
namespace prv {
std::string password;
}
std::string password()
{
if(remember_password()) {
const std::string saved_pass = preferences::get("password");
if(!wrap_password()) {
return saved_pass;
} else {
return parse_wrapped_credentials_field(saved_pass);
}
} else {
return prv::password;
}
}
void set_password(const std::string& password)
{
prv::password = password;
if(remember_password()) {
set_wrap_password(true);
preferences::set("password", wrap_credentials_field_value(password));
}
}
bool remember_password()
{
return preferences::get("remember_password", false);
}
void set_remember_password(bool remember)
{
preferences::set("remember_password", remember);
if(!remember) {
preferences::set("password", "");
}
}
bool turn_dialog()
{
return preferences::get("turn_dialog", false);

View file

@ -83,45 +83,6 @@ class acquaintance;
std::string campaign_server();
void set_campaign_server(const std::string& host);
/**
* Returns whether the MP username is stored wrapped in markers.
*
* New usernames are stored in a specific format to force string interpretation
* (due to bug #16571).
*/
bool wrap_login();
void set_wrap_login(bool wrap);
std::string login();
void set_login(const std::string& username);
// If password remembering is turned off use
// prv::password instead. This way we will not
// have to worry about whether to remember the
// password or not anywhere else in the code.
//
// It is put into a separate namespace to make clear
// it is "private" and not supposed to be edit outside
// of the preferences functions.
namespace prv {
extern std::string password;
}
/**
* Returns whether the password is stored wrapped in markers.
*
* New passwords are stored in a specific format to force string interpretation
* (due to bug #16571).
*/
bool wrap_password();
void set_wrap_password(bool wrap);
std::string password();
void set_password(const std::string& password);
bool remember_password();
void set_remember_password(bool remember);
bool turn_dialog();
void set_turn_dialog(bool ison);

View file

@ -25,6 +25,7 @@
#include "hotkey/hotkey_item.hpp"
#include "lexical_cast.hpp"
#include "log.hpp"
#include "credentials.hpp"
#include "preferences/general.hpp"
#include "sound.hpp"
#include "video.hpp" // non_interactive()
@ -104,6 +105,7 @@ base_manager::base_manager()
<< e.what()
<< std::endl;
}
preferences::load_credentials();
}
base_manager::~base_manager()
@ -162,6 +164,8 @@ void write_preferences()
ERR_FS << "error writing to preferences file '" << filesystem::get_prefs_file() << "'" << std::endl;
}
preferences::save_credentials();
#ifndef _WIN32
if(!prefs_file_existed) {

View file

@ -20,6 +20,7 @@
#include "server/game.hpp"
#include "server/player_network.hpp"
#include "serialization/string_utils.hpp"
#include "preferences/credentials.hpp"
#include <sstream>
#include <iomanip>

View file

@ -945,7 +945,7 @@ struct dialog_tester<mp_login>
{
mp_login* create()
{
return new mp_login("label", true);
return new mp_login("wesnoth.org", "label", true);
}
};

View file

@ -1,164 +0,0 @@
/*
Copyright (C) 2007 - 2017 by Benoit Timbert <benoit.timbert@free.fr>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/**
* @file
* Secure Hash Algorithm 1 (SHA-1).
* Used to checksum the game-config / cache.
*/
/* This is supposed to be an implementation of the
Secure Hash Algorithm 1 (SHA-1)
Check RFC 3174 for details about the algorithm.
Currently this implementation might produce different results on little-
and big-endian machines, but for our current usage, we don't care :)
*/
#include "utils/sha1.hpp"
#include <iomanip>
#include <sstream>
#define sha_rotl(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
#define sha_ch(x,y,z) ( ((x) & (y)) | ((~(x)) & (z)) )
#define sha_parity(x,y,z) ( (x) ^ (y) ^ (z) )
#define sha_maj(x,y,z) ( ((x) & (y)) | ((x) & (z)) | ((y) & (z)) )
std::string sha1_hash::display() {
std::stringstream s;
s << std::hex << std::setfill('0') << std::setw(8) << H0;
s << std::hex << std::setfill('0') << std::setw(8) << H1;
s << std::hex << std::setfill('0') << std::setw(8) << H2;
s << std::hex << std::setfill('0') << std::setw(8) << H3;
s << std::hex << std::setfill('0') << std::setw(8) << H4;
return s.str();
}
sha1_hash::sha1_hash(const std::string& str)
: H0(0x67452301), H1(0xefcdab89), H2(0x98badcfe), H3(0x10325476), H4(0xc3d2e1f0)
{
uint8_t block[64];
int bytes_left = str.size();
uint32_t ssz = bytes_left * 8; // string length in bits
std::stringstream iss (str, std::stringstream::in);
// cut our string in 64 bytes blocks then process it
while (bytes_left > 0) {
iss.read(reinterpret_cast<char*>(block), 64);
if (bytes_left <= 64) { // if it's the last block, pad it
if (bytes_left < 64) {
block[bytes_left]= 0x80; // add a 1 bit right after the end of the string
}
int i;
for (i = 63; i > bytes_left; i--) {
block[i]=0; // pad our block with zeros
}
if (bytes_left < 56) { // enough space to store the length
// put the length at the end of the block
block[60] = ssz >> 24;
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4244)
#endif
block[61] = ssz >> 16;
block[62] = ssz >> 8;
block[63] = ssz;
#ifdef _MSC_VER
#pragma warning (pop)
#endif
} else { // not enough space for the zeros => we need a new block
next(block);
// new block
for (i = 0; i < 60 ; i++) {
block[i]=0; // pad our block with zeros
}
if (bytes_left == 64) {
block[0]= 0x80; // add a 1 bit right after the end of the string = beginning of our new block
}
// put the length at the end of the block
block[60] = ssz >> 24;
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable: 4244)
#endif
block[61] = ssz >> 16;
block[62] = ssz >> 8;
block[63] = ssz;
#ifdef _MSC_VER
#pragma warning (pop)
#endif
}
}
next(block);
bytes_left -= 64;
}
}
void sha1_hash::next(uint8_t block[64]) {
uint32_t W[80];
uint32_t A, B, C, D, E, T;
int i;
A = H0;
B = H1;
C = H2;
D = H3;
E = H4;
for (i = 0; i < 16; i++) {
W[i]= (block[4 * i] << 24) | (block[4 * i + 1] << 16) | (block[4 * i + 2] << 8) | block[4 * i + 3];
}
for (; i < 80; i++) {
W[i]=sha_rotl(1, W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]);
}
for (i = 0; i < 20; i++) {
T = sha_rotl(5,A) + sha_ch(B,C,D) + E + W[i] + 0x5a827999;
E = D;
D = C;
C = sha_rotl(30,B);
B = A;
A = T;
}
for (; i < 40; i++) {
T = sha_rotl(5,A) + sha_parity(B,C,D) + E + W[i] + 0x6ed9eba1;
E = D;
D = C;
C = sha_rotl(30,B);
B = A;
A = T;
}
for (; i < 60; i++) {
T = sha_rotl(5,A) + sha_maj(B,C,D) + E + W[i] + 0x8f1bbcdc;
E = D;
D = C;
C = sha_rotl(30,B);
B = A;
A = T;
}
for (; i < 80; i++) {
T = sha_rotl(5,A) + sha_parity(B,C,D) + E + W[i] + 0xca62c1d6;
E = D;
D = C;
C = sha_rotl(30,B);
B = A;
A = T;
}
H0 += A;
H1 += B;
H2 += C;
H3 += D;
H4 += E;
}

View file

@ -1,35 +0,0 @@
/*
Copyright (C) 2007 - 2017 by Benoit Timbert <benoit.timbert@free.fr>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#pragma once
#include <string>
#include <cstdint>
class sha1_hash
{
public:
/** Make a hash from a string */
sha1_hash(const std::string& str);
/** Display the hash */
std::string display();
private:
/** Process the next 512 bits block */
void next(uint8_t block[64]);
uint32_t H0, H1, H2, H3, H4;
};

View file

@ -5,7 +5,7 @@ set -ev
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
brew update
brew install scons cairo pango moreutils sdl2_image sdl2_ttf sdl2_mixer
brew install scons cairo pango moreutils sdl2_image sdl2_ttf sdl2_mixer openssl
else
@ -17,7 +17,7 @@ else
sudo apt-get install -qq libboost-filesystem-dev libboost-iostreams-dev libboost-random-dev libboost-program-options-dev libboost-regex-dev libboost-system-dev libboost-test-dev libboost-locale-dev libboost-thread-dev
sudo apt-get install -qq libcairo2-dev libfribidi-dev libpango1.0-dev
sudo apt-get install -qq libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev libvorbis-dev
sudo apt-get install gdb moreutils xvfb
sudo apt-get install gdb moreutils xvfb libssl-dev
if [ "$USE_CMAKE" = true ]; then
sudo apt-get install -qq cmake;