Add libjwt and remove gnutls-openssl wrapper

This commit is contained in:
hax0kartik 2020-03-05 09:29:27 -08:00
parent 1959b2e070
commit 2091ad8c92
7 changed files with 1751 additions and 44 deletions

View File

@ -347,9 +347,37 @@ else(JPEG_FOUND)
"ZoneMinder requires jpeg but it was not found on your system") "ZoneMinder requires jpeg but it was not found on your system")
endif(JPEG_FOUND) endif(JPEG_FOUND)
# LIBJWT
find_package(LibJWT)
if(LIBJWT_FOUND)
set(HAVE_LIBJWT 1)
set(optlibsfound "${optlibsfound} LIBJWT")
list(APPEND ZM_BIN_LIBS "${LIBJWT_LIBRARY}")
else(LIBJWT_FOUND)
set(optlibsnotfound "${optlibsnotfound} LIBJWT")
endif(LIBJWT_FOUND)
# gnutls (using find_library and find_path)
find_library(GNUTLS_LIBRARIES gnutls)
if(GNUTLS_LIBRARIES)
set(HAVE_LIBGNUTLS 1)
list(APPEND ZM_BIN_LIBS "${GNUTLS_LIBRARIES}")
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h)
if(GNUTLS_INCLUDE_DIR)
include_directories("${GNUTLS_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}")
endif(GNUTLS_INCLUDE_DIR)
mark_as_advanced(FORCE GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR)
check_include_file("gnutls/gnutls.h" HAVE_GNUTLS_GNUTLS_H)
set(optlibsfound "${optlibsfound} GnuTLS")
else(GNUTLS_LIBRARIES)
set(optlibsnotfound "${optlibsnotfound} GnuTLS")
endif(GNUTLS_LIBRARIES)
# OpenSSL # OpenSSL
find_package(OpenSSL) if(NOT HAVE_LIBGNUTLS OR NOT HAVE_LIBJWT)
if(OPENSSL_FOUND) find_package(OpenSSL)
if(OPENSSL_FOUND)
set(HAVE_LIBOPENSSL 1) set(HAVE_LIBOPENSSL 1)
set(HAVE_LIBCRYPTO 1) set(HAVE_LIBCRYPTO 1)
list(APPEND ZM_BIN_LIBS "${OPENSSL_LIBRARIES}") list(APPEND ZM_BIN_LIBS "${OPENSSL_LIBRARIES}")
@ -357,9 +385,10 @@ if(OPENSSL_FOUND)
set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}") set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
check_include_file("openssl/md5.h" HAVE_OPENSSL_MD5_H) check_include_file("openssl/md5.h" HAVE_OPENSSL_MD5_H)
set(optlibsfound "${optlibsfound} OpenSSL") set(optlibsfound "${optlibsfound} OpenSSL")
else(OPENSSL_FOUND) else(OPENSSL_FOUND)
set(optlibsnotfound "${optlibsnotfound} OpenSSL") set(optlibsnotfound "${optlibsnotfound} OpenSSL")
endif(OPENSSL_FOUND) endif(OPENSSL_FOUND)
endif(NOT HAVE_LIBGNUTLS OR NOT HAVE_LIBJWT)
# pthread (using find_library and find_path) # pthread (using find_library and find_path)
find_library(PTHREAD_LIBRARIES pthread) find_library(PTHREAD_LIBRARIES pthread)
@ -416,28 +445,6 @@ else(GCRYPT_LIBRARIES)
set(optlibsnotfound "${optlibsnotfound} GCrypt") set(optlibsnotfound "${optlibsnotfound} GCrypt")
endif(GCRYPT_LIBRARIES) endif(GCRYPT_LIBRARIES)
# gnutls (using find_library and find_path)
find_library(GNUTLS_LIBRARIES gnutls-openssl)
if(NOT GNUTLS_LIBRARIES)
find_library(GNUTLS_LIBRARIES gnutls)
endif(NOT GNUTLS_LIBRARIES)
if(GNUTLS_LIBRARIES)
set(HAVE_LIBGNUTLS 1)
list(APPEND ZM_BIN_LIBS "${GNUTLS_LIBRARIES}")
find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h)
if(GNUTLS_INCLUDE_DIR)
include_directories("${GNUTLS_INCLUDE_DIR}")
set(CMAKE_REQUIRED_INCLUDES "${GNUTLS_INCLUDE_DIR}")
endif(GNUTLS_INCLUDE_DIR)
mark_as_advanced(FORCE GNUTLS_LIBRARIES GNUTLS_INCLUDE_DIR)
check_include_file("gnutls/openssl.h" HAVE_GNUTLS_OPENSSL_H)
check_include_file("gnutls/gnutls.h" HAVE_GNUTLS_GNUTLS_H)
set(optlibsfound "${optlibsfound} GnuTLS")
else(GNUTLS_LIBRARIES)
set(optlibsnotfound "${optlibsnotfound} GnuTLS")
endif(GNUTLS_LIBRARIES)
# mysqlclient (using find_library and find_path) # mysqlclient (using find_library and find_path)
find_library(MYSQLCLIENT_LIBRARIES mysqlclient PATH_SUFFIXES mysql) find_library(MYSQLCLIENT_LIBRARIES mysqlclient PATH_SUFFIXES mysql)
if(MYSQLCLIENT_LIBRARIES) if(MYSQLCLIENT_LIBRARIES)

