move to wrapper
This commit is contained in:
parent
d252a8ba30
commit
72325d12b7
|
@ -5,9 +5,6 @@
|
|||
[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/bcrypt"]
|
||||
path = third_party/bcrypt
|
||||
url = https://github.com/trusch/libbcrypt
|
||||
[submodule "third_party/sha1"]
|
||||
path = third_party/sha1
|
||||
url = https://github.com/vog/sha1
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY)
|
||||
|
||||
# Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc)
|
||||
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)
|
||||
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
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
#include "zm.h"
|
||||
# include "zm_crypt.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
//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 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 *input_password, const char *db_password_hash) {
|
||||
bool password_correct = false;
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
if (db_password_hash[0] == '*') {
|
||||
// MYSQL PASSWORD
|
||||
Info ("%s is an MD5 encoded password", db_password_hash);
|
||||
SHA1 checksum;
|
||||
|
||||
// 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);
|
||||
|
||||
Info ("Computed password_hash:%s, stored password_hash:%s", final_hash.c_str(), db_password_hash);
|
||||
password_correct = (std::string(db_password_hash) == final_hash);
|
||||
}
|
||||
else if ((db_password_hash[0] == '$') && (db_password_hash[1]== '2')
|
||||
&&(db_password_hash[3] == '$')) {
|
||||
// BCRYPT
|
||||
Info ("%s is a Bcrypt password", db_password_hash);
|
||||
BCrypt bcrypt;
|
||||
std::string input_hash = bcrypt.generateHash(std::string(input_password));
|
||||
password_correct = bcrypt.validatePassword(std::string(input_password), std::string(db_password_hash));
|
||||
}
|
||||
else {
|
||||
// plain
|
||||
password_correct = (strcmp(input_password, db_password_hash) == 0);
|
||||
}
|
||||
return password_correct;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// ZoneMinder General Utility Functions, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 Philip Coombes
|
||||
//
|
||||
// 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; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
#ifndef ZM_CRYPT_H
|
||||
#define ZM_CRYPT_H
|
||||
|
||||
#include <string.h>
|
||||
#include "BCrypt.hpp"
|
||||
#include "sha1.hpp"
|
||||
|
||||
bool verifyPassword( const char *input_password, const char *db_password_hash);
|
||||
|
||||
#endif // ZM_CRYPT_H
|
|
@ -26,10 +26,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "BCrypt.hpp"
|
||||
#include "sha1.hpp"
|
||||
|
||||
|
||||
#include "zm_utils.h"
|
||||
#include "zm_crypt.h"
|
||||
|
||||
User::User() {
|
||||
id = 0;
|
||||
|
@ -97,34 +97,15 @@ User *zmLoadUser( const char *username, const char *password ) {
|
|||
// According to docs, size of safer_whatever must be 2*length+1 due to unicode conversions + null terminator.
|
||||
mysql_real_escape_string(&dbconn, safer_username, username, username_length );
|
||||
|
||||
BCrypt bcrypt;
|
||||
std::string ptest = "test";
|
||||
std::string hash = bcrypt.generateHash(ptest);
|
||||
Info ("ZM_USER TEST: BCRYPT WORKED AND PRODUCED %s", hash.c_str());
|
||||
|
||||
SHA1 sha1_checksum;
|
||||
sha1_checksum.update (ptest);
|
||||
hash = sha1_checksum.final();
|
||||
Info ("ZM_USER TEST: SHA1 WORKED AND PRODUCED %s", hash.c_str());
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds"
|
||||
" FROM Users where Username = '%s' and Enabled = 1", safer_username );
|
||||
|
||||
if ( password ) {
|
||||
int password_length = strlen(password);
|
||||
char *safer_password = new char[(password_length * 2) + 1];
|
||||
mysql_real_escape_string(&dbconn, safer_password, password, password_length);
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds"
|
||||
" FROM Users WHERE Username = '%s' AND Password = password('%s') AND Enabled = 1",
|
||||
safer_username, safer_password );
|
||||
delete safer_password;
|
||||
} else {
|
||||
snprintf(sql, sizeof(sql),
|
||||
"SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds"
|
||||
" FROM Users where Username = '%s' and Enabled = 1", safer_username );
|
||||
}
|
||||
|
||||
if ( mysql_query(&dbconn, sql) ) {
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
exit(mysql_errno(&dbconn));
|
||||
exit(mysql_errno(&dbconn));
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||
|
@ -143,12 +124,20 @@ User *zmLoadUser( const char *username, const char *password ) {
|
|||
MYSQL_ROW dbrow = mysql_fetch_row(result);
|
||||
|
||||
User *user = new User(dbrow);
|
||||
Info("Authenticated user '%s'", user->getUsername());
|
||||
Info ("Retrieved password for user:%s as %s", user->getUsername(), user->getPassword());
|
||||
|
||||
mysql_free_result(result);
|
||||
delete safer_username;
|
||||
|
||||
return user;
|
||||
if (verifyPassword(password, user->getPassword())) {
|
||||
Info("Authenticated user '%s'", user->getUsername());
|
||||
mysql_free_result(result);
|
||||
delete safer_username;
|
||||
return user;
|
||||
}
|
||||
else {
|
||||
Warning("Unable to authenticate user %s", username);
|
||||
mysql_free_result(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Function to validate an authentication string
|
||||
|
|
Loading…
Reference in New Issue