• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 <cstring>
17 #include <map>
18 #include <securec.h>
19 #include <string>
20 #include <vector>
21 
22 #define private public
23 #include "http_client.h"
24 #include "http_client_request.h"
25 #undef private
26 #include "http_request_options.h"
27 #include "netstack_log.h"
28 #include "secure_char.h"
29 
30 namespace OHOS {
31 namespace NetStack {
32 namespace Http {
33 namespace {
34 using namespace OHOS::NetStack::HttpClient;
35 const uint8_t *g_baseFuzzData = nullptr;
36 size_t g_baseFuzzSize = 0;
37 size_t g_baseFuzzPos = 0;
38 constexpr size_t STR_LEN = 255;
39 constexpr int32_t TEST_PORT = 8888;
40 } // namespace
GetData()41 template <class T> T GetData()
42 {
43     T object{};
44     size_t objectSize = sizeof(object);
45     if (g_baseFuzzData == nullptr || g_baseFuzzSize <= g_baseFuzzPos || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
46         return object;
47     }
48     if (memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize)) {
49         return {};
50     }
51     g_baseFuzzPos += objectSize;
52     return object;
53 }
54 
SetGlobalFuzzData(const uint8_t * data,size_t size)55 void SetGlobalFuzzData(const uint8_t *data, size_t size)
56 {
57     g_baseFuzzData = data;
58     g_baseFuzzSize = size;
59     g_baseFuzzPos = 0;
60 }
61 
GetStringFromData(int strlen)62 std::string GetStringFromData(int strlen)
63 {
64     if (strlen < 1) {
65         return "";
66     }
67 
68     char cstr[strlen];
69     cstr[strlen - 1] = '\0';
70     for (int i = 0; i < strlen - 1; i++) {
71         cstr[i] = GetData<char>();
72     }
73     std::string str(cstr);
74     return str;
75 }
76 
SetCaPathFuzzTest(const uint8_t * data,size_t size)77 void SetCaPathFuzzTest(const uint8_t *data, size_t size)
78 {
79     if ((data == nullptr) || (size < 1)) {
80         return;
81     }
82     SetGlobalFuzzData(data, size);
83     std::string str = GetStringFromData(STR_LEN);
84 
85     HttpRequestOptions requestOptions;
86     requestOptions.SetCaPath(str);
87 }
88 
SetCaDataFuzzTest(const uint8_t * data,size_t size)89 void SetCaDataFuzzTest(const uint8_t *data, size_t size)
90 {
91     if ((data == nullptr) || (size < 1)) {
92         return;
93     }
94     SetGlobalFuzzData(data, size);
95     std::string str = GetStringFromData(STR_LEN);
96 
97     HttpRequestOptions requestOptions;
98     requestOptions.SetCaData(str);
99 }
100 
SetUrlFuzzTest(const uint8_t * data,size_t size)101 void SetUrlFuzzTest(const uint8_t *data, size_t size)
102 {
103     if ((data == nullptr) || (size < 1)) {
104         return;
105     }
106     SetGlobalFuzzData(data, size);
107     HttpRequestOptions requestOptions;
108     std::string str = GetStringFromData(STR_LEN);
109     requestOptions.SetUrl(str);
110 }
111 
SetMethodFuzzTest(const uint8_t * data,size_t size)112 void SetMethodFuzzTest(const uint8_t *data, size_t size)
113 {
114     if ((data == nullptr) || (size < 1)) {
115         return;
116     }
117     SetGlobalFuzzData(data, size);
118     HttpRequestOptions requestOptions;
119     std::string str = GetStringFromData(STR_LEN);
120     requestOptions.SetMethod(str);
121 }
122 
SetHeaderFuzzTest(const uint8_t * data,size_t size)123 void SetHeaderFuzzTest(const uint8_t *data, size_t size)
124 {
125     if ((data == nullptr) || (size < 1)) {
126         return;
127     }
128     SetGlobalFuzzData(data, size);
129     HttpRequestOptions requestOptions;
130     std::string str = GetStringFromData(STR_LEN);
131     requestOptions.SetHeader(str, str);
132 }
133 
SetReadTimeoutFuzzTest(const uint8_t * data,size_t size)134 void SetReadTimeoutFuzzTest(const uint8_t *data, size_t size)
135 {
136     if ((data == nullptr) || (size < 1)) {
137         return;
138     }
139     SetGlobalFuzzData(data, size);
140     HttpRequestOptions requestOptions;
141     requestOptions.SetReadTimeout(size);
142 }
143 
SetConnectTimeoutFuzzTest(const uint8_t * data,size_t size)144 void SetConnectTimeoutFuzzTest(const uint8_t *data, size_t size)
145 {
146     if ((data == nullptr) || (size < 1)) {
147         return;
148     }
149     SetGlobalFuzzData(data, size);
150     HttpRequestOptions requestOptions;
151     requestOptions.SetConnectTimeout(size);
152 }
153 
SetUsingProtocolFuzzTest(const uint8_t * data,size_t size)154 void SetUsingProtocolFuzzTest(const uint8_t *data, size_t size)
155 {
156     if ((data == nullptr) || (size < 1)) {
157         return;
158     }
159     SetGlobalFuzzData(data, size);
160     HttpRequestOptions requestOptions;
161 }
162 
SetHttpDataTypeFuzzTest(const uint8_t * data,size_t size)163 void SetHttpDataTypeFuzzTest(const uint8_t *data, size_t size)
164 {
165     if ((data == nullptr) || (size < 1)) {
166         return;
167     }
168     SetGlobalFuzzData(data, size);
169     HttpRequestOptions requestOptions;
170     std::string str = GetStringFromData(STR_LEN);
171     requestOptions.SetRequestTime(str);
172 }
173 
SetUsingHttpProxyTypeFuzzTest(const uint8_t * data,size_t size)174 void SetUsingHttpProxyTypeFuzzTest(const uint8_t *data, size_t size)
175 {
176     if ((data == nullptr) || (size < 1)) {
177         return;
178     }
179     SetGlobalFuzzData(data, size);
180     HttpRequestOptions requestOptions;
181     requestOptions.SetUsingHttpProxyType(UsingHttpProxyType::USE_SPECIFIED);
182 }
183 
SetSpecifiedHttpProxyFuzzTest(const uint8_t * data,size_t size)184 void SetSpecifiedHttpProxyFuzzTest(const uint8_t *data, size_t size)
185 {
186     if ((data == nullptr) || (size < 1)) {
187         return;
188     }
189     SetGlobalFuzzData(data, size);
190     HttpRequestOptions requestOptions;
191     std::string str = GetStringFromData(STR_LEN);
192     requestOptions.SetSpecifiedHttpProxy(str, size, str);
193 }
194 
SetDnsServersFuzzTest(const uint8_t * data,size_t size)195 void SetDnsServersFuzzTest(const uint8_t *data, size_t size)
196 {
197     if ((data == nullptr) || (size < 1)) {
198         return;
199     }
200     SetGlobalFuzzData(data, size);
201     HttpRequestOptions requestOptions;
202     std::vector<std::string> dnsServers = { GetStringFromData(STR_LEN), GetStringFromData(STR_LEN),
203         GetStringFromData(STR_LEN) };
204     requestOptions.SetDnsServers(dnsServers);
205 }
206 
SetDohUrlFuzzTest(const uint8_t * data,size_t size)207 void SetDohUrlFuzzTest(const uint8_t *data, size_t size)
208 {
209     if ((data == nullptr) || (size < 1)) {
210         return;
211     }
212     SetGlobalFuzzData(data, size);
213 
214     HttpRequestOptions requestOptions;
215     std::string str = GetStringFromData(STR_LEN);
216     requestOptions.SetDohUrl(str);
217 }
218 
SetRangeNumberFuzzTest(const uint8_t * data,size_t size)219 void SetRangeNumberFuzzTest(const uint8_t *data, size_t size)
220 {
221     if ((data == nullptr) || (size < 1)) {
222         return;
223     }
224     SetGlobalFuzzData(data, size);
225     HttpRequestOptions requestOptions;
226     requestOptions.SetRangeNumber(size, size);
227 }
228 
SetClientCertFuzzTest(const uint8_t * data,size_t size)229 void SetClientCertFuzzTest(const uint8_t *data, size_t size)
230 {
231     if ((data == nullptr) || (size < 1)) {
232         return;
233     }
234     SetGlobalFuzzData(data, size);
235 
236     HttpRequestOptions requestOptions;
237     std::string str = GetStringFromData(STR_LEN);
238     Secure::SecureChar pwd(str);
239     requestOptions.SetClientCert(str, str, str, pwd);
240 }
241 
AddMultiFormDataFuzzTest(const uint8_t * data,size_t size)242 void AddMultiFormDataFuzzTest(const uint8_t *data, size_t size)
243 {
244     if ((data == nullptr) || (size < 1)) {
245         return;
246     }
247     SetGlobalFuzzData(data, size);
248     HttpRequestOptions requestOptions;
249     MultiFormData multiFormData;
250     std::string str = GetStringFromData(STR_LEN);
251     multiFormData.name = str;
252     multiFormData.data = str;
253     multiFormData.contentType = str;
254     multiFormData.remoteFileName = str;
255     multiFormData.filePath = str;
256     requestOptions.AddMultiFormData(multiFormData);
257 }
258 
CreateHttpClientRequest()259 HttpClientRequest CreateHttpClientRequest()
260 {
261     HttpClientRequest httpReq;
262     std::string url = "https://www.baidu.com";
263     httpReq.SetURL(url);
264     return httpReq;
265 }
266 
CreateHttpClientRequest(const uint8_t * data,size_t size)267 HttpClientRequest CreateHttpClientRequest(const uint8_t *data, size_t size)
268 {
269     g_baseFuzzData = data;
270     g_baseFuzzSize = size;
271     g_baseFuzzPos = 0;
272     HttpClientRequest httpReq;
273     std::string str = GetStringFromData(STR_LEN);
274     httpReq.SetURL(str);
275     return httpReq;
276 }
277 
HttpSessionCreateTaskFuzzTest(const uint8_t * data,size_t size)278 void HttpSessionCreateTaskFuzzTest(const uint8_t *data, size_t size)
279 {
280     if ((data == nullptr) || (size < 1)) {
281         return;
282     }
283     HttpClientRequest httpReq = CreateHttpClientRequest();
284     auto testTask = HttpSession::GetInstance().CreateTask(httpReq);
285     testTask->Start();
286 
287     httpReq = CreateHttpClientRequest(data, size);
288     testTask = HttpSession::GetInstance().CreateTask(httpReq);
289     testTask->Start();
290 }
291 
HttpClientTaskGetHttpVersionFuzzTest(const uint8_t * data,size_t size)292 void HttpClientTaskGetHttpVersionFuzzTest(const uint8_t *data, size_t size)
293 {
294     if ((data == nullptr) || (size < 1)) {
295         return;
296     }
297 
298     HttpClientRequest httpReq = CreateHttpClientRequest();
299     auto task = HttpSession::GetInstance().CreateTask(httpReq);
300     HttpClient::HttpProtocol ptcl = HttpClient::HttpProtocol::HTTP1_1;
301     HttpClientRequest request;
302     request.SetHttpProtocol(ptcl);
303     uint32_t timeout = GetData<uint32_t>();
304     request.SetTimeout(timeout);
305     std::string testData = GetStringFromData(STR_LEN);
306     std::string result = request.GetBody();
307     request.body_ = "";
308     request.SetCaPath(testData);
309     uint32_t priority = GetData<uint32_t>();
310     request.SetPriority(priority);
311     result = request.GetURL();
312     result = request.GetMethod();
313     uint32_t ret = request.GetTimeout();
314     ret = request.GetConnectTimeout();
315     ptcl = request.GetHttpProtocol();
316     HttpClient::HttpProxyType proType = request.GetHttpProxyType();
317     NETSTACK_LOGD("ptcl = %{private}d, proType = %{private}d", ptcl, proType);
318     result = request.GetCaPath();
319     ret = request.GetPriority();
320     HttpProxy proxy = request.GetHttpProxy();
321     request.SetRequestTime(testData);
322     result = request.GetRequestTime();
323     task->GetHttpVersion(ptcl);
324 
325     request = CreateHttpClientRequest(data, size);
326     task = HttpSession::GetInstance().CreateTask(request);
327     task->SetOtherCurlOption(task->curlHandle_);
328 }
329 
HttpClientTaskSetHttpProtocolFuzzTest(const uint8_t * data,size_t size)330 void HttpClientTaskSetHttpProtocolFuzzTest(const uint8_t *data, size_t size)
331 {
332     if ((data == nullptr) || (size < 1)) {
333         return;
334     }
335 
336     HttpClientRequest httpReq = CreateHttpClientRequest(data, size);
337     auto task = HttpSession::GetInstance().CreateTask(httpReq);
338     HttpClientRequest request;
339     HttpClient::HttpProtocol ptcl = HttpClient::HttpProtocol::HTTP1_1;
340     request.SetHttpProtocol(ptcl);
341     HttpProxy proxy = request.GetHttpProxy();
342     std::string testData = GetStringFromData(STR_LEN);
343     request.SetCaPath(testData);
344     request.SetRequestTime(testData);
345     std::string result = request.GetRequestTime();
346     result = request.GetBody();
347     request.body_ = "";
348     task->GetHttpVersion(ptcl);
349     result = request.GetURL();
350     result = request.GetMethod();
351     result = request.GetCaPath();
352     uint32_t timeout = GetData<uint32_t>();
353     request.SetTimeout(timeout);
354     uint32_t prio = GetData<uint32_t>();
355     request.SetPriority(prio);
356     uint32_t ret = request.GetTimeout();
357     ret = request.GetConnectTimeout();
358     ret = request.GetPriority();
359     ptcl = request.GetHttpProtocol();
360     HttpClient::HttpProxyType proType = request.GetHttpProxyType();
361     NETSTACK_LOGD("ptcl = %{private}d, proType = %{private}d", ptcl, proType);
362 }
363 
HttpClientTaskSetOtherCurlOptionFuzzTest(const uint8_t * data,size_t size)364 void HttpClientTaskSetOtherCurlOptionFuzzTest(const uint8_t *data, size_t size)
365 {
366     if ((data == nullptr) || (size < 1)) {
367         return;
368     }
369 
370     HttpClientRequest request;
371     std::string url = "http://www.httpbin.org/get";
372     request.SetURL(url);
373     request.SetHttpProxyType(NOT_USE);
374     HttpProxy testProxy;
375     testProxy.host = "192.168.147.60";
376     testProxy.exclusions = "www.httpbin.org";
377     testProxy.port = TEST_PORT;
378     testProxy.tunnel = false;
379     request.SetHttpProxy(testProxy);
380     auto task = HttpSession::GetInstance().CreateTask(request);
381     task->SetOtherCurlOption(task->curlHandle_);
382 
383     request = CreateHttpClientRequest(data, size);
384     task = HttpSession::GetInstance().CreateTask(request);
385     task->SetOtherCurlOption(task->curlHandle_);
386 }
387 
HttpClientTaskSetCurlOptionsFuzzTest(const uint8_t * data,size_t size)388 void HttpClientTaskSetCurlOptionsFuzzTest(const uint8_t *data, size_t size)
389 {
390     if ((data == nullptr) || (size < 1)) {
391         return;
392     }
393 
394     HttpClientRequest httpReq;
395     std::string url = "http://www.httpbin.org/get";
396     httpReq.SetURL(url);
397     auto task = HttpSession::GetInstance().CreateTask(httpReq);
398     task->request_.SetMethod(HttpConstant::HTTP_METHOD_HEAD);
399     task->SetCurlOptions();
400 
401     httpReq = CreateHttpClientRequest(data, size);
402     task = HttpSession::GetInstance().CreateTask(httpReq);
403     task->request_.SetMethod(HttpConstant::HTTP_METHOD_HEAD);
404     task->SetCurlOptions();
405 }
406 
HttpClientTaskGetTypeFuzzTest(const uint8_t * data,size_t size)407 void HttpClientTaskGetTypeFuzzTest(const uint8_t *data, size_t size)
408 {
409     if ((data == nullptr) || (size < 1)) {
410         return;
411     }
412 
413     HttpClientRequest httpReq = CreateHttpClientRequest();
414     auto task = HttpSession::GetInstance().CreateTask(httpReq);
415     TaskType type = task->GetType();
416     std::string result = task->GetFilePath();
417     int taskId = task->GetTaskId();
418     TaskStatus status = static_cast<TaskStatus>(size % 2);
419     task->SetStatus(status);
420     status = task->GetStatus();
421     NETSTACK_LOGD("type = %{private}d, result = %{private}s, taskId = %{private}d, status = %{private}d", type,
422         result.c_str(), taskId, status);
423     task->OnSuccess([task](const HttpClientRequest &request, const HttpClientResponse &response) {});
424     task->OnCancel([](const HttpClientRequest &request, const HttpClientResponse &response) {});
425     task->OnFail(
426         [](const HttpClientRequest &request, const HttpClientResponse &response, const HttpClientError &error) {});
427     task->OnDataReceive([](const HttpClientRequest &request, const uint8_t *data, size_t length) {});
428     task->OnProgress(
429         [](const HttpClientRequest &request, u_long dltotal, u_long dlnow, u_long ultotal, u_long ulnow) {});
430     task->OnDataReceive([](const HttpClientRequest &request, const uint8_t *data, size_t length) {});
431     httpReq = CreateHttpClientRequest(data, size);
432     task = HttpSession::GetInstance().CreateTask(httpReq);
433     type = task->GetType();
434     result = task->GetFilePath();
435     taskId = task->GetTaskId();
436     status = task->GetStatus();
437     task->SetStatus(status);
438 }
439 } // namespace Http
440 } // namespace NetStack
441 } // namespace OHOS
442 
443 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)444 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
445 {
446     /* Run your code on data */
447     OHOS::NetStack::Http::SetCaPathFuzzTest(data, size);
448     OHOS::NetStack::Http::SetUrlFuzzTest(data, size);
449     OHOS::NetStack::Http::SetMethodFuzzTest(data, size);
450     OHOS::NetStack::Http::SetHeaderFuzzTest(data, size);
451     OHOS::NetStack::Http::SetReadTimeoutFuzzTest(data, size);
452     OHOS::NetStack::Http::SetConnectTimeoutFuzzTest(data, size);
453     OHOS::NetStack::Http::SetUsingProtocolFuzzTest(data, size);
454     OHOS::NetStack::Http::SetHttpDataTypeFuzzTest(data, size);
455     OHOS::NetStack::Http::SetUsingHttpProxyTypeFuzzTest(data, size);
456     OHOS::NetStack::Http::SetSpecifiedHttpProxyFuzzTest(data, size);
457     OHOS::NetStack::Http::SetDnsServersFuzzTest(data, size);
458     OHOS::NetStack::Http::SetDohUrlFuzzTest(data, size);
459     OHOS::NetStack::Http::SetRangeNumberFuzzTest(data, size);
460     OHOS::NetStack::Http::SetClientCertFuzzTest(data, size);
461     OHOS::NetStack::Http::AddMultiFormDataFuzzTest(data, size);
462     OHOS::NetStack::Http::HttpSessionCreateTaskFuzzTest(data, size);
463     OHOS::NetStack::Http::HttpClientTaskGetHttpVersionFuzzTest(data, size);
464     OHOS::NetStack::Http::HttpClientTaskSetHttpProtocolFuzzTest(data, size);
465     OHOS::NetStack::Http::HttpClientTaskSetOtherCurlOptionFuzzTest(data, size);
466     OHOS::NetStack::Http::HttpClientTaskSetCurlOptionsFuzzTest(data, size);
467     OHOS::NetStack::Http::HttpClientTaskGetTypeFuzzTest(data, size);
468     return 0;
469 }