Merge pull request #2874 from hax0kartik/2810-libjwt
Add libjwt and remove gnutls-openssl wrapper
This commit is contained in:
parent
af2b6c435e
commit
3a129a8818
|
@ -347,9 +347,37 @@ else(JPEG_FOUND)
|
|||
"ZoneMinder requires jpeg but it was not found on your system")
|
||||
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
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
if(NOT HAVE_LIBGNUTLS OR NOT HAVE_LIBJWT)
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
set(HAVE_LIBOPENSSL 1)
|
||||
set(HAVE_LIBCRYPTO 1)
|
||||
list(APPEND ZM_BIN_LIBS "${OPENSSL_LIBRARIES}")
|
||||
|
@ -357,9 +385,10 @@ if(OPENSSL_FOUND)
|
|||
set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
|
||||
check_include_file("openssl/md5.h" HAVE_OPENSSL_MD5_H)
|
||||
set(optlibsfound "${optlibsfound} OpenSSL")
|
||||
else(OPENSSL_FOUND)
|
||||
else(OPENSSL_FOUND)
|
||||
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)
|
||||
find_library(PTHREAD_LIBRARIES pthread)
|
||||
|
@ -416,28 +445,6 @@ else(GCRYPT_LIBRARIES)
|
|||
set(optlibsnotfound "${optlibsnotfound} GCrypt")
|
||||
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)
|
||||
find_library(MYSQLCLIENT_LIBRARIES mysqlclient PATH_SUFFIXES mysql)
|
||||
if(MYSQLCLIENT_LIBRARIES)
|
||||
|
|
|
@ -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)
|
|
@ -1,12 +1,81 @@
|
|||
#include "zm.h"
|
||||
#include "zm_crypt.h"
|
||||
#include "BCrypt.hpp"
|
||||
#include "jwt.h"
|
||||
#if HAVE_LIBJWT
|
||||
#include <jwt.h>
|
||||
#else
|
||||
#include "jwt_cpp.h"
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#if HAVE_LIBCRYPTO
|
||||
#include <openssl/sha.h>
|
||||
#elif HAVE_GNUTLS_GNUTLS_H
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
// 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::string username = "";
|
||||
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);
|
||||
}
|
||||
#endif // HAVE_LIBJWT
|
||||
|
||||
bool verifyPassword(const char *username, const char *input_password, const char *db_password_hash) {
|
||||
bool password_correct = false;
|
||||
|
@ -70,10 +140,16 @@ bool verifyPassword(const char *username, const char *input_password, const char
|
|||
// MYSQL PASSWORD
|
||||
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_final[SHA_DIGEST_LENGTH];
|
||||
|
||||
#if HAVE_LIBCRYPTO
|
||||
SHA_CTX ctx1, ctx2;
|
||||
|
||||
//get first iteration
|
||||
SHA1_Init(&ctx1);
|
||||
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_Update(&ctx2, digest_interim,SHA_DIGEST_LENGTH);
|
||||
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];
|
||||
final_hash[0] = '*';
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
#ifndef ZM_RTSP_AUTH_H
|
||||
#define ZM_RTSP_AUTH_H
|
||||
|
||||
#if HAVE_GNUTLS_OPENSSL_H
|
||||
#include <gnutls/openssl.h>
|
||||
#endif
|
||||
#if HAVE_GNUTLS_GNUTLS_H
|
||||
#include <gnutls/gnutls.h>
|
||||
#endif
|
||||
|
|
|
@ -27,9 +27,6 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#if HAVE_GNUTLS_OPENSSL_H
|
||||
#include <gnutls/openssl.h>
|
||||
#endif
|
||||
#if HAVE_GNUTLS_GNUTLS_H
|
||||
#include <gnutls/gnutls.h>
|
||||
#endif
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#cmakedefine HAVE_LIBGCRYPT 1
|
||||
#cmakedefine HAVE_GCRYPT_H 1
|
||||
#cmakedefine HAVE_LIBGNUTLS 1
|
||||
#cmakedefine HAVE_GNUTLS_OPENSSL_H 1
|
||||
#cmakedefine HAVE_GNUTLS_GNUTLS_H 1
|
||||
#cmakedefine HAVE_LIBMYSQLCLIENT 1
|
||||
#cmakedefine HAVE_MYSQL_H 1
|
||||
|
@ -66,6 +65,7 @@
|
|||
#cmakedefine HAVE_MP4_H 1
|
||||
#cmakedefine HAVE_MP4V2_H 1
|
||||
#cmakedefine HAVE_MP4V2_MP4V2_H 1
|
||||
#cmakedefine HAVE_LIBJWT 1
|
||||
|
||||
/* Authenication checks */
|
||||
#cmakedefine HAVE_MD5_OPENSSL 1
|
||||
|
|
Loading…
Reference in New Issue