b522b5f94914de872d7a85a4dbc19c3cd92a3072
[platform/core/security/key-manager.git] / src / manager / main / socket-2-id.cpp
1 /*
2  *  Copyright (c) 2000 - 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       socket-2-id.cpp
18  * @author     Bartlomiej Grzelewski (b.grzelewski@samsung.com)
19  * @version    1.0
20  */
21 #include <sys/smack.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24
25 #include <security-manager.h>
26
27 #include <dpl/log/log.h>
28 #include <protocols.h>
29 #include <socket-2-id.h>
30
31 namespace CKM {
32 namespace {
33
34 int getCredentialsFromSocket(int sock, std::string &res)  {
35     std::vector<char> result(1);
36     socklen_t length = 1;
37
38     if ((0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length))
39       && errno != ERANGE)
40     {
41         LogError("getsockopt failed");
42         return -1;
43     }
44
45     result.resize(length);
46
47     if (0 > getsockopt(sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)) {
48         LogError("getsockopt failed");
49         return -1;
50     }
51
52     result.push_back('\0');
53     res = result.data();
54     return 0;
55 }
56
57 int getPkgIdFromSmack(const std::string &smack, std::string &pkgId) {
58     // TODO
59     // Conversion from smack label to pkgId should be done
60     // by security-manager. Current version of security-manager
61     // does not support this feature yet.
62
63     static const std::string SMACK_PREFIX_APPID  = "User::App::";
64
65     if (smack.empty()) {
66         LogError("Smack is empty. Connection will be rejected");
67         return -1;
68     }
69
70     if (smack.compare(0, SMACK_PREFIX_APPID.size(), SMACK_PREFIX_APPID)) {
71         pkgId = "/" + smack;
72         LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId);
73         return 0;
74     }
75
76     std::string appId = smack.substr(SMACK_PREFIX_APPID.size(), std::string::npos);
77
78     char *pkg = nullptr;
79
80     if (0 > security_manager_get_app_pkgid(&pkg, appId.c_str())) {
81         LogError("Error in security_manager_get_app_pkgid");
82         return -1;
83     }
84
85     if (!pkg) {
86         LogError("PkgId could not be NULL");
87         return -1;
88     }
89
90     pkgId = pkg;
91     free(pkg);
92     LogDebug("Smack: " << smack << " Was translated to owner id: " << pkgId);
93     return 0;
94 }
95
96 } // namespace anonymous
97
98
99 int Socket2Id::translate(int sock, std::string &result) {
100     std::string smack;
101
102     if (0 > getCredentialsFromSocket(sock, smack)) {
103         return -1;
104     }
105
106     StringMap::iterator it = m_stringMap.find(smack);
107
108     if (it != m_stringMap.end()) {
109         result = it->second;
110         return 0;
111     }
112
113     std::string pkgId;
114     if (0 > getPkgIdFromSmack(smack, pkgId)) {
115         return -1;
116     }
117
118     result = pkgId;
119     m_stringMap.emplace(std::move(smack), std::move(pkgId));
120     return 0;
121 }
122
123 void Socket2Id::resetCache() {
124     m_stringMap.clear();
125 }
126
127 } // namespace CKM
128