diff options
author | bju <bju@maxi.fritz.box> | 2014-01-22 02:28:34 +0100 |
---|---|---|
committer | bju <bju@maxi.fritz.box> | 2014-01-22 02:28:34 +0100 |
commit | 321bebe669a5aafc2c4ff0e9f59e60de2fa79bac (patch) | |
tree | f8b81b463027a60481f8f41939eaa5a18824ce19 /vdr-vdrmanager/sock.cpp | |
parent | bc2c9e64787d4682bd9f3a3340f8b46497f63bb3 (diff) | |
download | vdr-manager-321bebe669a5aafc2c4ff0e9f59e60de2fa79bac.tar.gz vdr-manager-321bebe669a5aafc2c4ff0e9f59e60de2fa79bac.tar.bz2 |
http://projects.vdr-developer.org/issues/1267:
- some fixes on client side certificate validation
- added SSL server side support to the plugin
Diffstat (limited to 'vdr-vdrmanager/sock.cpp')
-rw-r--r-- | vdr-vdrmanager/sock.cpp | 302 |
1 files changed, 2 insertions, 300 deletions
diff --git a/vdr-vdrmanager/sock.cpp b/vdr-vdrmanager/sock.cpp index 1d1d907..7e7da70 100644 --- a/vdr-vdrmanager/sock.cpp +++ b/vdr-vdrmanager/sock.cpp @@ -3,12 +3,11 @@ */ #include <unistd.h> #include <vdr/plugin.h> +#include <openssl/err.h> #include "sock.h" #include "helpers.h" #include "compressor.h" -static int clientno = 0; - /* * cVdrmonSocket */ @@ -51,304 +50,7 @@ const char * cVdrmanagerSocket::GetPassword() { return password; } -/* - * cVdrmonServerSocket - */ -cVdrmanagerServerSocket::cVdrmanagerServerSocket() : - cVdrmanagerSocket() { -} - -cVdrmanagerServerSocket::~cVdrmanagerServerSocket() { -} - -bool cVdrmanagerServerSocket::Create(int port, const char * password, bool forceCheckSvrp, int compressionMode) { - - this->password = password; - this->forceCheckSvdrp = forceCheckSvrp; - this->compressionMode = compressionMode; - - // create socket - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock < 0) { - LOG_ERROR; - return false; - } - - // allow it to always reuse the same port: - int ReUseAddr = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &ReUseAddr, sizeof(ReUseAddr)); - - // bind to address - struct sockaddr_in name; - name.sin_family = AF_INET; - name.sin_port = htons(port); - name.sin_addr.s_addr = htonl(INADDR_ANY); - if (bind(sock, (struct sockaddr *) &name, sizeof(name)) < 0) { - LOG_ERROR; - Close(); - return false; - } - - // make it non-blocking: - if (!MakeDontBlock()) { - Close(); - return false; - } - - // listen to the socket: - if (listen(sock, 100) < 0) { - LOG_ERROR; - Close(); - return false; - } - - return true; -} - -cVdrmanagerClientSocket * cVdrmanagerServerSocket::Accept() { - cVdrmanagerClientSocket * newsocket = NULL; - - // accept the connection - struct sockaddr_in clientname; - uint size = sizeof(clientname); - int newsock = accept(sock, (struct sockaddr *) &clientname, &size); - if (newsock > 0) { - // create client socket - newsocket = new cVdrmanagerClientSocket(password, compressionMode); - if (!newsocket->Attach(newsock)) { - delete newsocket; - return NULL; - } - - if (!IsPasswordSet() || forceCheckSvdrp == true) { - bool accepted = SVDRPhosts.Acceptable(clientname.sin_addr.s_addr); - if (!accepted) { - newsocket->PutLine(string("NACC Access denied.\n")); - newsocket->Flush(); - delete newsocket; - newsocket = NULL; - } - 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 - ) - LOG_ERROR; - - return newsocket; -} - -/* - * cVdrmonClientSocket - */ -cVdrmanagerClientSocket::cVdrmanagerClientSocket(const char * password, int compressionMode) { - readbuf = ""; - writebuf = ""; - sendbuf = NULL; - sendsize = 0; - sendoffset = 0; - disconnected = false; - initDisconnect = false; - client = ++clientno; - this->password = password; - this->compressionMode = compressionMode; - login = false; - compression = false; - initCompression = false; -} - -cVdrmanagerClientSocket::~cVdrmanagerClientSocket() { -} - -bool cVdrmanagerClientSocket::IsLineComplete() { - // check a for complete line - string::size_type pos = readbuf.find("\r", 0); - if (pos == string::npos) - pos = readbuf.find("\n"); - return pos != string::npos; -} - bool cVdrmanagerSocket::IsPasswordSet(){ - return strcmp(password, ""); -} - -bool cVdrmanagerClientSocket::GetLine(string& line) { - // check the line - string::size_type pos = readbuf.find("\r", 0); - if (pos == string::npos) - pos = readbuf.find("\n", 0); - if (pos == string::npos) - return false; - - // extract the line ... - line = readbuf.substr(0, pos); - - // handle \r\n - if (readbuf[pos] == '\r' && readbuf.length() > pos - && readbuf[pos + 1] == '\n') - pos++; - - // ... and move the remainder - readbuf = readbuf.substr(pos + 1); - - return true; + return strcmp(password, ""); } -bool cVdrmanagerClientSocket::Read() { - if (Disconnected()) - return false; - - int rc; - bool len = 0; - char buf[2001]; - while ((rc = read(sock, buf, sizeof(buf) - 1)) > 0) { - buf[rc] = 0; - readbuf += buf; - len += rc; - } - - if (rc < 0 && errno != EAGAIN) - { - LOG_ERROR; - return false; - } else if (rc == 0) { - disconnected = true; - } - - return len > 0; -} - -bool cVdrmanagerClientSocket::Disconnected() { - return disconnected; -} - -void cVdrmanagerClientSocket::Disconnect() { - initDisconnect = true; -} - -bool cVdrmanagerClientSocket::PutLine(string line) { - - // fill writebuf - if (line.length() > 0) { - writebuf += line; - return true; - } - - // initialize sendbuf if needed - if (sendbuf == NULL) { - if (!compression) { - sendbuf = (char *)malloc(writebuf.length()+1); - strcpy(sendbuf, writebuf.c_str()); - sendsize = writebuf.length(); - } else { - Compress(); - } - sendoffset = 0; - writebuf.clear(); - } - - // send data - if (sendsize > 0) { - - // write so many bytes as possible - int rc = write(sock, sendbuf + sendoffset, sendsize); - if (rc < 0 && errno != EAGAIN) - { - LOG_ERROR; - - if (sendbuf != NULL) { - free(sendbuf); - sendbuf = NULL; - } - - return false; - } - sendsize -= rc; - sendoffset += rc; - } - - if (sendsize == 0) { - - if (sendbuf != NULL) { - free(sendbuf); - sendbuf = NULL; - } - - if (initCompression) { - isyslog("Compression is activated now"); - initCompression = false; - compression = true; - } - - if (initDisconnect) { - initDisconnect = false; - disconnected = true; - } - } - - return true; -} - -bool cVdrmanagerClientSocket::Flush() { - return PutLine(""); -} - -bool cVdrmanagerClientSocket::Attach(int fd) { - sock = fd; - return MakeDontBlock(); -} - -int cVdrmanagerClientSocket::GetClientId() { - return client; -} - -bool cVdrmanagerClientSocket::WritePending() { - return sendsize > 0; -} - -bool cVdrmanagerClientSocket::IsLoggedIn() { - return login || !password || !*password; -} - -void cVdrmanagerClientSocket::SetLoggedIn() { - login = true; -} - -void cVdrmanagerClientSocket::ActivateCompression() { - - string mode = "NONE"; - switch (compressionMode) { - case COMPRESSION_GZIP: - mode = "GZIP"; - initCompression = true; - break; - case COMPRESSION_ZLIB: - mode = "ZLIB"; - initCompression = true; - break; - default: - mode = "NONE"; - break; - } - - PutLine("!OK " + mode + "\r\n"); -} - -void cVdrmanagerClientSocket::Compress() { - cCompressor compressor = cCompressor(); - - switch (compressionMode) { - case COMPRESSION_GZIP: - compressor.CompressGzip(writebuf); - break; - case COMPRESSION_ZLIB: - compressor.CompressZlib(writebuf); - break; - } - - sendbuf = compressor.GetData(); - sendsize = compressor.getDataSize(); - - double ratio = 1.0 * writebuf.length() / sendsize; - dsyslog("[vdrmanager] Compression stats: raw %ld, compressed %ld, ratio %f:1", writebuf.length(), sendsize, ratio); -} |