merge with master
[framework/osp/net.git] / src / sockets / FNetSock_SecureSocketManagedNetConnectionEventListenerImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FNetSock_SecureSocketManagedNetConnectionEventListenerImpl.cpp
20  * @brief               This is the implementation file for _SecureSocketManagedNetConnectionEventListener class.
21  * @version     2.1
22  *
23  * This file contains the implementation of _SecureSocketManagedNetConnectionEventListener class.
24  */
25
26 #include <unistd.h>
27 #include <errno.h>
28 #include <FBaseString.h>
29 #include <FBaseSysLog.h>
30 #include <FNetNetConnectionInfo.h>
31 #include <FBase_StringConverter.h>
32 #include "FNet_NetConnectionInfoImpl.h"
33 #include "FNetSock_SecureSocketEventArg.h"
34 #include "FNetSock_SecureSocketManagedNetConnectionEventListenerImpl.h"
35
36 using namespace Tizen::Base;
37 using namespace Tizen::Base::Runtime;
38
39 namespace Tizen { namespace Net { namespace Sockets
40 {
41
42 static const long _VERIFY_DEPTH = 9; // certificate verification depth 9
43
44 _SecureSocketManagedNetConnectionEventListener::_SecureSocketManagedNetConnectionEventListener(void)
45         : __isStarted(false)
46         , __isStopped(false)
47         , __pNetConnectionInfo(null)
48         , __socketFd(INVALID_HANDLE)
49         , __backLog(-1)
50         , __flag(FLAG_NONE)
51         , __pSecureSocketEvent(null)
52         , __pThread(null)
53         , __pSecureSocketImpl(null)
54         , __pSslKey(null)
55 {
56         memset(&__remoteAddr, 0, sizeof(__remoteAddr));
57         __remoteAddr.sin_family = AF_INET;
58         __remoteAddr.sin_addr.s_addr = htonl(INADDR_ANY);
59         __remoteAddr.sin_port = htons(0);
60 }
61
62 _SecureSocketManagedNetConnectionEventListener::~_SecureSocketManagedNetConnectionEventListener(void)
63 {
64         __pSecureSocketEvent = null;
65         __flag = FLAG_NONE;
66         __backLog = -1;
67         __socketFd = INVALID_HANDLE;
68         __pNetConnectionInfo = null;
69         __pSecureSocketImpl = null;
70         __isStarted = false;
71         __isStopped = false;
72
73         if (__pThread)
74         {
75                 delete __pThread;
76                 __pThread = null;
77         }
78 }
79
80 void
81 _SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionBearerChanged(ManagedNetConnection& managedNetConnection)
82 {
83         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionBearerChanged - Enter");
84
85         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionBearerChanged - End");
86 }
87
88 void
89 _SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStarted(ManagedNetConnection& managedNetConnection)
90 {
91         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionStarted - Enter");
92
93         __isStarted = true;
94         __isStopped = false;
95
96         const _NetConnectionInfoImpl* pNCInfoImpl = null;
97         String deviceName;
98         char* pDeviceName = null;
99         int err = 0;
100
101         result r = E_SUCCESS;
102
103         __pNetConnectionInfo = managedNetConnection.GetNetConnectionInfo();
104         if (__pNetConnectionInfo == null)
105         {
106                 SysLogException(NID_NET_SOCK, E_INVALID_CONNECTION, "[E_INVALID_CONNECTION] NetConnectionInfo is null. Failed to ManagedNetConnection GetNetConnectionInfo.");
107         }
108         else
109         {
110                 pNCInfoImpl = _NetConnectionInfoImpl::GetInstance(*__pNetConnectionInfo);
111
112                 deviceName = pNCInfoImpl->GetDeviceName();
113
114                 if (deviceName.IsEmpty())
115                 {
116                         SysLog(NID_NET_SOCK, "DeviceName is empty string. - Emulator Case");
117                 }
118                 else
119                 {
120                         SysLog(NID_NET_SOCK, "DeviceName is not empty string.[Device name : %ls] - Target Case", deviceName.GetPointer());
121
122                         pDeviceName = _StringConverter::CopyToCharArrayN(deviceName);
123                         SysTryCatch(NID_NET_SOCK, pDeviceName != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
124
125                         err = setsockopt(__socketFd, SOL_SOCKET, SO_BINDTODEVICE, pDeviceName, strlen(pDeviceName) + 1);
126                         delete[] pDeviceName;
127                         if (err < 0)
128                         {
129                                 ConvertErrorToResult(errno);
130
131                                 SysLogException(NID_NET_SOCK, E_INVALID_CONNECTION, "[E_INVALID_CONNECTION] Failed to bind device name.");
132                         }
133                 }
134         }
135
136         switch (__flag)
137         {
138         case FLAG_CONSTRUCT:
139                 SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStarted - Construct");
140                 break;
141
142         case FLAG_CONNECT:
143                 SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStarted - Connect");
144                 err = connect(__socketFd, (struct sockaddr*) &__remoteAddr, sizeof(__remoteAddr));
145
146                 if (err < 0)
147                 {
148                         r = ConvertErrorToResult(errno);
149                         SysTryCatch(NID_NET_SOCK,r == E_WOULD_BLOCK, , r, "[%s] Failed to connect the socket.", GetErrorMessage(r));
150                 }
151
152                 r = SslConnect();
153                 SysTryCatch(NID_NET_SOCK, r == E_SUCCESS, , r, "[%s] Failed to sslconnect the socket.",GetErrorMessage(r));
154                 break;
155
156         case FLAG_LISTEN:
157                 SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStarted - Listen");
158                 err = listen(__socketFd, __backLog);
159                 break;
160         default:
161                 break;
162         }
163
164         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionStarted - End");
165
166 CATCH:
167         return;
168 }
169
170 void
171 _SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStopped(ManagedNetConnection& managedNetConnection, NetConnectionStoppedReason reason)
172 {
173         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionStopped - Enter");
174
175         __isStarted = false;
176         __isStopped = true;
177
178         int sockFd = -1;
179
180         _SecureSocketEventArg* pSecureSocketEventArg = null;
181
182         switch (__flag)
183         {
184         case FLAG_CONSTRUCT:
185                 SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStopped - Construct");
186                 break;
187
188         case FLAG_CONNECT:
189                 SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStopped - Connect");
190                 break;
191         case FLAG_LISTEN:
192                 SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionStopped - Listen");
193                 break;
194
195         default:
196                 break;
197         }
198
199         pSecureSocketEventArg = new (std::nothrow) _SecureSocketEventArg(__pSecureSocketImpl->__socketFd, NET_SOCKET_EVENT_CLOSE);
200         pSecureSocketEventArg->SetError(E_NETWORK_UNAVAILABLE);
201         __pSecureSocketEvent->Fire(*pSecureSocketEventArg);
202
203         if (__pSecureSocketImpl->__pGlibSocketInfo != null)
204         {
205                 delete __pSecureSocketImpl->__pGlibSocketInfo;
206                 __pSecureSocketImpl->__pGlibSocketInfo = null;
207         }
208
209         if (__pSecureSocketImpl->__socketFd > INVALID_HANDLE)
210         {
211                 sockFd = __pSecureSocketImpl->__socketFd;
212                 close(__pSecureSocketImpl->__socketFd);
213                 __pSecureSocketImpl->__socketFd = INVALID_HANDLE;
214                 SysLog(NID_NET_HTTP, "### SocketFd(%d) was closed..", sockFd);
215         }
216
217         SysLog(NID_NET_SOCK, "_SocketManagedNetConnectionEventListener - OnManagedNetConnectionStopped - End");
218 }
219
220 void
221 _SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionSuspended(ManagedNetConnection& managedNetConnection)
222 {
223         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionSuspended - Enter");
224
225         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionSuspended - End");
226 }
227
228 void
229 _SecureSocketManagedNetConnectionEventListener::OnManagedNetConnectionResumed(ManagedNetConnection& managedNetConnection)
230 {
231         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionResumed - Enter");
232
233         SysLog(NID_NET_SOCK, "_SecureSocketManagedNetConnectionEventListener - OnManagedNetConnectionResumed - End");
234 }
235
236 void
237 _SecureSocketManagedNetConnectionEventListener::SetConstructParams(_SecureSocketEvent* pSocketEventSet, HSocket socketFdSet, _SocketMethodFlag flagSet, _SecureSocketImpl* pSecuresSocketImplSet)
238 {
239         __pSecureSocketEvent = pSocketEventSet;
240         __socketFd = socketFdSet;
241         __flag = flagSet;
242         __pSecureSocketImpl = pSecuresSocketImplSet;
243 }
244
245 void
246 _SecureSocketManagedNetConnectionEventListener::SetConnectParams(HSocket socketFdSet, sockaddr_in remoteAddrSet, _SocketMethodFlag flagSet,
247                 _SecureSocketImpl* pSecureSocketImplSet)
248 {
249         __socketFd = socketFdSet;
250         __remoteAddr = remoteAddrSet;
251         __flag = flagSet;
252         __pSecureSocketImpl = pSecureSocketImplSet;
253 }
254
255 void
256 _SecureSocketManagedNetConnectionEventListener::SetListenParams(HSocket __socketFdSet, int backLogSet, _SocketMethodFlag flagSet)
257 {
258         __socketFd = __socketFdSet;
259         __backLog = backLogSet;
260         __flag = flagSet;
261 }
262
263 void
264 _SecureSocketManagedNetConnectionEventListener::SetStartedFlag(bool isStartSet)
265 {
266         __isStarted = isStartSet;
267 }
268
269 bool
270 _SecureSocketManagedNetConnectionEventListener::GetStartedFlag()
271 {
272         return __isStarted;
273 }
274
275 result
276 _SecureSocketManagedNetConnectionEventListener::SslConnect()
277 {
278         result r = E_SUCCESS;
279
280         int sslError = 0;
281         int sslIndex = 0;
282
283         __pSecureSocketImpl->__pSsl = SSL_new(__pSecureSocketImpl->__pSslCtx);
284         SysTryCatch(NID_NET_SOCK, __pSecureSocketImpl->__pSsl != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create the SSL Object.");
285
286         SSL_set_fd(__pSecureSocketImpl->__pSsl, __socketFd);
287
288         SSL_set_options(__pSecureSocketImpl->__pSsl, SSL_OP_ALL);
289
290         if (__pSecureSocketImpl->__isNonblock == true)
291         {
292                 SSL_CTX_set_client_cert_cb(__pSecureSocketImpl->__pSslCtx, (int (*)(SSL*, X509**, EVP_PKEY**)) _SecureSocketImpl::OnClientCertCallback);
293
294                 SSL_set_mode(__pSecureSocketImpl->__pSsl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
295
296                 sslIndex = SSL_get_ex_new_index(0, (char*) "_SecureSocketImpl index", null, null, null);
297
298                 SSL_set_ex_data(__pSecureSocketImpl->__pSsl, sslIndex, __pSecureSocketImpl);
299
300                 __pSslKey = new Integer((int) __pSecureSocketImpl->__pSsl);
301
302                 pthread_mutex_lock(&_SecureSocketImpl::__mapMutex);
303                 _Singleton::GetSslMap()->Add(*(__pSslKey), *(new Integer((int) sslIndex)));
304                 pthread_mutex_unlock(&_SecureSocketImpl::__mapMutex);
305
306                 SSL_set_verify(__pSecureSocketImpl->__pSsl, SSL_VERIFY_PEER, (int (*)(int, X509_STORE_CTX*)) _SecureSocketImpl::OnVerifyPeerCallback);
307                 // verify certification depth is set to VERIFY_DEPTH.
308                 // Allows level 0: peer certificates.
309                 //        level 1: CA certificates.
310                 //        level 2: higher level CA certificates.
311                 //        and so on.
312                 __pSecureSocketImpl->__sslDepth = _VERIFY_DEPTH;
313                 SSL_set_verify_depth(__pSecureSocketImpl->__pSsl, __pSecureSocketImpl->__sslDepth);
314
315                 // Create thread
316                 __pThread = new (std::nothrow) Thread();
317                 SysTryCatch(NID_NET_SOCK, __pThread != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
318
319                 r = __pThread->Construct(*__pSecureSocketImpl);
320                 SysTryCatch(NID_NET_SOCK, r == E_SUCCESS, , r, GetErrorMessage(r));
321
322                 // Start thread
323                 r = __pThread->Start();
324                 SysTryCatch(NID_NET_SOCK, r == E_SUCCESS, , r, GetErrorMessage(r));
325         }
326         else
327         {
328                 if (__pSecureSocketImpl->__sslVerify == SECURE_SOCKET_VERIFY_NONE)
329                 {
330                         SSL_set_verify(__pSecureSocketImpl->__pSsl, SSL_VERIFY_PEER, null);
331                 }
332
333                 sslError = SSL_connect(__pSecureSocketImpl->__pSsl);
334                 SysTryReturnResult(NID_NET_SOCK, sslError >= 1, E_SYSTEM, "Failed to perform the handshake.");
335         }
336
337         return r;
338
339 CATCH:
340         if (__pThread)
341         {
342                 delete __pThread;
343                 __pThread = null;
344         }
345
346         return r;
347 }
348
349 } } } // Tizen::Net::Sockets