From d952fe7117c6c557c0fc200e4e4a0e23822067dc Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Sat, 4 May 2019 11:52:53 -0400 Subject: [PATCH] Moved to openSSL SHA1, initial JWT plugin --- .gitmodules | 6 ++--- src/CMakeLists.txt | 9 +++---- src/zm_crypt.cpp | 60 ++++++++++++++++----------------------------- src/zm_crypt.h | 5 +++- third_party/jwt-cpp | 1 + 5 files changed, 33 insertions(+), 48 deletions(-) create mode 160000 third_party/jwt-cpp diff --git a/.gitmodules b/.gitmodules index c4cc3d6d1..f5bcf359d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,9 +5,9 @@ [submodule "web/api/app/Plugin/CakePHP-Enum-Behavior"] path = web/api/app/Plugin/CakePHP-Enum-Behavior url = https://github.com/ZoneMinder/CakePHP-Enum-Behavior.git -[submodule "third_party/sha1"] - path = third_party/sha1 - url = https://github.com/vog/sha1 [submodule "third_party/bcrypt"] path = third_party/bcrypt url = https://github.com/pliablepixels/libbcrypt +[submodule "third_party/jwt-cpp"] + path = third_party/jwt-cpp + url = https://github.com/Thalhammer/jwt-cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a55ce095..efdb5224d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,12 +7,9 @@ configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY) set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_frame.cpp zm_eventstream.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_input.cpp zm_ffmpeg_camera.cpp zm_group.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_monitorstream.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packet.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_nvsocket.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_swscale.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp zm_crypt.cpp) -# includes and linkages to 3rd party libraries/src -set (ZM_BIN_THIRDPARTY_SRC_FILES ../third_party/sha1/sha1.cpp) - # A fix for cmake recompiling the source files for every target. -add_library(zm STATIC ${ZM_BIN_SRC_FILES} ${ZM_BIN_THIRDPARTY_SRC_FILES}) +add_library(zm STATIC ${ZM_BIN_SRC_FILES}) link_directories(/home/pp/source/pp_ZoneMinder.git/third_party/bcrypt) add_executable(zmc zmc.cpp) @@ -20,7 +17,9 @@ add_executable(zma zma.cpp) add_executable(zmu zmu.cpp) add_executable(zms zms.cpp) -include_directories(../third_party/sha1 ../third_party/bcrypt/include/bcrypt) +# JWT is a header only library. +include_directories(../third_party/bcrypt/include/bcrypt) +include_directories(../third_party/jwt-cpp/include/jwt-cpp) target_link_libraries(zmc zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) target_link_libraries(zma zm ${ZM_EXTRA_LIBS} ${ZM_BIN_LIBS}) diff --git a/src/zm_crypt.cpp b/src/zm_crypt.cpp index 19fa6dd9d..cf707aff0 100644 --- a/src/zm_crypt.cpp +++ b/src/zm_crypt.cpp @@ -4,37 +4,22 @@ -//https://stackoverflow.com/a/46403026/1361529 -char char2int(char input) { - if (input >= '0' && input <= '9') - return input - '0'; - else if (input >= 'A' && input <= 'F') - return input - 'A' + 10; - else if (input >= 'a' && input <= 'f') - return input - 'a' + 10; - else - return input; // this really should not happen + +std::string createToken() { + std::string token = jwt::create() + .set_issuer("auth0") + //.set_expires_at(jwt::date(expiresAt)) + //.set_issued_at(jwt::date(tp)) + //.set_issued_at(jwt::date(std::chrono::system_clock::now())) + //.set_expires_at(jwt::date(std::chrono::system_clock::now()+std::chrono::seconds{EXPIRY})) + .sign(jwt::algorithm::hs256{"secret"}); + return token; } -std::string hex2str(std::string &hex) { - std::string out; - out.resize(hex.size() / 2 + hex.size() % 2); - std::string::iterator it = hex.begin(); - std::string::iterator out_it = out.begin(); - if (hex.size() % 2 != 0) { - *out_it++ = char(char2int(*it++)); - } - - for (; it < hex.end() - 1; it++) { - *out_it++ = char2int(*it++) << 4 | char2int(*it); - }; - - return out; -} - bool verifyPassword(const char *username, const char *input_password, const char *db_password_hash) { bool password_correct = false; + Info ("JWT created as %s",createToken().c_str()); if (strlen(db_password_hash ) < 4) { // actually, shoud be more, but this is min. for next code Error ("DB Password is too short or invalid to check"); @@ -43,20 +28,17 @@ bool verifyPassword(const char *username, const char *input_password, const char if (db_password_hash[0] == '*') { // MYSQL PASSWORD Info ("%s is using an MD5 encoded password", username); - SHA1 checksum; + unsigned char digest_interim[SHA_DIGEST_LENGTH]; + unsigned char digest_final[SHA_DIGEST_LENGTH]; + SHA1((unsigned char*)&input_password, strlen((const char *) input_password), (unsigned char*)&digest_interim); + SHA1((unsigned char*)&digest_interim, strlen((const char *)digest_interim), (unsigned char*)&digest_final); + char final_hash[SHA_DIGEST_LENGTH * 2 +2]; + for(int i = 0; i < SHA_DIGEST_LENGTH; i++) + sprintf(&final_hash[i*2], "%02X", (unsigned int)digest_final[i]); - // next few lines do '*'+SHA1(raw(SHA1(password))) - // which is MYSQL >=4.1 PASSWORD algorithm - checksum.update(input_password); - std::string interim_hash = checksum.final(); - std::string binary_hash = hex2str(interim_hash); // get interim hash - checksum.update(binary_hash); - interim_hash = checksum.final(); - std::string final_hash = "*" + interim_hash; - std::transform(final_hash.begin(), final_hash.end(), final_hash.begin(), ::toupper); - - Debug (5, "Computed password_hash:%s, stored password_hash:%s", final_hash.c_str(), db_password_hash); - password_correct = (std::string(db_password_hash) == final_hash); + Info ("Computed password_hash:%s, stored password_hash:%s", final_hash, db_password_hash); + Debug (5, "Computed password_hash:%s, stored password_hash:%s", final_hash, db_password_hash); + password_correct = (strcmp(db_password_hash, final_hash)==0); } else if ((db_password_hash[0] == '$') && (db_password_hash[1]== '2') &&(db_password_hash[3] == '$')) { diff --git a/src/zm_crypt.h b/src/zm_crypt.h index ad4aa06da..a1e8945e4 100644 --- a/src/zm_crypt.h +++ b/src/zm_crypt.h @@ -20,10 +20,13 @@ #ifndef ZM_CRYPT_H #define ZM_CRYPT_H + #include +#include #include "BCrypt.hpp" -#include "sha1.hpp" +#include "jwt.h" bool verifyPassword( const char *username, const char *input_password, const char *db_password_hash); +std::string createToken(); #endif // ZM_CRYPT_H \ No newline at end of file diff --git a/third_party/jwt-cpp b/third_party/jwt-cpp new file mode 160000 index 000000000..dd0337e64 --- /dev/null +++ b/third_party/jwt-cpp @@ -0,0 +1 @@ +Subproject commit dd0337e64c19b5c6290b30429a9eedafadcae4b7