· 4 years ago · Apr 09, 2021, 10:10 AM
1#include <iostream>
2#include <vector>
3#include <sstream>
4#include <iomanip>
5#include <new>
6#include <thread>
7#include <vector>
8
9#define CURL_STATICLIB
10
11#include <curl/curl.h>
12
13#include <nlohmann/json.hpp>
14
15#include <Windows.h>
16#include <Iphlpapi.h>
17
18
19#pragma comment(lib, "iphlpapi.lib")
20
21
22static size_t write_callback(void* contents, size_t size, size_t n, void* userp) {
23 (static_cast<std::string*>(userp))->append(static_cast<char*>(contents), size * n);
24 return size * n;
25}
26
27class net_client {
28public:
29 using parameter_pack_t = std::vector<std::pair<std::string, std::string>>;
30
31 std::string post_request(std::string_view method, const parameter_pack_t& postfields) {
32 CURL* curl = curl_easy_init();
33
34 std::string buffer;
35 if (curl) {
36 std::string params = create_parameters(postfields);
37
38 curl_easy_setopt(curl, CURLOPT_POST, 1L);
39 curl_easy_setopt(curl, CURLOPT_URL, method.data());
40 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, params.c_str());
41 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
42 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
43
44 CURLcode res = curl_easy_perform(curl);
45 curl_easy_cleanup(curl);
46
47 if (res != CURLE_OK) {
48 std::string errmsg = "curl error: ";
49 errmsg += curl_easy_strerror(res);
50 throw std::runtime_error(errmsg);
51 }
52 }
53 curl_global_cleanup();
54 return buffer;
55 }
56
57private:
58 std::string url_escape(std::string_view url) {
59 char* encoded = curl_easy_escape(NULL, url.data(), url.length());
60 std::string res{ encoded };
61 curl_free(encoded);
62 return res;
63 }
64
65 std::string create_parameters(const parameter_pack_t& body) {
66 std::string result;
67 for (const auto& [key, value] : body) {
68 result += key;
69 result += '=';
70 result += url_escape(value);
71 result += '&';
72 }
73 if (!result.empty()) {
74 result.pop_back();
75 }
76 return result;
77 }
78};
79
80class hdd_utility {
81public:
82 DWORD get_serial_number() {
83 DWORD VolumeSerialNumber = 0;
84 GetVolumeInformation(L"c:\\", NULL, NULL, &VolumeSerialNumber, NULL, NULL, NULL, NULL);
85 return VolumeSerialNumber;
86 }
87};
88
89class mac_utility {
90public:
91 std::vector<std::string> get_mac() {
92 PIP_ADAPTER_INFO AdapterInfo;
93 DWORD dwBufLen = sizeof(IP_ADAPTER_INFO);
94 std::vector<std::string> mac_addresses;
95
96 AdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
97 if (!AdapterInfo) {
98 throw std::runtime_error("Cannot allocate memory for GetAdaptersinfo");
99 }
100
101 if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) {
102 free(AdapterInfo);
103 AdapterInfo = (IP_ADAPTER_INFO*)malloc(dwBufLen);
104 if (!AdapterInfo) {
105 throw std::runtime_error("Cannot allocate memory for GetAdaptersinfo");
106 }
107 }
108
109 if (GetAdaptersInfo(AdapterInfo, &dwBufLen) == NO_ERROR) {
110 PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;
111 std::ostringstream ss;
112 do {
113 for (size_t i = 0; i < 6; i++) {
114 ss << std::setw(2) << std::setfill('0') << std::hex <<
115 static_cast<int>(AdapterInfo->Address[i]);
116 if (i < 5) {
117 ss << ':';
118 }
119 }
120 mac_addresses.emplace_back(std::string(ss.str()));
121 ss.clear();
122 ss.str("");
123
124 pAdapterInfo = pAdapterInfo->Next;
125 } while (pAdapterInfo);
126 }
127 free(AdapterInfo);
128 return mac_addresses;
129 }
130};
131
132class solution {
133public:
134 std::string authorize() {
135 std::string auth_data =
136 client.post_request(testing_url, { {"action", "auth"} });
137 nlohmann::json json = nlohmann::json::parse(auth_data);
138 return json["data"]["key"];
139 }
140
141 std::string get_secret(std::string_view key) {
142 std::string secret_data = client.post_request(testing_url, {
143 {"action", "getSecret"}, {"key", key.data()}
144 });
145 nlohmann::json secret_key_object = nlohmann::json::parse(secret_data);
146 bool is_success = secret_key_object["success"];
147
148 if (is_success) {
149 return secret_key_object["data"]["secret"];
150 }
151 else {
152 std::string errmsg = secret_key_object["data"]["message"];
153 throw std::runtime_error("error: " + errmsg);
154 }
155 }
156
157private:
158 static inline const std::string_view testing_url = "https://testing.burosd.ru/cpp/1/?";
159 net_client client;
160};
161
162
163
164class solution2 {
165public:
166 void run() {
167 while (true) {
168 std::string hdd_serial_number = std::to_string(hdd_util.get_serial_number());
169 std::vector<std::string> mac_addresses = mac_util.get_mac();
170
171 for (auto&& address : mac_addresses) {
172 std::string response = client.post_request("https://testing.burosd.ru/cpp/2/?", {
173 {"action", "track"},
174 {"mac", address},
175 {"serial_disk", hdd_serial_number}
176 });
177 nlohmann::json parsed_object = nlohmann::json::parse(response);
178 std::cout << parsed_object["data"]["message"] << std::endl;
179 }
180 using namespace std::chrono_literals;
181 std::this_thread::sleep_for(30s);
182 }
183 }
184
185private:
186 hdd_utility hdd_util;
187 mac_utility mac_util;
188
189 net_client client;
190};
191
192int main() {
193 std::cout << "\tSolution1: " << std::endl;
194 solution client;
195 std::string auth_key = client.authorize();
196 std::string secret_key = client.get_secret(auth_key);
197
198 std::cout << "auth key: " << auth_key << std::endl;
199 std::cout << "secret key: " << secret_key << std::endl;
200
201 std::cout << "\tSolution2: " << std::endl;
202 solution2 s2;
203 s2.run();
204 return 0;
205}