Move db initialize func and make deinit func
[platform/core/security/cert-svc.git] / vcore / server / src / cert-server-main.c
1 /**
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *  http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 /**
17  * @file     cert-server-main.c
18  * @author   Madhan A K (madhan.ak@samsung.com)
19  *           Kyungwook Tak (k.tak@samsung.com)
20  * @version  1.0
21  * @brief    cert-svc server.
22  */
23
24 #include <stdlib.h>
25 #include <signal.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <sys/un.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/socket.h>
32 #include <sys/time.h>
33 #include <sys/select.h>
34 #include <systemd/sd-daemon.h>
35
36 #include <cert-svc/cerror.h>
37 #include <cert-svc/ccert.h>
38 #include <vcore/Client.h>
39
40 #include <cert-server-debug.h>
41 #include <cert-server-logic.h>
42 #include <cert-server-db.h>
43
44 void CertSigHandler(int signo)
45 {
46         SLOGD("Got Signal %d, exiting now.", signo);
47
48         deinitialize_db();
49
50         exit(1);
51 }
52
53 int CertSvcGetSocketFromSystemd(int *pSockfd)
54 {
55         int n = sd_listen_fds(0);
56         int fd;
57
58         for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
59                 if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, VCORE_SOCK_PATH, 0)) {
60                         LOGD("Get socket from systemd. fd[%d]", fd);
61                         *pSockfd = fd;
62                         return CERTSVC_SUCCESS;
63                 }
64         }
65
66         return CERTSVC_FAIL;
67 }
68
69 void CertSvcServerComm(void)
70 {
71         int server_sockfd = 0;
72         int client_sockfd = 0;
73         int read_len = 0;
74         int client_len = 0;
75         struct sockaddr_un clientaddr;
76         int result = CERTSVC_SUCCESS;
77         char *certListBuffer = NULL;
78         char *certBlockBuffer = NULL;
79         size_t bufferLen = 0;
80         size_t blockBufferLen = 0;
81
82         struct timeval timeout;
83         timeout.tv_sec = 10;
84         timeout.tv_usec = 0;
85
86         SLOGI("cert-server is starting...");
87
88         VcoreRequestData recv_data;
89         VcoreResponseData send_data;
90
91         if (CertSvcGetSocketFromSystemd(&server_sockfd) != CERTSVC_SUCCESS) {
92                 SLOGE("Failed to get sockfd from systemd.");
93                 return;
94         }
95
96         client_len = sizeof(clientaddr);
97         signal(SIGINT, (void*)CertSigHandler);
98
99         result = initialize_db();
100         if (result != CERTSVC_SUCCESS) {
101                 SLOGE("Failed to initialize database.");
102                 result = CERTSVC_IO_ERROR;
103                 goto Error_close_exit;
104         }
105
106         fd_set fd;
107         struct timeval tv;
108         while (1) {
109                 errno = 0;
110
111                 FD_ZERO(&fd);
112                 FD_SET(server_sockfd, &fd);
113
114                 tv.tv_sec = 1;
115                 tv.tv_usec = 0;
116
117                 memset(&recv_data, 0x00, sizeof(VcoreRequestData));
118                 memset(&send_data, 0x00, sizeof(VcoreResponseData));
119
120                 int ret = select(server_sockfd + 1, &fd, NULL, NULL, &tv);
121                 if (ret == 0) { // timeout
122                         SLOGD("cert-server timeout. exit.");
123                         break;
124                 }
125
126                 if (ret == -1) {
127                         SLOGE("select() error.");
128                         break;
129                 }
130
131                 if ((client_sockfd = accept(server_sockfd, (struct sockaddr*)&clientaddr, (socklen_t*)&client_len)) < 0) {
132                         SLOGE("Error in function accept().[socket desc :%d, error no :%d].", client_sockfd, errno);
133                         continue;
134                 }
135
136                 SLOGD("cert-server Accept! client sock[%d]", client_sockfd);
137
138                 if (setsockopt(client_sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
139                         SLOGE("Error in Set SO_RCVTIMEO Socket Option");
140                         send_data.result = CERTSVC_FAIL;
141                         goto Error_close_exit;
142                 }
143
144                 if (setsockopt(client_sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) {
145                         SLOGE("Error in Set SO_SNDTIMEO Socket Option");
146                         send_data.result = CERTSVC_FAIL;
147                         goto Error_close_exit;
148                 }
149
150                 SLOGD("Connected to a client...");
151
152                 read_len = recv(client_sockfd, (char*)&recv_data, sizeof(recv_data), 0);
153                 if (read_len < 0) {
154                         SLOGE("Error in function recv().");
155                         send_data.result = CERTSVC_FAIL;
156                         goto Error_close_exit;
157                 }
158
159                 SLOGD("revc request: reqType=%d", recv_data.reqType);
160
161                 switch (recv_data.reqType) {
162                 case CERTSVC_EXTRACT_CERT:
163                 {
164                         send_data.result = getCertificateDetailFromStore(
165                                         recv_data.storeType,
166                                         recv_data.certType,
167                                         recv_data.gname,
168                                         send_data.dataBlock);
169                         send_data.dataBlockLen = strlen(send_data.dataBlock);
170                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
171                         break;
172                 }
173
174                 case CERTSVC_EXTRACT_SYSTEM_CERT:
175                 {
176                         send_data.result = getCertificateDetailFromSystemStore(
177                                         recv_data.gname,
178                                         send_data.dataBlock);
179                         send_data.dataBlockLen = strlen(send_data.dataBlock);
180                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
181                         break;
182                 }
183
184                 case CERTSVC_DELETE_CERT:
185                 {
186                         send_data.result = deleteCertificateFromStore(
187                                         recv_data.storeType,
188                                         recv_data.gname);
189                         if (send_data.result == CERTSVC_SUCCESS)
190                                 send_data.result = update_ca_certificate_file(NULL);
191                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
192                         break;
193                 }
194
195                 case CERTSVC_GET_CERTIFICATE_STATUS:
196                 {
197                         send_data.result = getCertificateStatusFromStore(
198                                         recv_data.storeType,
199                                         recv_data.gname,
200                                         &send_data.certStatus);
201                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
202                         break;
203                 }
204
205                 case CERTSVC_SET_CERTIFICATE_STATUS:
206                 {
207                         send_data.result = setCertificateStatusToStore(
208                                         recv_data.storeType,
209                                         recv_data.is_root_app,
210                                         recv_data.gname,
211                                         recv_data.certStatus);
212                         if (send_data.result == CERTSVC_SUCCESS)
213                                 send_data.result = update_ca_certificate_file(NULL);
214                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
215                         break;
216                 }
217
218                 case CERTSVC_CHECK_ALIAS_EXISTS:
219                 {
220                         send_data.result = checkAliasExistsInStore(
221                                         recv_data.storeType,
222                                         recv_data.gname,
223                                         &send_data.isAliasUnique);
224                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
225                         break;
226                 }
227
228                 case CERTSVC_INSTALL_CERTIFICATE:
229                 {
230                         send_data.result = installCertificateToStore(
231                                         recv_data.storeType,
232                                         recv_data.gname,
233                                         recv_data.common_name,
234                                         recv_data.private_key_gname,
235                                         recv_data.associated_gname,
236                                         recv_data.dataBlock,
237                                         recv_data.certType);
238
239                         if (send_data.result == CERTSVC_SUCCESS && (recv_data.certType == PEM_CRT || recv_data.certType == P12_TRUSTED))
240                                 send_data.result = update_ca_certificate_file(recv_data.dataBlock);
241                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
242                         break;
243                 }
244
245                 case CERTSVC_GET_CERTIFICATE_LIST:
246                 case CERTSVC_GET_USER_CERTIFICATE_LIST:
247                 case CERTSVC_GET_ROOT_CERTIFICATE_LIST:
248                 {
249                         send_data.result = getCertificateListFromStore(
250                                         recv_data.reqType,
251                                         recv_data.storeType,
252                                         recv_data.is_root_app,
253                                         &certListBuffer,
254                                         &bufferLen,
255                                         &send_data.certCount);
256                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
257                         if (bufferLen > 0)
258                                 result = send(client_sockfd, certListBuffer, bufferLen, 0);
259                         break;
260                 }
261
262                 case CERTSVC_GET_CERTIFICATE_ALIAS:
263                 {
264                         send_data.result = getCertificateAliasFromStore(
265                                         recv_data.storeType,
266                                         recv_data.gname,
267                                         send_data.common_name);
268                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
269                         break;
270                 }
271
272                 case CERTSVC_LOAD_CERTIFICATES:
273                 {
274                         send_data.result = loadCertificatesFromStore(
275                                         recv_data.storeType,
276                                         recv_data.gname,
277                                         &certBlockBuffer,
278                                         &blockBufferLen,
279                                         &send_data.certBlockCount);
280                         result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
281                         if (blockBufferLen > 0)
282                                 result = send(client_sockfd, certBlockBuffer, blockBufferLen, 0);
283                         break;
284                 }
285
286                 default:
287                         SLOGE("Input error. Please check request type");
288                         break;
289                 }
290
291                 if (result <= 0)
292                         SLOGE("send failed :%d, errno %d try once", result, errno);
293         }
294
295 Error_close_exit:
296         close(server_sockfd);
297
298         deinitialize_db();
299
300         free(certListBuffer);
301         free(certBlockBuffer);
302
303         if (client_sockfd >= 0) {
304                 result = send(client_sockfd, (char*)&send_data, sizeof(send_data), 0);
305                 close(client_sockfd);
306         } else {
307                 SLOGE("cannot connect to client socket.");
308         }
309
310         SLOGI("CertSvcServerComm done.");
311 }
312
313 int main(void)
314 {
315         SLOGI("cert-server start");
316         CertSvcServerComm();
317         SLOGI("cert-server end");
318
319         return 0;
320 }