Fix confict when pulling master
This commit is contained in:
commit
9e39924095
|
@ -1,3 +1,9 @@
|
|||
zoneminder (1.28.0+1-utopic-SNAPSHOT2014112001) utopic; urgency=medium
|
||||
|
||||
* Various fixes and developments since 1.28.0. Includes Digest-Auth for HTTP and better for RTSP
|
||||
|
||||
-- Isaac Connor <iconnor@connortechnology.com> Thu, 20 Nov 2014 10:57:57 -0500
|
||||
|
||||
zoneminder (1.28.0-trusty) trusty; urgency=medium
|
||||
|
||||
* Release
|
||||
|
|
|
@ -29,7 +29,6 @@ void zmLoadConfig()
|
|||
{
|
||||
FILE *cfg;
|
||||
char line[512];
|
||||
char *val;
|
||||
if ( (cfg = fopen( ZM_CONFIG, "r")) == NULL )
|
||||
{
|
||||
Fatal( "Can't open %s: %s", ZM_CONFIG, strerror(errno) );
|
||||
|
@ -82,19 +81,16 @@ void zmLoadConfig()
|
|||
white_len = strspn( val_ptr, " \t" );
|
||||
val_ptr += white_len;
|
||||
|
||||
val = (char *)malloc( strlen(val_ptr)+1 );
|
||||
strncpy( val, val_ptr, strlen(val_ptr)+1 );
|
||||
|
||||
if ( strcasecmp( name_ptr, "ZM_DB_HOST" ) == 0 )
|
||||
staticConfig.DB_HOST = val;
|
||||
staticConfig.DB_HOST = std::string(val_ptr);
|
||||
else if ( strcasecmp( name_ptr, "ZM_DB_NAME" ) == 0 )
|
||||
staticConfig.DB_NAME = val;
|
||||
staticConfig.DB_NAME = std::string(val_ptr);
|
||||
else if ( strcasecmp( name_ptr, "ZM_DB_USER" ) == 0 )
|
||||
staticConfig.DB_USER = val;
|
||||
staticConfig.DB_USER = std::string(val_ptr);
|
||||
else if ( strcasecmp( name_ptr, "ZM_DB_PASS" ) == 0 )
|
||||
staticConfig.DB_PASS = val;
|
||||
staticConfig.DB_PASS = std::string(val_ptr);
|
||||
else if ( strcasecmp( name_ptr, "ZM_PATH_WEB" ) == 0 )
|
||||
staticConfig.PATH_WEB = val;
|
||||
staticConfig.PATH_WEB = std::string(val_ptr);
|
||||
else
|
||||
{
|
||||
// We ignore this now as there may be more parameters than the
|
||||
|
|
|
@ -140,6 +140,22 @@ Image::Image( const Image &p_image )
|
|||
Image::~Image()
|
||||
{
|
||||
DumpImgBuffer();
|
||||
if ( initialised )
|
||||
{
|
||||
delete[] y_table;
|
||||
delete[] uv_table;
|
||||
delete[] r_v_table;
|
||||
delete[] g_v_table;
|
||||
delete[] g_u_table;
|
||||
delete[] b_u_table;
|
||||
initialised = false;
|
||||
}
|
||||
if ( jpg_dcinfo )
|
||||
{
|
||||
jpeg_destroy_decompress( jpg_dcinfo );
|
||||
delete jpg_dcinfo;
|
||||
jpg_dcinfo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Image::Initialise()
|
||||
|
|
|
@ -334,6 +334,8 @@ Monitor::Monitor(
|
|||
camera( p_camera ),
|
||||
n_zones( p_n_zones ),
|
||||
zones( p_zones ),
|
||||
timestamps( 0 ),
|
||||
images( 0 ),
|
||||
iDoNativeMotDet( p_DoNativeMotDet ),
|
||||
ThePluginManager( p_id )
|
||||
{
|
||||
|
@ -613,6 +615,14 @@ bool Monitor::connect() {
|
|||
|
||||
Monitor::~Monitor()
|
||||
{
|
||||
if ( timestamps ) {
|
||||
delete[] timestamps;
|
||||
timestamps = 0;
|
||||
}
|
||||
if ( images ) {
|
||||
delete[] images;
|
||||
images = 0;
|
||||
}
|
||||
if ( mem_ptr ) {
|
||||
if ( event )
|
||||
Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() );
|
||||
|
@ -1306,8 +1316,6 @@ bool Monitor::Analyse()
|
|||
}
|
||||
|
||||
static bool static_undef = true;
|
||||
static struct timeval **timestamps;
|
||||
static Image **images;
|
||||
static int last_section_mod = 0;
|
||||
static bool last_signal;
|
||||
|
||||
|
|
|
@ -289,13 +289,15 @@ protected:
|
|||
int n_zones;
|
||||
Zone **zones;
|
||||
|
||||
struct timeval **timestamps;
|
||||
Image **images;
|
||||
|
||||
int iDoNativeMotDet;
|
||||
#if ZM_PLUGINS_ON
|
||||
PluginManager ThePluginManager;
|
||||
#else
|
||||
int ThePluginManager;
|
||||
#endif
|
||||
|
||||
int n_linked_monitors;
|
||||
MonitorLink **linked_monitors;
|
||||
|
||||
|
|
|
@ -63,8 +63,16 @@ void RemoteCamera::Initialise()
|
|||
auth = host.substr( 0, authIndex );
|
||||
host.erase( 0, authIndex+1 );
|
||||
auth64 = base64Encode( auth );
|
||||
|
||||
authIndex = auth.rfind( ':' );
|
||||
username = auth.substr(0,authIndex);
|
||||
password = auth.substr( authIndex+1, auth.length() );
|
||||
|
||||
}
|
||||
|
||||
mNeedAuth = false;
|
||||
mAuthenticator = new Authenticator(username,password);
|
||||
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define ZM_REMOTE_CAMERA_H
|
||||
|
||||
#include "zm_camera.h"
|
||||
#include "zm_rtsp_auth.h"
|
||||
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
@ -39,8 +40,17 @@ protected:
|
|||
std::string port;
|
||||
std::string path;
|
||||
std::string auth;
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string auth64;
|
||||
|
||||
// Reworked authentication system
|
||||
// First try without authentication, even if we have a username and password
|
||||
// on receiving a 401 response, select authentication method (basic or digest)
|
||||
// fill required fields and set needAuth
|
||||
// subsequent requests can set the required authentication header.
|
||||
bool mNeedAuth;
|
||||
Authenticator* mAuthenticator;
|
||||
protected:
|
||||
struct addrinfo *hp;
|
||||
|
||||
|
@ -53,6 +63,8 @@ public:
|
|||
const std::string &Port() const { return( port ); }
|
||||
const std::string &Path() const { return( path ); }
|
||||
const std::string &Auth() const { return( auth ); }
|
||||
const std::string &Username() const { return( username ); }
|
||||
const std::string &Password() const { return( password ); }
|
||||
|
||||
virtual void Initialise();
|
||||
virtual void Terminate() = 0;
|
||||
|
|
|
@ -62,7 +62,7 @@ void RemoteCameraHttp::Initialise()
|
|||
{
|
||||
request = stringtf( "GET %s HTTP/%s\r\n", path.c_str(), config.http_version );
|
||||
request += stringtf( "User-Agent: %s/%s\r\n", config.http_ua, ZM_VERSION );
|
||||
request += stringtf( "Host: %s\r\n", host .c_str());
|
||||
request += stringtf( "Host: %s\r\n", host.c_str());
|
||||
if ( strcmp( config.http_version, "1.0" ) == 0 )
|
||||
request += stringtf( "Connection: Keep-Alive\r\n" );
|
||||
if ( !auth.empty() )
|
||||
|
@ -130,6 +130,7 @@ int RemoteCameraHttp::Disconnect()
|
|||
|
||||
int RemoteCameraHttp::SendRequest()
|
||||
{
|
||||
Debug( 2, "Sending request: %s", request.c_str() );
|
||||
if ( write( sd, request.data(), request.length() ) < 0 )
|
||||
{
|
||||
Error( "Can't write: %s", strerror(errno) );
|
||||
|
@ -216,6 +217,8 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected )
|
|||
}
|
||||
while ( total_bytes_to_read );
|
||||
|
||||
Debug( 3, buffer );
|
||||
|
||||
return( total_bytes_read );
|
||||
}
|
||||
|
||||
|
@ -280,9 +283,31 @@ int RemoteCameraHttp::GetResponse()
|
|||
status_code = atoi( status_expr->MatchString( 2 ) );
|
||||
status_mesg = status_expr->MatchString( 3 );
|
||||
|
||||
if ( status_code < 200 || status_code > 299 )
|
||||
{
|
||||
Error( "Invalid response status %d: %s", status_code, status_mesg );
|
||||
if ( status_code == 401 ) {
|
||||
if ( mNeedAuth ) {
|
||||
Error( "Failed authentication: " );
|
||||
return( -1 );
|
||||
}
|
||||
mNeedAuth = true;
|
||||
std::string Header = header;
|
||||
|
||||
mAuthenticator->checkAuthResponse(Header);
|
||||
if ( mAuthenticator->auth_method() == AUTH_DIGEST ) {
|
||||
Debug( 2, "Need Digest Authentication" );
|
||||
request = stringtf( "GET %s HTTP/%s\r\n", path.c_str(), config.http_version );
|
||||
request += stringtf( "User-Agent: %s/%s\r\n", config.http_ua, ZM_VERSION );
|
||||
request += stringtf( "Host: %s\r\n", host.c_str());
|
||||
if ( strcmp( config.http_version, "1.0" ) == 0 )
|
||||
request += stringtf( "Connection: Keep-Alive\r\n" );
|
||||
request += mAuthenticator->getAuthHeader( "GET", path.c_str() );
|
||||
request += "\r\n";
|
||||
|
||||
Debug( 2, "New request header: %s", request.c_str() );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
} else if ( status_code < 200 || status_code > 299 ) {
|
||||
Error( "Invalid response status %d: %s\n%s", status_code, status_mesg, (char *)buffer );
|
||||
return( -1 );
|
||||
}
|
||||
Debug( 3, "Got status '%d' (%s), http version %s", status_code, status_mesg, http_version );
|
||||
|
@ -545,11 +570,13 @@ int RemoteCameraHttp::GetResponse()
|
|||
static const char *content_length_match = "Content-length:";
|
||||
static const char *content_type_match = "Content-type:";
|
||||
static const char *boundary_match = "boundary=";
|
||||
static const char *authenticate_match = "WWW-Authenticate:";
|
||||
static int http_match_len = 0;
|
||||
static int connection_match_len = 0;
|
||||
static int content_length_match_len = 0;
|
||||
static int content_type_match_len = 0;
|
||||
static int boundary_match_len = 0;
|
||||
static int authenticate_match_len = 0;
|
||||
|
||||
if ( !http_match_len )
|
||||
http_match_len = strlen( http_match );
|
||||
|
@ -561,6 +588,8 @@ int RemoteCameraHttp::GetResponse()
|
|||
content_type_match_len = strlen( content_type_match );
|
||||
if ( !boundary_match_len )
|
||||
boundary_match_len = strlen( boundary_match );
|
||||
if ( !authenticate_match_len )
|
||||
authenticate_match_len = strlen( authenticate_match );
|
||||
|
||||
static int n_headers;
|
||||
//static char *headers[32];
|
||||
|
@ -573,6 +602,7 @@ int RemoteCameraHttp::GetResponse()
|
|||
static char *content_length_header;
|
||||
static char *content_type_header;
|
||||
static char *boundary_header;
|
||||
static char *authenticate_header;
|
||||
static char subcontent_length_header[32];
|
||||
static char subcontent_type_header[64];
|
||||
|
||||
|
@ -596,6 +626,7 @@ int RemoteCameraHttp::GetResponse()
|
|||
connection_header = 0;
|
||||
content_length_header = 0;
|
||||
content_type_header = 0;
|
||||
authenticate_header = 0;
|
||||
|
||||
http_version[0] = '\0';
|
||||
status_code [0]= '\0';
|
||||
|
@ -674,6 +705,12 @@ int RemoteCameraHttp::GetResponse()
|
|||
content_length_header = header_ptr+content_length_match_len;
|
||||
Debug( 6, "Got content length header '%s'", header_ptr );
|
||||
}
|
||||
|
||||
else if ( !authenticate_header && (strncasecmp( header_ptr, authenticate_match, authenticate_match_len) == 0) )
|
||||
{
|
||||
authenticate_header = header_ptr;
|
||||
Debug( 6, "Got authenticate header '%s'", header_ptr );
|
||||
}
|
||||
else if ( !content_type_header && (strncasecmp( header_ptr, content_type_match, content_type_match_len) == 0) )
|
||||
{
|
||||
content_type_header = header_ptr+content_type_match_len;
|
||||
|
@ -721,7 +758,36 @@ int RemoteCameraHttp::GetResponse()
|
|||
start_ptr += strspn( start_ptr, " " );
|
||||
strcpy( status_mesg, start_ptr );
|
||||
|
||||
if ( status < 200 || status > 299 )
|
||||
if ( status == 401 ) {
|
||||
if ( mNeedAuth ) {
|
||||
Error( "Failed authentication: " );
|
||||
return( -1 );
|
||||
}
|
||||
if ( ! authenticate_header ) {
|
||||
Error( "Failed authentication, but don't have an authentication header: " );
|
||||
return( -1 );
|
||||
}
|
||||
mNeedAuth = true;
|
||||
std::string Header = authenticate_header;
|
||||
Debug(2, "Checking for digest auth in %s", authenticate_header );
|
||||
|
||||
mAuthenticator->checkAuthResponse(Header);
|
||||
if ( mAuthenticator->auth_method() == AUTH_DIGEST ) {
|
||||
Debug( 2, "Need Digest Authentication" );
|
||||
request = stringtf( "GET %s HTTP/%s\r\n", path.c_str(), config.http_version );
|
||||
request += stringtf( "User-Agent: %s/%s\r\n", config.http_ua, ZM_VERSION );
|
||||
request += stringtf( "Host: %s\r\n", host.c_str());
|
||||
if ( strcmp( config.http_version, "1.0" ) == 0 )
|
||||
request += stringtf( "Connection: Keep-Alive\r\n" );
|
||||
request += mAuthenticator->getAuthHeader( "GET", path.c_str() );
|
||||
request += "\r\n";
|
||||
|
||||
Debug( 2, "New request header: %s", request.c_str() );
|
||||
return( 0 );
|
||||
} else {
|
||||
Debug( 2, "Need some other kind of Authentication" );
|
||||
}
|
||||
} else if ( status < 200 || status > 299 )
|
||||
{
|
||||
Error( "Invalid response status %s: %s", status_code, status_mesg );
|
||||
return( -1 );
|
||||
|
|
|
@ -67,34 +67,6 @@ bool RtspThread::sendCommand( std::string message )
|
|||
return( true );
|
||||
}
|
||||
|
||||
// find WWW-Authenticate header, send to Authenticator to extract required subfields
|
||||
void RtspThread::checkAuthResponse(std::string &response)
|
||||
{
|
||||
std::string authLine;
|
||||
StringVector lines = split( response, "\r\n" );
|
||||
const char* authenticate_match = "WWW-Authenticate:";
|
||||
size_t authenticate_match_len = strlen(authenticate_match);
|
||||
|
||||
for ( size_t i = 0; i < lines.size(); i++ )
|
||||
{
|
||||
// stop at end of headers
|
||||
if (lines[i].length()==0)
|
||||
break;
|
||||
|
||||
if (strncasecmp(lines[i].c_str(),authenticate_match,authenticate_match_len) == 0)
|
||||
{
|
||||
authLine = lines[i];
|
||||
Debug( 2, "Found auth line at %d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!authLine.empty())
|
||||
{
|
||||
Debug( 2, "Analyze auth line %s", authLine.c_str());
|
||||
mAuthenticator->authHandleHeader( trimSpaces(authLine.substr(authenticate_match_len,authLine.length()-authenticate_match_len)) );
|
||||
}
|
||||
}
|
||||
|
||||
bool RtspThread::recvResponse( std::string &response )
|
||||
{
|
||||
if ( mRtspSocket.recv( response ) < 0 )
|
||||
|
@ -120,7 +92,7 @@ bool RtspThread::recvResponse( std::string &response )
|
|||
if ( respCode == 401)
|
||||
{
|
||||
Debug( 2, "Got 401 access denied response code, check WWW-Authenticate header and retry");
|
||||
checkAuthResponse(response);
|
||||
mAuthenticator->checkAuthResponse(response);
|
||||
mNeedAuth = true;
|
||||
return( false );
|
||||
}
|
||||
|
@ -326,7 +298,7 @@ int RtspThread::run()
|
|||
// for requested authentication method
|
||||
if (respCode == 401 && !authTried) {
|
||||
mNeedAuth = true;
|
||||
checkAuthResponse(response);
|
||||
mAuthenticator->checkAuthResponse(response);
|
||||
Debug(2, "Processed 401 response");
|
||||
mRtspSocket.close();
|
||||
if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) )
|
||||
|
@ -361,7 +333,7 @@ int RtspThread::run()
|
|||
int localPorts[2] = { 0, 0 };
|
||||
|
||||
// Request supported RTSP commands by the server
|
||||
message = "OPTIONS * RTSP/1.0\r\n";
|
||||
message = "OPTIONS "+mUrl+" RTSP/1.0\r\n";
|
||||
if ( !sendCommand( message ) )
|
||||
return( -1 );
|
||||
if ( !recvResponse( response ) )
|
||||
|
@ -680,7 +652,7 @@ int RtspThread::run()
|
|||
select.addReader( &mRtspSocket );
|
||||
|
||||
Buffer buffer( ZM_NETWORK_BUFSIZ );
|
||||
std::string keepaliveMessage = "OPTIONS * RTSP/1.0\r\n";
|
||||
std::string keepaliveMessage = "OPTIONS "+mUrl+" RTSP/1.0\r\n";
|
||||
std::string keepaliveResponse = "RTSP/1.0 200 OK\r\n";
|
||||
while ( !mStop && select.wait() >= 0 )
|
||||
{
|
||||
|
|
|
@ -38,6 +38,8 @@ Authenticator::Authenticator(std::string &username, std::string password) {
|
|||
fAuthMethod = AUTH_UNDEFINED;
|
||||
fUsername = username;
|
||||
fPassword = password;
|
||||
nc = 1;
|
||||
fCnonce = "0a4f113b";
|
||||
}
|
||||
|
||||
Authenticator::~Authenticator() {
|
||||
|
@ -83,8 +85,12 @@ void Authenticator::authHandleHeader(std::string headerData)
|
|||
fNonce = trimSet( kvPair[1], "\"");
|
||||
continue;
|
||||
}
|
||||
if (key == "qop") {
|
||||
fQop = trimSet( kvPair[1], "\"");
|
||||
continue;
|
||||
}
|
||||
Debug( 2, "Auth data completed. User: %s, realm: %s, nonce: %s", username().c_str(), fRealm.c_str(), fNonce.c_str());
|
||||
}
|
||||
Debug( 2, "Auth data completed. User: %s, realm: %s, nonce: %s, qop: %s", username().c_str(), fRealm.c_str(), fNonce.c_str(), fQop.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,8 +110,13 @@ std::string Authenticator::getAuthHeader(std::string method, std::string uri)
|
|||
{
|
||||
result += std::string("Digest ") +
|
||||
"username=\"" + quote(username()) + "\", realm=\"" + quote(realm()) + "\", " +
|
||||
"nonce=\"" + quote(nonce()) + "\", uri=\"" + quote(uri) + "\", " +
|
||||
"response=\"" + computeDigestResponse(method, uri) + "\"";
|
||||
"nonce=\"" + quote(nonce()) + "\", uri=\"" + quote(uri) + "\"";
|
||||
if ( ! fQop.empty() ) {
|
||||
result += ", qop=" + fQop;
|
||||
result += ", nc=" + stringtf("%08x",nc);
|
||||
result += ", cnonce=" + fCnonce;
|
||||
}
|
||||
result += ", response=\"" + computeDigestResponse(method, uri) + "\"";
|
||||
|
||||
//Authorization: Digest username="zm",
|
||||
// realm="NC-336PW-HD-1080P",
|
||||
|
@ -133,6 +144,7 @@ std::string Authenticator::computeDigestResponse(std::string &method, std::strin
|
|||
|
||||
// Step 1: md5(<username>:<realm>:<password>)
|
||||
std::string ha1Data = username() + ":" + realm() + ":" + password();
|
||||
Debug( 2, "HA1 pre-md5: %s", ha1Data.c_str() );
|
||||
#if HAVE_DECL_MD5
|
||||
MD5((unsigned char*)ha1Data.c_str(), ha1Data.length(), md5buf);
|
||||
#elif HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
|
@ -148,6 +160,7 @@ std::string Authenticator::computeDigestResponse(std::string &method, std::strin
|
|||
|
||||
// Step 2: md5(<cmd>:<url>)
|
||||
std::string ha2Data = method + ":" + uri;
|
||||
Debug( 2, "HA2 pre-md5: %s", ha2Data.c_str() );
|
||||
#if HAVE_DECL_MD5
|
||||
MD5((unsigned char*)ha2Data.c_str(), ha2Data.length(), md5buf );
|
||||
#elif HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
|
@ -162,7 +175,14 @@ std::string Authenticator::computeDigestResponse(std::string &method, std::strin
|
|||
std::string ha2Hash = md5HexBuf;
|
||||
|
||||
// Step 3: md5(ha1:<nonce>:ha2)
|
||||
std::string digestData = ha1Hash + ":" + nonce() + ":" + ha2Hash;
|
||||
std::string digestData = ha1Hash + ":" + nonce();
|
||||
if ( ! fQop.empty() ) {
|
||||
digestData += ":" + stringtf("%08x", nc) + ":"+fCnonce + ":" + fQop;
|
||||
nc ++;
|
||||
// if qop was specified, then we have to include t and a cnonce and an nccount
|
||||
}
|
||||
digestData += ":" + ha2Hash;
|
||||
Debug( 2, "pre-md5: %s", digestData.c_str() );
|
||||
#if HAVE_DECL_MD5
|
||||
MD5((unsigned char*)digestData.c_str(), digestData.length(), md5buf);
|
||||
#elif HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
|
@ -181,3 +201,28 @@ std::string Authenticator::computeDigestResponse(std::string &method, std::strin
|
|||
#endif // HAVE_DECL_MD5
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void Authenticator::checkAuthResponse(std::string &response) {
|
||||
std::string authLine;
|
||||
StringVector lines = split( response, "\r\n" );
|
||||
const char* authenticate_match = "WWW-Authenticate:";
|
||||
size_t authenticate_match_len = strlen(authenticate_match);
|
||||
|
||||
for ( size_t i = 0; i < lines.size(); i++ ) {
|
||||
// stop at end of headers
|
||||
if (lines[i].length()==0)
|
||||
break;
|
||||
|
||||
if (strncasecmp(lines[i].c_str(),authenticate_match,authenticate_match_len) == 0) {
|
||||
authLine = lines[i];
|
||||
Debug( 2, "Found auth line at %d", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!authLine.empty()) {
|
||||
Debug( 2, "Analyze auth line %s", authLine.c_str());
|
||||
authHandleHeader( trimSpaces(authLine.substr(authenticate_match_len,authLine.length()-authenticate_match_len)) );
|
||||
} else {
|
||||
Debug( 2, "Didn't find auth line in %s", authLine.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,10 +32,9 @@
|
|||
#include <openssl/md5.h>
|
||||
#endif // HAVE_GCRYPT_H || HAVE_LIBCRYPTO
|
||||
|
||||
class Authenticator
|
||||
{
|
||||
enum AuthMethod { AUTH_UNDEFINED = 0, AUTH_BASIC = 1, AUTH_DIGEST = 2 };
|
||||
class Authenticator {
|
||||
public:
|
||||
typedef enum { AUTH_UNDEFINED, AUTH_BASIC, AUTH_DIGEST } RtspAuthMethod;
|
||||
Authenticator(std::string &username, std::string password);
|
||||
virtual ~Authenticator();
|
||||
void reset();
|
||||
|
@ -43,19 +42,24 @@ public:
|
|||
std::string realm() { return fRealm; }
|
||||
std::string nonce() { return fNonce; }
|
||||
std::string username() { return fUsername; }
|
||||
AuthMethod auth_method() const { return fAuthMethod; }
|
||||
|
||||
std::string computeDigestResponse( std::string &cmd, std::string &url );
|
||||
void authHandleHeader( std::string headerData );
|
||||
std::string getAuthHeader( std::string method, std::string path );
|
||||
void checkAuthResponse(std::string &response);
|
||||
|
||||
private:
|
||||
std::string password() { return fPassword; }
|
||||
RtspAuthMethod fAuthMethod;
|
||||
AuthMethod fAuthMethod;
|
||||
std::string fRealm;
|
||||
std::string fNonce;
|
||||
std::string fCnonce;
|
||||
std::string fQop;
|
||||
std::string fUsername;
|
||||
std::string fPassword;
|
||||
std::string quote( std::string src );
|
||||
int nc;
|
||||
};
|
||||
|
||||
#endif // ZM_RTSP_AUTH_H
|
||||
|
|
|
@ -296,7 +296,7 @@ int main( int argc, char *argv[] )
|
|||
{
|
||||
delete monitors[i];
|
||||
}
|
||||
delete monitors;
|
||||
delete [] monitors;
|
||||
delete [] alarm_capture_delays;
|
||||
delete [] capture_delays;
|
||||
delete [] next_delays;
|
||||
|
|
Loading…
Reference in New Issue