View File

@ -0,0 +1,28 @@
include(FindPackageHandleStandardArgs)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBJWT QUIET libjwt)
find_path(LIBJWT_INCLUDE_DIR
NAMES jwt.h
HINTS ${PC_LIBJWT_INCLUDEDIR} ${PC_LIBJWT_INCLUDE_DIRS}
)
find_library(LIBJWT_LIBRARY
NAMES jwt-gnutls libjwt-gnutls liblibjwt-gnutls
HINTS ${PC_LIBJWT_LIBDIR} ${PC_LIBJWT_LIBRARY_DIR}
)
find_package_handle_standard_args(LibJWT
REQUIRED_VARS LIBJWT_INCLUDE_DIR LIBJWT_LIBRARY
)
if(LIBJWT_FOUND)
add_library(libjwt STATIC IMPORTED GLOBAL)
set_target_properties(libjwt PROPERTIES
IMPORTED_LOCATION "${LIBJWT_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${LIBJWT_INCLUDE_DIR}"
)
endif()
mark_as_advanced(LIBJWT_INCLUDE_DIR LIBJWT_LIBRARY)

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,81 @@
#include "zm.h" #include "zm.h"
#include "zm_crypt.h" #include "zm_crypt.h"
#include "BCrypt.hpp" #include "BCrypt.hpp"
#include "jwt.h" #if HAVE_LIBJWT
#include <jwt.h>
#else
#include "jwt_cpp.h"
#endif
#include <algorithm> #include <algorithm>
#if HAVE_LIBCRYPTO
#include <openssl/sha.h> #include <openssl/sha.h>
#elif HAVE_GNUTLS_GNUTLS_H
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#endif
#include <string.h> #include <string.h>
// returns username if valid, "" if not // returns username if valid, "" if not
#if HAVE_LIBJWT
std::pair <std::string, unsigned int> verifyToken(std::string jwt_token_str, std::string key) {
std::string username = "";
unsigned int token_issued_at = 0;
int err = 0;
jwt_t *jwt = nullptr;
err = jwt_new(&jwt);
if( err ) {
Error("Unable to Allocate JWT object");
return std::make_pair("", 0);
}
err = jwt_set_alg(jwt, JWT_ALG_HS256, (const unsigned char*)key.c_str(), key.length());
if( err ) {
jwt_free(jwt);
Error("Error setting Algorithm for JWT decode");
return std::make_pair("", 0);
}
err = jwt_decode(&jwt, jwt_token_str.c_str(), nullptr, 0);
if( err ) {
jwt_free(jwt);
Error("Could not decode JWT");
return std::make_pair("", 0);
}
const char *c_type = jwt_get_grant(jwt, (const char*)"type");
if ( !c_type ) {
jwt_free(jwt);
Error("Missing token type. This should not happen");
return std::make_pair("", 0);
} else if ( std::string(c_type) != "access" ) {
jwt_free(jwt);
Error("Only access tokens are allowed. Please do not use refresh tokens");
return std::make_pair("", 0);
}
const char *c_username = jwt_get_grant(jwt, (const char*)"user");
if( !c_username ) {
jwt_free(jwt);
Error("User not found in claim");
return std::make_pair("", 0);
}
username = std::string(c_username);
Debug(1, "Got %s as user claim from token", username.c_str());
token_issued_at = (unsigned int)jwt_get_grant_int(jwt, "iat");
if ( errno == ENOENT ) {
jwt_free(jwt);
Error("IAT not found in claim. This should not happen");
return std::make_pair("", 0);
}
Debug(1, "Got IAT token=%u", token_issued_at);
jwt_free(jwt);
return std::make_pair(username, token_issued_at);
}
#else // HAVE_LIBJWT
std::pair <std::string, unsigned int> verifyToken(std::string jwt_token_str, std::string key) { std::pair <std::string, unsigned int> verifyToken(std::string jwt_token_str, std::string key) {
std::string username = ""; std::string username = "";
unsigned int token_issued_at = 0; unsigned int token_issued_at = 0;
@ -58,6 +127,7 @@ std::pair <std::string, unsigned int> verifyToken(std::string jwt_token_str, std
} }
return std::make_pair(username, token_issued_at); return std::make_pair(username, token_issued_at);
} }
#endif // HAVE_LIBJWT
bool verifyPassword(const char *username, const char *input_password, const char *db_password_hash) { bool verifyPassword(const char *username, const char *input_password, const char *db_password_hash) {
bool password_correct = false; bool password_correct = false;
@ -70,10 +140,16 @@ bool verifyPassword(const char *username, const char *input_password, const char
// MYSQL PASSWORD // MYSQL PASSWORD
Debug(1, "%s is using an MD5 encoded password", username); Debug(1, "%s is using an MD5 encoded password", username);
SHA_CTX ctx1, ctx2; #ifndef SHA_DIGEST_LENGTH
#define SHA_DIGEST_LENGTH 20
#endif
unsigned char digest_interim[SHA_DIGEST_LENGTH]; unsigned char digest_interim[SHA_DIGEST_LENGTH];
unsigned char digest_final[SHA_DIGEST_LENGTH]; unsigned char digest_final[SHA_DIGEST_LENGTH];
#if HAVE_LIBCRYPTO
SHA_CTX ctx1, ctx2;
//get first iteration //get first iteration
SHA1_Init(&ctx1); SHA1_Init(&ctx1);
SHA1_Update(&ctx1, input_password, strlen(input_password)); SHA1_Update(&ctx1, input_password, strlen(input_password));
@ -83,6 +159,15 @@ bool verifyPassword(const char *username, const char *input_password, const char
SHA1_Init(&ctx2); SHA1_Init(&ctx2);
SHA1_Update(&ctx2, digest_interim,SHA_DIGEST_LENGTH); SHA1_Update(&ctx2, digest_interim,SHA_DIGEST_LENGTH);
SHA1_Final (digest_final, &ctx2); SHA1_Final (digest_final, &ctx2);
#elif HAVE_GNUTLS_GNUTLS_H
//get first iteration
gnutls_hash_fast(GNUTLS_DIG_SHA1, input_password, strlen(input_password), digest_interim);
//2nd iteration
gnutls_hash_fast(GNUTLS_DIG_SHA1, digest_interim, SHA_DIGEST_LENGTH, digest_final);
#else
Error("Authentication Error. ZoneMinder not built with GnuTLS or Openssl");
return false;
#endif
char final_hash[SHA_DIGEST_LENGTH * 2 +2]; char final_hash[SHA_DIGEST_LENGTH * 2 +2];
final_hash[0] = '*'; final_hash[0] = '*';

View File

@ -19,9 +19,6 @@
#ifndef ZM_RTSP_AUTH_H #ifndef ZM_RTSP_AUTH_H
#define ZM_RTSP_AUTH_H #define ZM_RTSP_AUTH_H
#if HAVE_GNUTLS_OPENSSL_H
#include <gnutls/openssl.h>
#endif
#if HAVE_GNUTLS_GNUTLS_H #if HAVE_GNUTLS_GNUTLS_H
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
#endif #endif

View File

@ -27,9 +27,6 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#if HAVE_GNUTLS_OPENSSL_H
#include <gnutls/openssl.h>
#endif
#if HAVE_GNUTLS_GNUTLS_H #if HAVE_GNUTLS_GNUTLS_H
#include <gnutls/gnutls.h> #include <gnutls/gnutls.h>
#endif #endif

View File

@ -38,7 +38,6 @@
#cmakedefine HAVE_LIBGCRYPT 1 #cmakedefine HAVE_LIBGCRYPT 1
#cmakedefine HAVE_GCRYPT_H 1 #cmakedefine HAVE_GCRYPT_H 1
#cmakedefine HAVE_LIBGNUTLS 1 #cmakedefine HAVE_LIBGNUTLS 1
#cmakedefine HAVE_GNUTLS_OPENSSL_H 1
#cmakedefine HAVE_GNUTLS_GNUTLS_H 1 #cmakedefine HAVE_GNUTLS_GNUTLS_H 1
#cmakedefine HAVE_LIBMYSQLCLIENT 1 #cmakedefine HAVE_LIBMYSQLCLIENT 1
#cmakedefine HAVE_MYSQL_H 1 #cmakedefine HAVE_MYSQL_H 1
@ -66,6 +65,7 @@
#cmakedefine HAVE_MP4_H 1 #cmakedefine HAVE_MP4_H 1
#cmakedefine HAVE_MP4V2_H 1 #cmakedefine HAVE_MP4V2_H 1
#cmakedefine HAVE_MP4V2_MP4V2_H 1 #cmakedefine HAVE_MP4V2_MP4V2_H 1
#cmakedefine HAVE_LIBJWT 1
/* Authenication checks */ /* Authenication checks */
#cmakedefine HAVE_MD5_OPENSSL 1 #cmakedefine HAVE_MD5_OPENSSL 1