1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "remote_uri.h"
17 #include <string>
18 #include <fcntl.h>
19 #include <tuple>
20 #include <unistd.h>
21 #include "accesstoken_kit.h"
22 #include "ipc_skeleton.h"
23 #include "hap_token_info.h"
24
25 namespace OHOS {
26 namespace DistributedFS {
27 namespace ModuleRemoteUri {
28 namespace {
29 const std::string FRAGMENT_TAG = "#";
30 const std::string FD_TAG = "=";
31 const std::string REMOTE_URI_TAG = "fdFromBinder";
32 const std::string SCHEME_TAG = ":";
33 const std::string SCHEME = "datashare";
34 }
35
GetCallingPkgName()36 static std::string GetCallingPkgName()
37 {
38 uint32_t pid = IPCSkeleton::GetCallingTokenID();
39 Security::AccessToken::HapTokenInfo tokenInfo = Security::AccessToken::HapTokenInfo();
40 Security::AccessToken::AccessTokenKit::GetHapTokenInfo(pid, tokenInfo);
41 return tokenInfo.bundleName;
42 }
43
IsRemoteUri(const std::string & path,int & fd,const int & flags)44 bool RemoteUri::IsRemoteUri(const std::string& path, int &fd, const int& flags)
45 {
46 std::string::size_type posDatashare = path.find(SCHEME_TAG);
47 std::string::size_type posFragment = path.find(FRAGMENT_TAG);
48 std::string::size_type posFd = path.find(FD_TAG);
49 if (posDatashare == std::string::npos || posFragment == std::string::npos ||
50 posFd == std::string::npos) {
51 return false;
52 }
53
54 std::string scheme = path.substr(0, posDatashare);
55 if (scheme != SCHEME) {
56 return false;
57 }
58
59 std::string fragment = path.substr(posFragment + 1, REMOTE_URI_TAG.size());
60 if (fragment == REMOTE_URI_TAG) {
61 std::string fdStr = path.substr(posFd + 1);
62 fd = atoi(fdStr.c_str());
63 if (fd < 0 || flags != O_RDONLY) {
64 fd = -1;
65 }
66 return true;
67 }
68 return false;
69 }
70
ConvertUri(const int & fd,std::string & remoteUri)71 int RemoteUri::ConvertUri(const int &fd, std::string &remoteUri)
72 {
73 if (fd < 0) {
74 return EINVAL;
75 }
76 std::string pkgName = GetCallingPkgName();
77 remoteUri = SCHEME + ":///" + pkgName + "/" + FRAGMENT_TAG +
78 REMOTE_URI_TAG + FD_TAG + std::to_string(fd);
79 return 0;
80 }
81
OpenRemoteUri(const std::string & remoteUri)82 int RemoteUri::OpenRemoteUri(const std::string &remoteUri)
83 {
84 int fd = -1;
85 IsRemoteUri(remoteUri, fd);
86 return fd;
87 }
88 } // namespace ModuleRemoteUri
89 } // namespace DistributedFS
90 } // namespace OHOS
91