summaryrefslogtreecommitdiff
path: root/vdr-vdrmanager
diff options
context:
space:
mode:
Diffstat (limited to 'vdr-vdrmanager')
-rw-r--r--vdr-vdrmanager/sock.cpp104
-rw-r--r--vdr-vdrmanager/sock.h10
-rw-r--r--vdr-vdrmanager/vdrmanager.cpp12
-rw-r--r--vdr-vdrmanager/vdrmanagerthread.cpp29
-rw-r--r--vdr-vdrmanager/vdrmanagerthread.h5
5 files changed, 142 insertions, 18 deletions
diff --git a/vdr-vdrmanager/sock.cpp b/vdr-vdrmanager/sock.cpp
index 1d17ee2..e2d4d36 100644
--- a/vdr-vdrmanager/sock.cpp
+++ b/vdr-vdrmanager/sock.cpp
@@ -3,6 +3,8 @@
*/
#include <unistd.h>
#include <vdr/plugin.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
#include "sock.h"
#include "helpers.h"
@@ -13,6 +15,9 @@ static int clientno = 0;
*/
cVdrmanagerSocket::cVdrmanagerSocket() {
sock = -1;
+ useSSL = false;
+ password = "";
+ forceCheckSvdrp = false;
}
cVdrmanagerSocket::~cVdrmanagerSocket() {
@@ -50,20 +55,37 @@ const char * cVdrmanagerSocket::GetPassword() {
return password;
}
+void cVdrmanagerSocket::LogSSLError() {
+
+ char * error = ERR_error_string(ERR_get_error(), NULL);
+
+ esyslog("SSL error: %s", error);
+
+}
+
/*
* cVdrmonServerSocket
*/
-cVdrmanagerServerSocket::cVdrmanagerServerSocket() :
- cVdrmanagerSocket() {
+cVdrmanagerServerSocket::cVdrmanagerServerSocket() : cVdrmanagerSocket() {
+
+ sslContext = NULL;
}
cVdrmanagerServerSocket::~cVdrmanagerServerSocket() {
}
-bool cVdrmanagerServerSocket::Create(int port, const char * password, bool forceCheckSvrp) {
- // save password
+bool cVdrmanagerServerSocket::Create(int port, const char * password, bool forceCheckSvrp,
+ bool useSSL, const char * pemFile) {
+
this->password = password;
this->forceCheckSvdrp = forceCheckSvrp;
+ this->useSSL = useSSL;
+
+ // create SSL context
+ if (useSSL && !InitSSL(pemFile)) {
+ return false;
+ }
+
// create socket
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock < 0) {
@@ -117,6 +139,12 @@ cVdrmanagerClientSocket * cVdrmanagerServerSocket::Accept() {
return NULL;
}
+ // Attach client SSL
+ if (!newsocket->InitSSL(sslContext)) {
+ delete newsocket;
+ return NULL;
+ }
+
if (!IsPasswordSet() || forceCheckSvdrp == true) {
bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr);
if (!accepted) {
@@ -127,14 +155,35 @@ cVdrmanagerClientSocket * cVdrmanagerServerSocket::Accept() {
}
dsyslog(
"[vdrmanager] connect from %s, port %hd - %s", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port), accepted ? "accepted" : "DENIED");
+
}
- } else if (errno != EINTR && errno != EAGAIN
- )
+ } else if (errno != EINTR && errno != EAGAIN) {
LOG_ERROR;
+ }
return newsocket;
}
+bool cVdrmanagerServerSocket::InitSSL(const char * pemFile) {
+
+ sslContext = SSL_CTX_new(SSLv3_server_method());
+ if (sslContext == NULL) {
+ LogSSLError();
+ return false;
+ }
+
+ if (SSL_CTX_use_certificate_file(sslContext, pemFile, SSL_FILETYPE_PEM) != 1) {
+ LogSSLError();
+ return false;
+ }
+
+ if (SSL_CTX_use_PrivateKey_file(sslContext, pemFile, SSL_FILETYPE_PEM) != 1) {
+ LogSSLError();
+ return false;
+ }
+
+ return true;
+}
/*
* cVdrmonClientSocket
*/
@@ -147,6 +196,10 @@ cVdrmanagerClientSocket::cVdrmanagerClientSocket(const char * password) {
}
cVdrmanagerClientSocket::~cVdrmanagerClientSocket() {
+
+ if (sslContext) {
+ SSL_free(sslContext);
+ }
}
bool cVdrmanagerClientSocket::IsLineComplete() {
@@ -184,13 +237,24 @@ bool cVdrmanagerClientSocket::GetLine(string& line) {
}
bool cVdrmanagerClientSocket::Read() {
+
if (Disconnected())
return false;
int rc;
bool len = 0;
char buf[2001];
- while ((rc = read(sock, buf, sizeof(buf) - 1)) > 0) {
+
+ for(;;) {
+ if (useSSL) {
+ rc = read(sock, buf, sizeof(buf)-1);
+ } else {
+ rc = SSL_read(sslContext, buf, sizeof(buf)-1);
+ }
+
+ if (rc <= 0)
+ break;
+
buf[rc] = 0;
readbuf += buf;
len += rc;
@@ -229,8 +293,12 @@ bool cVdrmanagerClientSocket::PutLine(string line) {
// data present?
if (writebuf.length() > 0) {
- // write so many bytes as possible
- int rc = write(sock, writebuf.c_str(), writebuf.length());
+ int rc;
+ if (useSSL) {
+ rc = SSL_write(sslContext, writebuf.c_str(), writebuf.length());
+ } else {
+ rc = write(sock, writebuf.c_str(), writebuf.length());
+ }
if (rc < 0 && errno != EAGAIN)
{
LOG_ERROR;
@@ -270,3 +338,21 @@ bool cVdrmanagerClientSocket::IsLoggedIn() {
void cVdrmanagerClientSocket::SetLoggedIn() {
login = true;
}
+
+bool::cVdrmanagerClientSocket::InitSSL(SSL_CTX * sslContext) {
+
+ // create a new SSL context
+ this->sslContext = SSL_new(sslContext);
+ if (this->sslContext == NULL) {
+ LOG_ERROR_STR("Error creating new SSL context");
+ return false;
+ }
+
+ // connect context to the socket
+ if (SSL_set_fd(this->sslContext, sock) != 1) {
+ SSL_free(this->sslContext);
+ this->sslContext = NULL;
+ LOG_ERROR_STR("Error connecting SSL and socket");
+ return false;
+ }
+}
diff --git a/vdr-vdrmanager/sock.h b/vdr-vdrmanager/sock.h
index 0234afc..94da4b2 100644
--- a/vdr-vdrmanager/sock.h
+++ b/vdr-vdrmanager/sock.h
@@ -8,6 +8,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <string>
+#include <openssl/ssl.h>
using namespace std;
@@ -17,6 +18,7 @@ protected:
int sock;
const char * password;
bool forceCheckSvdrp;
+ bool useSSL;
protected:
cVdrmanagerSocket();
bool IsPasswordSet();
@@ -26,6 +28,7 @@ public:
int GetSocket();
bool MakeDontBlock();
const char * GetPassword();
+ void LogSSLError();
};
class cVdrmanagerClientSocket : public cVdrmanagerSocket
@@ -36,6 +39,7 @@ private:
bool disconnected;
int client;
bool login;
+ SSL * sslContext;
public:
cVdrmanagerClientSocket(const char * password);
virtual ~cVdrmanagerClientSocket();
@@ -51,15 +55,19 @@ public:
bool WritePending();
bool IsLoggedIn();
void SetLoggedIn();
+ bool InitSSL(SSL_CTX * sslContext);
};
class cVdrmanagerServerSocket : public cVdrmanagerSocket
{
+private:
+ SSL_CTX * sslContext;
public:
cVdrmanagerServerSocket();
virtual ~cVdrmanagerServerSocket();
- bool Create(int port, const char * password, bool forceCheckSvdrp);
+ bool Create(int port, const char * password, bool forceCheckSvdrp, bool useSSL, const char * pemFile);
cVdrmanagerClientSocket * Accept();
+ bool InitSSL(const char * pemFile);
};
#endif
diff --git a/vdr-vdrmanager/vdrmanager.cpp b/vdr-vdrmanager/vdrmanager.cpp
index 2b81464..96c5f6f 100644
--- a/vdr-vdrmanager/vdrmanager.cpp
+++ b/vdr-vdrmanager/vdrmanager.cpp
@@ -25,6 +25,8 @@ private:
int port;
const char * password;
bool forceCheckSvdrp;
+ bool useSSL;
+ const char * pemFile;
bool forceDelete;
protected:
public:
@@ -58,6 +60,8 @@ cVdrManager::cVdrManager(void) {
password = "";
forceCheckSvdrp = false;
forceDelete = false;
+ useSSL = false;
+ pemFile = NULL;
}
cVdrManager::~cVdrManager() {
@@ -78,8 +82,12 @@ const char * cVdrManager::CommandLineHelp(void) {
bool cVdrManager::ProcessArgs(int argc, char *argv[]) {
int c;
- while ((c = getopt(argc, argv, "p:P:s:f")) != -1)
+ while ((c = getopt(argc, argv, "c:p:P:s:f")) != -1)
switch (c) {
+ case 'c':
+ pemFile = optarg;
+ useSSL = true;
+ break;
case 'p':
port = atoi(optarg);
break;
@@ -115,7 +123,7 @@ bool cVdrManager::Initialize(void) {
// Initialize any background activities the plugin shall perform.
// Start any background activities the plugin shall perform.
- Thread = new cVdrManagerThread(port, password, forceCheckSvdrp);
+ Thread = new cVdrManagerThread(port, password, forceCheckSvdrp, useSSL, pemFile);
return Thread != NULL;
}
diff --git a/vdr-vdrmanager/vdrmanagerthread.cpp b/vdr-vdrmanager/vdrmanagerthread.cpp
index 2a4ca64..977f3d1 100644
--- a/vdr-vdrmanager/vdrmanagerthread.cpp
+++ b/vdr-vdrmanager/vdrmanagerthread.cpp
@@ -4,16 +4,21 @@
#include <string.h>
#include <vdr/plugin.h>
#include <vdr/thread.h>
+#include <openssl/ssl.h>
+
#include "vdrmanagerthread.h"
#include "select.h"
#include "helpers.h"
-cVdrManagerThread::cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp)
+cVdrManagerThread::cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp,
+ bool useSSL, const char * pemFile)
{
select = NULL;
- this -> port = port;
- this -> password = password;
- this -> forceCheckSvdrp = forceCheckSvdrp;
+ this->port = port;
+ this->password = password;
+ this->forceCheckSvdrp = forceCheckSvdrp;
+ this->useSSL = useSSL;
+ this->pemFile = pemFile;
}
cVdrManagerThread::~cVdrManagerThread()
@@ -23,6 +28,11 @@ cVdrManagerThread::~cVdrManagerThread()
void cVdrManagerThread::Action(void)
{
+ // initialize SSL
+ if (useSSL) {
+ InitSSL();
+ }
+
// create listener socket
if (!Init())
return;
@@ -43,7 +53,7 @@ bool cVdrManagerThread::Init()
// create server socket
cVdrmanagerServerSocket * sock = new cVdrmanagerServerSocket();
- if (sock == NULL || !sock->Create(port, password, forceCheckSvdrp))
+ if (sock == NULL || !sock->Create(port, password, forceCheckSvdrp, useSSL, pemFile))
return false;
// register server socket
@@ -61,3 +71,12 @@ void cVdrManagerThread::Cleanup()
void cVdrManagerThread::Shutdown()
{
}
+
+bool cVdrManagerThread::InitSSL() {
+
+ SSL_library_init();
+ SSL_load_error_strings();
+ ERR_load_BIO_strings();
+ ERR_load_SSL_strings();
+
+}
diff --git a/vdr-vdrmanager/vdrmanagerthread.h b/vdr-vdrmanager/vdrmanagerthread.h
index 83f5f31..ac3551b 100644
--- a/vdr-vdrmanager/vdrmanagerthread.h
+++ b/vdr-vdrmanager/vdrmanagerthread.h
@@ -22,14 +22,17 @@ private:
int port;
const char * password;
bool forceCheckSvdrp;
+ bool useSSL;
+ const char * pemFile;
public:
- cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp);
+ cVdrManagerThread(int port, const char * password, bool forceCheckSvdrp, bool useSSL, const char * pemFile);
virtual void Action(void);
void Shutdown();
private:
virtual ~cVdrManagerThread();
void Cleanup();
bool Init();
+ bool InitSSL();
};
#endif