blob: 3f2cb70607e90349d17eb1e1fb5017c3b7188d5e [file] [log] [blame]
Alexandre Lisionddd731e2014-01-31 11:50:08 -05001// Copyright (C) 2010 David Sugar, Tycho Softworks.
2//
3// This file is part of GNU uCommon C++.
4//
5// GNU uCommon C++ is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published
7// by the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GNU uCommon C++ is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17
18#include "local.h"
19
20SSLBuffer::SSLBuffer(const TCPServer *tcp, secure::server_t scontext, size_t size) :
21TCPBuffer(tcp, size)
22{
23 ssl = context::session((context *)scontext);
24 bio = NULL;
25 server = true;
26
27 if(!is_open() || !ssl)
28 return;
29
30 gnutls_transport_set_ptr((SSL)ssl, reinterpret_cast<gnutls_transport_ptr_t>( so));
31 int result = gnutls_handshake((SSL)ssl);
32
33 if(result >= 0)
34 bio = ssl;
35
36}
37
38SSLBuffer::SSLBuffer(secure::client_t scontext) :
39TCPBuffer()
40{
41 ssl = context::session((context *)scontext);
42 bio = NULL;
43 server = false;
44}
45
46SSLBuffer::~SSLBuffer()
47{
48 release();
49}
50
51bool SSLBuffer::_pending(void)
52{
53 return TCPBuffer::_pending();
54}
55
56void SSLBuffer::open(const char *host, const char *service, size_t size)
57{
58 if(server) {
59 ioerr = EBADF;
60 return;
61 }
62
63 close();
64
65 TCPBuffer::open(host, service, size);
66
67 if(!is_open() || !ssl)
68 return;
69
70 gnutls_transport_set_ptr((SSL)ssl, reinterpret_cast<gnutls_transport_ptr_t>(so));
71 int result = gnutls_handshake((SSL)ssl);
72
73 if(result >= 0)
74 bio = ssl;
75}
76
77void SSLBuffer::close(void)
78{
79 if(server) {
80 ioerr = EBADF;
81 return;
82 }
83
84 if(bio)
85 gnutls_bye((SSL)ssl, GNUTLS_SHUT_RDWR);
86 bio = NULL;
87 TCPBuffer::close();
88}
89
90void SSLBuffer::release(void)
91{
92 server = false;
93 close();
94 if(ssl) {
95 gnutls_deinit((SSL)ssl);
96 ssl = NULL;
97 }
98}
99
100bool SSLBuffer::_flush(void)
101{
102 return TCPBuffer::_flush();
103}
104
105size_t SSLBuffer::_push(const char *address, size_t size)
106{
107 if(!bio)
108 return TCPBuffer::_push(address, size);
109
110 int result = gnutls_record_send((SSL)ssl, address, size);
111 if(result < 0) {
112 result = 0;
113 ioerr = EIO;
114 }
115 return (size_t)result;
116}
117
118size_t SSLBuffer::_pull(char *address, size_t size)
119{
120 if(!bio)
121 return TCPBuffer::_pull(address, size);
122
123 int result = gnutls_record_recv((SSL)ssl, address, size);
124 if(result < 0) {
125 result = 0;
126 ioerr = EIO;
127 }
128 return (size_t)result;
129}
130