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")
|
"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)
|
||||||
|
|
|
@ -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.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] = '*';
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue