Merge branch 'master' of github.com:ZoneMinder/zoneminder
commit
4ff69c3156
|
@ -119,6 +119,8 @@ FfmpegCamera::FfmpegCamera(
|
|||
hwaccel_name(p_hwaccel_name),
|
||||
hwaccel_device(p_hwaccel_device)
|
||||
{
|
||||
mMaskedPath = mask_authentication(mPath);
|
||||
mMaskedSecondPath = mask_authentication(mSecondPath);
|
||||
if ( capture ) {
|
||||
FFMPEGInit();
|
||||
}
|
||||
|
@ -161,12 +163,12 @@ FfmpegCamera::~FfmpegCamera() {
|
|||
int FfmpegCamera::PrimeCapture() {
|
||||
start_read_time = std::chrono::steady_clock::now();
|
||||
if ( mCanCapture ) {
|
||||
Debug(1, "Priming capture from %s, Closing", mPath.c_str());
|
||||
Debug(1, "Priming capture from %s, Closing", mMaskedPath.c_str());
|
||||
Close();
|
||||
}
|
||||
mVideoStreamId = -1;
|
||||
mAudioStreamId = -1;
|
||||
Debug(1, "Priming capture from %s", mPath.c_str());
|
||||
Debug(1, "Priming capture from %s", mMaskedPath.c_str());
|
||||
|
||||
return OpenFfmpeg();
|
||||
}
|
||||
|
@ -294,7 +296,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
mPath = mPath.substr(7);
|
||||
} // end if RTSP
|
||||
|
||||
Debug(1, "Calling avformat_open_input for %s", mPath.c_str());
|
||||
Debug(1, "Calling avformat_open_input for %s", mMaskedPath.c_str());
|
||||
|
||||
mFormatContext = avformat_alloc_context();
|
||||
mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback;
|
||||
|
@ -321,7 +323,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
ret = avformat_find_stream_info(mFormatContext, nullptr);
|
||||
if (ret < 0) {
|
||||
Error("Unable to find stream info from %s due to: %s",
|
||||
mPath.c_str(), av_make_error_string(ret).c_str());
|
||||
mMaskedPath.c_str(), av_make_error_string(ret).c_str());
|
||||
avformat_close_input(&mFormatContext);
|
||||
return -1;
|
||||
}
|
||||
|
@ -374,7 +376,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
mVideoCodec = avcodec_find_decoder(mVideoStream->codecpar->codec_id);
|
||||
if (!mVideoCodec) {
|
||||
// Try and get the codec from the codec context
|
||||
Error("Can't find codec for video stream from %s", mPath.c_str());
|
||||
Error("Can't find codec for video stream from %s", mMaskedPath.c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -483,7 +485,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
Warning("Option %s not recognized by ffmpeg", e->key);
|
||||
}
|
||||
if (ret < 0) {
|
||||
Error("Unable to open codec for video stream from %s", mPath.c_str());
|
||||
Error("Unable to open codec for video stream from %s", mMaskedPath.c_str());
|
||||
av_dict_free(&opts);
|
||||
return -1;
|
||||
}
|
||||
|
@ -504,7 +506,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
if ( mAudioStreamId >= 0 ) {
|
||||
const AVCodec *mAudioCodec = nullptr;
|
||||
if (!(mAudioCodec = avcodec_find_decoder(mAudioStream->codecpar->codec_id))) {
|
||||
Debug(1, "Can't find codec for audio stream from %s", mPath.c_str());
|
||||
Debug(1, "Can't find codec for audio stream from %s", mMaskedPath.c_str());
|
||||
} else {
|
||||
mAudioCodecContext = avcodec_alloc_context3(mAudioCodec);
|
||||
avcodec_parameters_to_context(mAudioCodecContext, mAudioStream->codecpar);
|
||||
|
@ -512,7 +514,7 @@ int FfmpegCamera::OpenFfmpeg() {
|
|||
zm_dump_stream_format((mSecondFormatContext?mSecondFormatContext:mFormatContext), mAudioStreamId, 0, 0);
|
||||
// Open the codec
|
||||
if (avcodec_open2(mAudioCodecContext, mAudioCodec, nullptr) < 0) {
|
||||
Error("Unable to open codec for audio stream from %s", mPath.c_str());
|
||||
Error("Unable to open codec for audio stream from %s", mMaskedPath.c_str());
|
||||
return -1;
|
||||
} // end if opened
|
||||
} // end if found decoder
|
||||
|
|
|
@ -36,7 +36,9 @@ typedef struct DecodeContext {
|
|||
class FfmpegCamera : public Camera {
|
||||
protected:
|
||||
std::string mPath;
|
||||
std::string mMaskedPath;
|
||||
std::string mSecondPath;
|
||||
std::string mMaskedSecondPath;
|
||||
std::string mMethod;
|
||||
std::string mOptions;
|
||||
|
||||
|
|
|
@ -442,3 +442,32 @@ std::string QueryString::parseValue(std::istream &input) {
|
|||
|
||||
return UriDecode(url_encoded_value);
|
||||
}
|
||||
|
||||
std::string mask_authentication(const std::string &url) {
|
||||
std::string masked_url = url;
|
||||
std::size_t at_at = masked_url.find("@");
|
||||
if (at_at == std::string::npos) {
|
||||
return masked_url;
|
||||
}
|
||||
std::size_t password_at = masked_url.rfind(":", at_at);
|
||||
|
||||
if (password_at == std::string::npos) {
|
||||
// no : means no http:// either so something liek username@192.168.1.1
|
||||
masked_url.replace(0, at_at, at_at, '*');
|
||||
} else if (masked_url[password_at+1] == '/') {
|
||||
// no password, something like http://username@192.168.1.1
|
||||
masked_url.replace(password_at+3, at_at-(password_at+3), at_at-(password_at+3), '*');
|
||||
} else {
|
||||
// have username and password, something like http://username:password@192.168.1.1/
|
||||
masked_url.replace(password_at+1, at_at - (password_at+1), at_at - (password_at+1), '*');
|
||||
std::size_t username_at = masked_url.rfind("/", password_at);
|
||||
if (username_at == std::string::npos) {
|
||||
// Something like username:password@192.168.1.1
|
||||
masked_url.replace(0, password_at, password_at, '*');
|
||||
} else {
|
||||
masked_url.replace(username_at+1, password_at-(username_at+1), password_at-(username_at+1), '*');
|
||||
// something like http://username:password@192.168.1.1/
|
||||
}
|
||||
}
|
||||
return masked_url;
|
||||
}
|
||||
|
|
|
@ -127,6 +127,8 @@ template<typename T, std::size_t N>
|
|||
constexpr std::size_t size(const T(&)[N]) noexcept { return N; }
|
||||
}
|
||||
|
||||
std::string mask_authentication(const std::string &url);
|
||||
|
||||
std::string UriDecode(const std::string &encoded);
|
||||
|
||||
class QueryParameter {
|
||||
|
|
|
@ -250,3 +250,31 @@ TEST_CASE("QueryString") {
|
|||
REQUIRE(p2->values()[0] == "value2");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("mask_authentication") {
|
||||
SECTION("no authentication") {
|
||||
std::string url("http://192.168.1.1");
|
||||
std::string result = mask_authentication(url);
|
||||
REQUIRE(url == result);
|
||||
}
|
||||
SECTION("has username no password has scheme") {
|
||||
std::string url("http://username@192.168.1.1");
|
||||
std::string result = mask_authentication(url);
|
||||
REQUIRE(result == "http://********@192.168.1.1");
|
||||
}
|
||||
SECTION("has username no password no scheme") {
|
||||
std::string url("username@192.168.1.1");
|
||||
std::string result = mask_authentication(url);
|
||||
REQUIRE(result == "********@192.168.1.1");
|
||||
}
|
||||
SECTION("has username has password no scheme") {
|
||||
std::string url("username:password@192.168.1.1");
|
||||
std::string result = mask_authentication(url);
|
||||
REQUIRE(result == "********:********@192.168.1.1");
|
||||
}
|
||||
SECTION("has username has password has scheme") {
|
||||
std::string url("http://username:password@192.168.1.1");
|
||||
std::string result = mask_authentication(url);
|
||||
REQUIRE(result == "http://********:********@192.168.1.1");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue