Moved to openSSL SHA1, initial JWT plugin

This commit is contained in:
Pliable Pixels 2019-05-04 11:52:53 -04:00
parent 7603e94e90
commit d952fe7117
5 changed files with 33 additions and 48 deletions

6
.gitmodules vendored
View File

@ -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

View File

@ -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})

View File

@ -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] == '$')) {

View File

@ -20,10 +20,13 @@
#ifndef ZM_CRYPT_H
#define ZM_CRYPT_H
#include <string.h>
#include <openssl/sha.h>
#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

1
third_party/jwt-cpp vendored Submodule

@ -0,0 +1 @@
Subproject commit dd0337e64c19b5c6290b30429a9eedafadcae4b7