comparison 3rdparty/vmime/src/vmime/security/sasl/SASLSocket.cpp @ 0:a4671277546c tip

created the repository for the thymian project
author ferencd
date Tue, 17 Aug 2021 11:19:54 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:a4671277546c
1 //
2 // VMime library (http://www.vmime.org)
3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 3 of
8 // the License, or (at your option) any later version.
9 //
10 // This program 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 GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // Linking this library statically or dynamically with other modules is making
20 // a combined work based on this library. Thus, the terms and conditions of
21 // the GNU General Public License cover the whole combination.
22 //
23
24 #include "vmime/config.hpp"
25
26
27 #if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
28
29
30 #include "vmime/security/sasl/SASLSocket.hpp"
31 #include "vmime/security/sasl/SASLSession.hpp"
32
33 #include "vmime/utility/stringUtils.hpp"
34
35 #include "vmime/exception.hpp"
36
37 #include <algorithm>
38 #include <cstring>
39
40 #include <gsasl.h>
41
42
43 namespace vmime {
44 namespace security {
45 namespace sasl {
46
47
48
49 SASLSocket::SASLSocket(shared_ptr <SASLSession> sess, shared_ptr <net::socket> wrapped)
50 : m_session(sess), m_wrapped(wrapped),
51 m_pendingBuffer(0), m_pendingPos(0), m_pendingLen(0)
52 {
53 }
54
55
56 SASLSocket::~SASLSocket()
57 {
58 if (m_pendingBuffer)
59 delete [] m_pendingBuffer;
60 }
61
62
63 void SASLSocket::connect(const string& address, const port_t port)
64 {
65 m_wrapped->connect(address, port);
66 }
67
68
69 void SASLSocket::disconnect()
70 {
71 m_wrapped->disconnect();
72 }
73
74
75 bool SASLSocket::isConnected() const
76 {
77 return m_wrapped->isConnected();
78 }
79
80
81 size_t SASLSocket::getBlockSize() const
82 {
83 return m_wrapped->getBlockSize();
84 }
85
86
87 const string SASLSocket::getPeerName() const
88 {
89 return m_wrapped->getPeerName();
90 }
91
92
93 const string SASLSocket::getPeerAddress() const
94 {
95 return m_wrapped->getPeerAddress();
96 }
97
98
99 shared_ptr <net::timeoutHandler> SASLSocket::getTimeoutHandler()
100 {
101 return m_wrapped->getTimeoutHandler();
102 }
103
104
105 void SASLSocket::setTracer(shared_ptr <net::tracer> tracer)
106 {
107 m_wrapped->setTracer(tracer);
108 }
109
110
111 shared_ptr <net::tracer> SASLSocket::getTracer()
112 {
113 return m_wrapped->getTracer();
114 }
115
116
117 bool SASLSocket::waitForRead(const int msecs)
118 {
119 return m_wrapped->waitForRead(msecs);
120 }
121
122
123 bool SASLSocket::waitForWrite(const int msecs)
124 {
125 return m_wrapped->waitForWrite(msecs);
126 }
127
128
129 void SASLSocket::receive(string& buffer)
130 {
131 const size_t n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer));
132
133 buffer = utility::stringUtils::makeStringFromBytes(m_recvBuffer, n);
134 }
135
136
137 size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count)
138 {
139 if (m_pendingLen != 0)
140 {
141 const size_t copyLen =
142 (count >= m_pendingLen ? m_pendingLen : count);
143
144 std::copy(m_pendingBuffer + m_pendingPos,
145 m_pendingBuffer + m_pendingPos + copyLen,
146 buffer);
147
148 m_pendingLen -= copyLen;
149 m_pendingPos += copyLen;
150
151 if (m_pendingLen == 0)
152 {
153 delete [] m_pendingBuffer;
154
155 m_pendingBuffer = 0;
156 m_pendingPos = 0;
157 m_pendingLen = 0;
158 }
159
160 return copyLen;
161 }
162
163 const size_t n = m_wrapped->receiveRaw(buffer, count);
164
165 byte_t* output = 0;
166 size_t outputLen = 0;
167
168 m_session->getMechanism()->decode
169 (m_session, buffer, n, &output, &outputLen);
170
171 // If we can not copy all decoded data into the output buffer, put
172 // remaining data into a pending buffer for next calls to receive()
173 if (outputLen > count)
174 {
175 std::copy(output, output + count, buffer);
176
177 m_pendingBuffer = output;
178 m_pendingLen = outputLen;
179 m_pendingPos = count;
180
181 return count;
182 }
183 else
184 {
185 std::copy(output, output + outputLen, buffer);
186
187 delete [] output;
188
189 return outputLen;
190 }
191 }
192
193
194 void SASLSocket::send(const string& buffer)
195 {
196 sendRaw(reinterpret_cast <const byte_t*>(buffer.data()), buffer.length());
197 }
198
199
200 void SASLSocket::send(const char* str)
201 {
202 sendRaw(reinterpret_cast <const byte_t*>(str), strlen(str));
203 }
204
205
206 void SASLSocket::sendRaw(const byte_t* buffer, const size_t count)
207 {
208 byte_t* output = 0;
209 size_t outputLen = 0;
210
211 m_session->getMechanism()->encode
212 (m_session, buffer, count, &output, &outputLen);
213
214 try
215 {
216 m_wrapped->sendRaw(output, outputLen);
217 }
218 catch (...)
219 {
220 delete [] output;
221 throw;
222 }
223
224 delete [] output;
225 }
226
227
228 size_t SASLSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count)
229 {
230 byte_t* output = 0;
231 size_t outputLen = 0;
232
233 m_session->getMechanism()->encode
234 (m_session, buffer, count, &output, &outputLen);
235
236 size_t bytesSent = 0;
237
238 try
239 {
240 bytesSent = m_wrapped->sendRawNonBlocking(output, outputLen);
241 }
242 catch (...)
243 {
244 delete [] output;
245 throw;
246 }
247
248 delete [] output;
249
250 return bytesSent;
251 }
252
253
254 unsigned int SASLSocket::getStatus() const
255 {
256 return m_wrapped->getStatus();
257 }
258
259
260 } // sasl
261 } // security
262 } // vmime
263
264
265 #endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
266