git-svn-id: svn://db.shs.com.ru/pip@315 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2017-02-28 15:42:28 +00:00
parent 749a7f2f48
commit 1dc6f27c9e
3 changed files with 218 additions and 16 deletions

View File

@@ -28,7 +28,8 @@ const char hash_def_key[] = "_picrypt_";
PICrypt::PICrypt() { PICrypt::PICrypt() {
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
sodium_init(); int ret;
ret = sodium_init();
nonce_.resize(crypto_secretbox_NONCEBYTES); nonce_.resize(crypto_secretbox_NONCEBYTES);
key_.resize(crypto_secretbox_KEYBYTES); key_.resize(crypto_secretbox_KEYBYTES);
randombytes_buf(key_.data(), key_.size()); randombytes_buf(key_.data(), key_.size());
@@ -72,22 +73,23 @@ PIByteArray PICrypt::crypt(const PIByteArray & data) {
PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) { PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) {
PIByteArray ret; PIByteArray retba;
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
if (key.size() != crypto_secretbox_KEYBYTES) if (key.size() != crypto_secretbox_KEYBYTES)
key.resize(crypto_secretbox_KEYBYTES, ' '); key.resize(crypto_secretbox_KEYBYTES, ' ');
//return PIByteArray(); //return PIByteArray();
sodium_init(); int ret;
ret = sodium_init();
PIByteArray n; PIByteArray n;
ret.resize(data.size() + crypto_secretbox_MACBYTES); retba.resize(data.size() + crypto_secretbox_MACBYTES);
n.resize(crypto_secretbox_NONCEBYTES); n.resize(crypto_secretbox_NONCEBYTES);
randombytes_buf(n.data(), n.size()); randombytes_buf(n.data(), n.size());
crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data()); crypto_secretbox_easy(retba.data(), data.data(), data.size(), n.data(), key.data());
ret.append(n); retba.append(n);
#else #else
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=1"; piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=1";
#endif #endif
return ret; return retba;
} }
@@ -112,7 +114,7 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool *ok) {
PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool *ok) { PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool *ok) {
PIByteArray ret; PIByteArray retba;
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
if (key.size() != crypto_secretbox_KEYBYTES) if (key.size() != crypto_secretbox_KEYBYTES)
key.resize(crypto_secretbox_KEYBYTES, ' '); key.resize(crypto_secretbox_KEYBYTES, ' ');
@@ -123,12 +125,13 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bo
if (ok) *ok = false; if (ok) *ok = false;
return PIByteArray(); return PIByteArray();
} }
sodium_init(); int ret;
ret = sodium_init();
PIByteArray n; PIByteArray n;
n.resize(crypto_secretbox_NONCEBYTES); n.resize(crypto_secretbox_NONCEBYTES);
ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); retba.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES);
memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size());
if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) { if (crypto_secretbox_open_easy(retba.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) {
if (ok) *ok = false; if (ok) *ok = false;
// piCout << "[PICrypt]" << "bad key_"; // piCout << "[PICrypt]" << "bad key_";
return PIByteArray(); return PIByteArray();
@@ -137,14 +140,15 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bo
piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=";
#endif #endif
if (ok) *ok = true; if (ok) *ok = true;
return ret; return retba;
} }
PIByteArray PICrypt::hash(const PIString & secret) { PIByteArray PICrypt::hash(const PIString & secret) {
PIByteArray hash; PIByteArray hash;
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
sodium_init(); int ret;
ret = sodium_init();
hash.resize(crypto_generichash_BYTES); hash.resize(crypto_generichash_BYTES);
PIByteArray s(secret.data(), secret.size()); PIByteArray s(secret.data(), secret.size());
crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar*)hash_def_key, sizeof(hash_def_key) - 1); crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar*)hash_def_key, sizeof(hash_def_key) - 1);
@@ -159,7 +163,8 @@ ullong PICrypt::shorthash(const PIString& s, PIByteArray key) {
ullong hash = 0; ullong hash = 0;
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
if (crypto_shorthash_BYTES != sizeof(hash)) piCout << "[PICrypt]" << "internal error: bad hash size"; if (crypto_shorthash_BYTES != sizeof(hash)) piCout << "[PICrypt]" << "internal error: bad hash size";
sodium_init(); int ret;
ret = sodium_init();
if (key.size() != crypto_shorthash_KEYBYTES) { if (key.size() != crypto_shorthash_KEYBYTES) {
piCout << "[PICrypt]" << "invalid key size" << key.size() << ", shoud be" << crypto_shorthash_KEYBYTES << ", filled zeros"; piCout << "[PICrypt]" << "invalid key size" << key.size() << ", shoud be" << crypto_shorthash_KEYBYTES << ", filled zeros";
key.resize(crypto_shorthash_KEYBYTES, 0); key.resize(crypto_shorthash_KEYBYTES, 0);
@@ -176,7 +181,8 @@ ullong PICrypt::shorthash(const PIString& s, PIByteArray key) {
PIByteArray PICrypt::generateKey() { PIByteArray PICrypt::generateKey() {
PIByteArray hash; PIByteArray hash;
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
sodium_init(); int ret;
ret = sodium_init();
hash.resize(crypto_secretbox_KEYBYTES); hash.resize(crypto_secretbox_KEYBYTES);
randombytes_buf(hash.data(), hash.size()); randombytes_buf(hash.data(), hash.size());
#else #else

View File

@@ -4,7 +4,7 @@
#define PIP_VERSION_MAJOR 0 #define PIP_VERSION_MAJOR 0
#define PIP_VERSION_MINOR 7 #define PIP_VERSION_MINOR 7
#define PIP_VERSION_REVISION 1 #define PIP_VERSION_REVISION 2
#define PIP_VERSION_SUFFIX "" #define PIP_VERSION_SUFFIX ""
#endif // PIVERSION_H #endif // PIVERSION_H

196
src/thread/pigrabberbase.h Normal file
View File

@@ -0,0 +1,196 @@
/*! \file pigrabberbase.h
* \brief Abstract class for create grabbers
*/
/*
PIP - Platform Independent Primitives
Abstract class for create grabbers
Copyright (C) 2017 Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIGRABBERBASE_H
#define PIGRABBERBASE_H
#include "pithread.h"
#include "pidiagnostics.h"
template<typename T = PIByteArray>
class PIGrabberBase: public PIThread
{
PIOBJECT_SUBCLASS(PIGrabberBase, PIThread)
public:
PIGrabberBase() {
is_opened = false;
is_recording = false;
}
virtual ~PIGrabberBase() {
stopGrabber(false);
}
virtual bool isOpened() const {return is_opened;}
virtual bool isRecording() const {return is_recording;}
virtual void startRecord(const PIString & filename) {
if (!isOpened()) return;
if (isRecording()) return;
rec_mutex.lock();
startRecordInternal(filename);
is_recording = true;
rec_mutex.unlock();
}
virtual void stopRecord() {
if (!isOpened()) return;
if (!isRecording()) return;
rec_mutex.lock();
is_recording = false;
stopRecordInternal();
rec_mutex.unlock();
}
T last() const {
T ret;
last_mutex.lock();
ret = last_;
last_mutex.unlock();
return ret;
}
bool isEmpty() {
bool ret;
que_mutex.lock();
ret = que.isEmpty();
que_mutex.unlock();
return ret;
}
int queSize() {
int ret;
que_mutex.lock();
ret = que.size();
que_mutex.unlock();
return ret;
}
T dequeue() {
T ret;
// piCoutObj << "start";
que_mutex.lock();
if (!que.isEmpty()) {
// piCoutObj << "dequeue";
ret = que.dequeue();
}
// piCoutObj << "end";
que_mutex.unlock();
return ret;
}
void stopGrabber(bool wait_forever = true) {
if (isRunning()) {
stop();
if (wait_forever) waitForFinish();
else {
if (!waitForFinish(100)) terminate();
stopRecord();
close();
}
}
}
bool open() {
bool ret = openInternal();
if (!is_opened && ret)
opened();
is_opened = ret;
return ret;
}
void close() {
bool em = is_opened;
closeInternal();
last_ = T();
if (em)
closed();
is_opened = false;
}
const PIDiagnostics & diag() const {return diag_;}
void clear() {
que_mutex.lock();
que.clear();
que_mutex.unlock();
}
void restart() {
clear();
close();
}
EVENT(dataReady)
EVENT(opened)
EVENT(closed)
protected:
virtual void init() {}
virtual bool openInternal() = 0;
virtual void closeInternal() = 0;
virtual int get(T & val) = 0;
virtual void record(const T & val) {}
virtual void startRecordInternal(const PIString & filename) {}
virtual void stopRecordInternal() {}
bool is_opened, is_recording;
mutable PIMutex rec_mutex;
private:
void begin() {
init();
}
void run() {
if (!isOpened()) {
open();
diag_.reset();
if (!is_opened)
piMSleep(200);
}
if (isOpened()) {
T c;
int ret = get(c);
if (ret < 0) {
close();
return;
}
if (ret > 0) {
piMSleep(1);
return;
}
diag_.received(1);
que_mutex.lock();
que.enqueue(c);
que_mutex.unlock();
if (isRecording()) {
rec_mutex.lock();
record(c);
rec_mutex.unlock();
diag_.sended(1);
}
last_mutex.lock();
last_ = c;
last_mutex.unlock();
dataReady();
}
}
void end() {
stopRecord();
close();
}
T last_;
PIQueue<T> que;
PIDiagnostics diag_;
mutable PIMutex que_mutex, last_mutex;
};
#endif // PIGRABBERBASE_H