PluginProbe
WebTotem Security / 2.1.3
WebTotem Security v2.1.3
3.0.1 3.0.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.1 2.2.2 2.2.3 2.2.4 All 109 releases
wt-security / library / WT.php

WT.php in WebTotem Security 2.1.3, at library/WT.php

319 lines 16.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php defined('ABSPATH') or die("Protected By WT!");
2
3
4 class WTSEC_LIBRARY_WT
5 {
6 const URL = "https://api.wtotem.com/graphql";
7
8 public static function auth($key)
9 {
10 $payload = '{"query":"mutation{\n guest{\n apiKeys{\n auth(apiKey:\"' . $key . '\"),{\n token{\n value,refreshToken,expiresIn\n }\n }\n }\n }\n}"}';
11 return self::requestApi($payload);
12 }
13
14 protected static function requestApi($payload, $token = false, $repeat = false)
15 {
16 if ($token) {
17 $token = WTSEC_LIBRARY_App::getToken();
18 }
19 $args = [
20 'body' => $payload,
21 'timeout' => '15',
22 'sslverify' => false,
23 'headers' => ['Content-Type:application/json', 'Content-Type' => 'application/json', 'source:WORDPRESS', 'Accept: application/json'],
24 ];
25 if (!is_null($token) && $token) {
26 $authorization = "Bearer " . $token;
27 $args['headers'] = array_merge($args['headers'], ["Authorization" => $authorization]);
28 }
29 $response = wp_remote_post(self::URL, $args);
30 $httpcode = wp_remote_retrieve_response_code($response);
31
32 if ($httpcode < 200) {
33 WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server'));
34 }
35 $response = wp_remote_retrieve_body($response);
36
37 $result = json_decode($response, true);
38 if (isset($result['errors'][0]['message'])) {
39 $message = self::diffMesageForHuman($result['errors'][0]['message']);
40 if (stripos($result['errors'][0]['message'], "token") !== false && !$repeat) {
41 $result = WTSEC_LIBRARY_WT::auth(wtsec_app()->get("api_key"));
42 if (isset($result['data']['guest']['apiKeys']['auth']['token']['value'])) {
43 $token_ = $result['data']['guest']['apiKeys']['auth']['token']['value'];
44 WTSEC_LIBRARY_App::login($token_);
45 return self::requestApi($payload, $token, true);
46 } else {
47 WTSEC_LIBRARY_App::logout();
48 }
49 } else {
50 if ($message !== false) {
51 WTSEC_LIBRARY_Session::setNotification("warning", $message);
52 }
53 }
54 }
55 return $result;
56 }
57
58 public static function diffMesageForHuman($message)
59 {
60 $definition = $message;
61 $excepts = [
62 "RESOURCE_NOT_FOUND", "DUPLICATE_HOST", "INVALID_CREDENTIALS", "INVALID_API_KEY", "Invalid token",
63 ];
64 if (in_array($message, $excepts)) {
65 return false;
66 }
67 switch ($message) {
68 case 'HOSTS_LIMIT_EXCEEDED':
69 $definition = WTSEC_LIBRARY_Localization::lmsg('hosts_limit_exceed');
70 break;
71 case 'RESOURCE_NOT_FOUND':
72 $definition = WTSEC_LIBRARY_Localization::lmsg('resource_not_found');
73 break;
74 case 'Invalid token':
75 $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_token');
76 break;
77 case 'USER_ALREADY_REGISTERED':
78 $definition = WTSEC_LIBRARY_Localization::lmsg('user_already_exist');
79 break;
80 case 'DUPLICATE_HOST':
81 $definition = WTSEC_LIBRARY_Localization::lmsg('duplicate_host');
82 break;
83 case 'Agent does not exist or has been already verified':
84 $definition = WTSEC_LIBRARY_Localization::lmsg('agent_does_not_exist_or_has_been_already_verified');
85 break;
86 case 'INVALID_DOMAIN_NAME':
87 $definition = WTSEC_LIBRARY_Localization::lmsg('invalid_domain_name');
88 break;
89 }
90 return $definition;
91 }
92
93 public static function requestURL($url)
94 {
95 $args = [
96 'timeout' => '15',
97 'sslverify' => false,
98 ];
99 $response = wp_remote_get($url, $args);
100 $httpcode = wp_remote_retrieve_response_code($response);
101 if ($httpcode < 200) {
102 WTSEC_LIBRARY_Session::setNotification("error", WTSEC_LIBRARY_Localization::lmsg('could_not_connect_to_the_server'));
103 }
104 $response = wp_remote_retrieve_body($response);
105 return $response;
106 }
107
108 public static function getOwnSite($attempt = false)
109 {
110 $payload = '{"query":"query getSites { auth { viewer { sites { ...sites __typename } __typename } __typename }}fragment sites on SiteQueries { list(filter: {}) { edges { node { id hostname title ssl { status __typename } availability { status __typename } reputation { status __typename } ports { status __typename } deface { status __typename } domain { status __typename } antivirus { status __typename } firewall { status __typename } maliciousScript { stack { name __typename } __typename } __typename } __typename } __typename } __typename}"}';
111
112 $result = self::requestApi($payload, true);
113 if (isset($result['data']['auth']['viewer']['sites']['list']['edges'])) {
114 //mutator
115 foreach ($result['data']['auth']['viewer']['sites']['list']['edges'] as &$m) {
116 if (isset($m['node']['hostname'])) {
117 $m['node']['hostname'] = WTSEC_LIBRARY_Idn::idn_to_utf8($m['node']['hostname']);
118 // if ($m['node']['id'] == "c2l0ZV8yNTg=") {
119 // return $m['node'];
120 // }
121 if (self::isSiteUrl($m['node']['hostname'])) {
122 return $m['node'];
123 }
124 }
125 }
126 $add_site = self::addSite(WTSEC_SITE_URL);
127 if (isset($add_site['errors'])) {
128 return $result['data']['node'] = [];
129 } else {
130 if (!$attempt) {
131 return self::getOwnSite(true);
132 }
133 }
134 }
135 return [];
136 }
137
138 public static function isSiteUrl($url)
139 {
140 return WTSEC_LIBRARY_Idn::idn_to_utf8(WTSEC_SITE_URL) === $url;
141 }
142
143 public static function addSite($url)
144 {
145 $payload = '{"variables":{"input":{"title":"' . $url . '","hostname":"' . $url . '","configs":{"scheme":"http","port":80,"wa":{},"dec":{},"ps":{}}}},"query":"mutation ($input: CreateSiteInput) {\n auth {\n sites {\n create(input: $input) {\n id\n hostname\n title\n __typename\n }\n __typename\n }\n __typename\n }\n}\n"}';
146 return self::requestApi($payload, true);
147 }
148
149 public static function getAllChecks($host_id)
150 {
151 $from = time() - (60 * 60 * 24);
152 $to = time();
153 $from_waf = time() - (60 * 60 * 24 * 7);
154 $payload = '{"query":"query($id: ID!, $dateRange:DateRangeInput!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n availability {\n status\n lastTest {\n time\n }\n responseTime\n downTime(dateRange: $dateRange)\n percent(dateRange: $dateRange)\n }\n deface {\n status\n lastTest {\n time\n }\n words\n count\n }\n domain {\n status\n registrar\n owner\n email\n createdDate\n expiredDate\n }\n ports {\n status\n lastTest {\n time\n }\n ip\n tcp\n country\n }\n ssl {\n status\n daysLeft\n expiryDate\n issueDate\n }\n reputation {\n status\n lastTest {\n time\n }\n virusList {\n viruses\n antiVirus\n }\n }\n firewall {\n lastTest { \n time\n } \n status\n chart(dateRange: $dateRange) {\n time\n attacks\n blocked\n }\n report(dateRange: $dateRange) {\n time\n attacks\n ip\n }\n }\n maliciousScript{\n lastTest{\n time\n }\n status\n }\n antivirus{\n status \n stats { \n changed\n deleted\n scaned\n infected\n error\n } \n lastTest { \n time\n } \n isFirstCheck\n }\n }\n }\n }\n }\n}","variables":{"id":"' . $host_id . '","dateRange":{"to":' . $to . ',"from":' . $from_waf . '}}}';
155 $response = self::requestApi($payload, true);
156 if (isset($response['data']['auth']['viewer']['sites']['one'])) {
157 return $response['data']['auth']['viewer']['sites']['one'];
158 }
159 return [];
160 }
161
162 public static function changeStatus($config_id, $host_id)
163 {
164 $payload = '{"query":"\n mutation {\n toggleServiceConfig(\n id: ' . $config_id . '\n userhostId: ' . $host_id . '\n ) {\n isActive\n }\n }\n "}';
165 return self::requestApi($payload, true);
166 }
167
168 public static function serviceConnect($id, $service)
169 {
170 $payload = '{"query":"mutation {\n auth {\n agents{\n check(siteId:\"' . $id . '\",service:' . strtolower($service) . ',plugin:WORDPRESS)\n }\n }\n}\n"}';
171 return self::requestApi($payload, true);
172 }
173
174 public static function generateFile($id, $service)
175 {
176 $payload = '{"query":"mutation {\n auth {\n agents{\n generate(siteId:\"' . $id . '\",service:' . strtolower($service) . '){\n agentName\n }\n }\n }\n}\n"}';
177 return self::requestApi($payload, true);
178 }
179
180 public static function checkStatus($id, $service)
181 {
182 $payload = '{"operationName":null,"variables":{"id":"' . $id . '"},"query":"query ($id: ID!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n ... on Site {\n configs {\n ... on ' . $service . 'Config {\n isActive\n id\n }\n }\n }\n }\n }\n }\n }\n}\n"}';
183 return self::requestApi($payload, true);
184 }
185
186 public static function getOptions($host_id)
187 {
188 $payload = '{"query":"query{\nuserHost(id:' . $host_id . '){\n id\n title\n hostname\n stack\n createdAt\n services {\n id\n name\n configs {\n id\n \tdata\n isActive\n }\n }\n }\n}"}';
189 return self::requestApi($payload, true);
190 }
191
192 public static function getAntivirus($host_id)
193 {
194 $payload = '{"operationName":null,"variables":{"id":"' . $host_id . '","avLogFilter":{"event":"infected","order":{"direction":"DESC","field":"time"},"pagination":{"first":10,"cursor":null}}},"query":"query ($id: ID!, $avLogFilter: AvLogFilter!) {\n auth {\n viewer {\n sites {\n one(id: $id) {\n id\n ... on Site {\n configs {\n ... on AvConfig {\n isActive\n id\n }\n }\n }\n antivirus {\n status\n log(avLogFilter: $avLogFilter) {\n edges {\n node {\n filePath\n matches\n event\n signatures\n time\n }\n }\n }\n lastTest {\n time\n }\n stats {\n changed\n deleted\n scaned\n infected\n }\n }\n }\n }\n }\n }\n}\n"}';
195 return self::requestApi($payload, true);
196 }
197
198 public static function getStatusIcon($status)
199 {
200 $statuses = [
201 "clean" => [
202 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.ok'),
203 "color" => self::getColor("success")
204 ],
205 "pending" => [
206 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.pending'),
207 "color" => self::getColor("grey")
208 ],
209 "expired" => [
210 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expired'),
211 "color" => self::getColor("orange")
212
213 ],
214 "invalid" => [
215 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.invalid'),
216 "color" => self::getColor("error")
217 ],
218 "no_cert" => [
219 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.no_cert'),
220 "color" => self::getColor("orange")
221 ],
222 "error" => [
223 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.error'),
224 "color" => self::getColor("error")
225 ],
226 "expires" => [
227 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires'),
228 "color" => self::getColor("orange")
229 ],
230 "expires_today" => [
231 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.expires_today'),
232 "color" => self::getColor("error")
233 ],
234 "down" => [
235 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.down'),
236 "color" => self::getColor("error")
237 ],
238 "up" => [
239 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.up'),
240 "color" => self::getColor("success")
241 ],
242 "infected" => [
243 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.infected'),
244 "color" => self::getColor("error")
245 ],
246 "open_ports" => [
247 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.open'),
248 "color" => self::getColor("orange")
249 ],
250 "deface" => [
251 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.deface'),
252 "color" => self::getColor("error")
253 ],
254 "modified" => [
255 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.modified'),
256 "color" => self::getColor("grey")
257 ],
258 "not_supported" => [
259 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.unsupported'),
260 "color" => self::getColor("orange")
261 ],
262 "not_registered" => [
263 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_registered'),
264 "color" => self::getColor("orange")
265 ],
266 "not_installed" => [
267 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.not_installed'),
268 "color" => self::getColor("error")
269 ],
270 "working" => [
271 "text" => WTSEC_LIBRARY_Localization::lmsg('statuses.working'),
272 "color" => self::getColor("success")
273 ],
274 ];
275 if (isset($statuses[$status])) {
276 return ["icon" => $statuses[$status]["color"]["icon"], "color" => $statuses[$status]["color"]["color"], "text" => "<span class='" . $statuses[$status]["color"]["color"] . "'>" . $statuses[$status]["text"] . "</span>"];
277 } else {
278 return ["icon" => "ww-icon--status_unknow", "color" => "ww--status_unknow", "text" => "<span class='ww--status_unknow'>Unknown status</span>"];
279 }
280 }
281
282 public static function getColor($type)
283 {
284 $types = [
285 "green" => "is--status--ok",
286 "red" => "is--status--error",
287 "success" => "is--status--ok",
288 "error" => "is--status--error",
289 "orange" => "is--status--warning",
290 "warning" => "is--status--warning",
291 "grey" => "ww--status_unknow"
292 ];
293 $icon_types = [
294 "green" => "ww-icon--status_ok",
295 "red" => "ww-icon--status_error",
296 "success" => "ww-icon--status_ok",
297 "error" => "ww-icon--status_error",
298 "orange" => "ww-icon--status_warning",
299 "warning" => "ww-icon--status_warning",
300 "grey" => "ww-icon--status_unknow"
301 ];
302 return ["icon" => $icon_types[$type], "color" => $types[$type]];
303 }
304
305 public static function getConfigId($configs)
306 {
307 $id = 0;
308 $is_active = false;
309 foreach ($configs as &$config) {
310 if (!empty($config)) {
311 $id = $config['id'];
312 $is_active = $config['isActive'];
313 break;
314 }
315 }
316 return compact('id', 'is_active');
317 }
318
319 }