]> git.stg.codes - stg.git/blob - stglibs/srvconf.lib/netunit.cpp
Placeholder added to the XML-RPC API documentation book
[stg.git] / stglibs / srvconf.lib / netunit.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21  /*
22  $Revision: 1.6 $
23  $Date: 2009/02/06 10:25:54 $
24  $Author: faust $
25  */
26
27 //---------------------------------------------------------------------------
28 #include <netdb.h>
29 #include <arpa/inet.h>
30 #include <unistd.h>
31
32 #include <cstdio>
33 #include <cstring>
34
35 #include "netunit.h"
36 #include "stg/common.h"
37
38 //---------------------------------------------------------------------------
39
40 #define SEND_DATA_ERROR             "Send data error!"
41 #define RECV_DATA_ANSWER_ERROR      "Recv data answer error!"
42 #define UNKNOWN_ERROR               "Unknown error!"
43 #define CONNECT_FAILED              "Connect failed!"
44 #define INCORRECT_LOGIN             "Incorrect login!"
45 #define INCORRECT_HEADER            "Incorrect header!"
46 #define SEND_LOGIN_ERROR            "Send login error!"
47 #define RECV_LOGIN_ANSWER_ERROR     "Recv login answer error!"
48 #define CREATE_SOCKET_ERROR         "Create socket failed!"
49 #define WSASTARTUP_FAILED           "WSAStartup failed!"
50 #define SEND_HEADER_ERROR           "Send header error!"
51 #define RECV_HEADER_ANSWER_ERROR    "Recv header answer error!"
52
53 //---------------------------------------------------------------------------
54 NETTRANSACT::NETTRANSACT()
55     : port(0),
56       outerSocket(-1),
57       RxCallBack(NULL),
58       dataRxCallBack(NULL)
59 {
60 }
61 //-----------------------------------------------------------------------------
62 void NETTRANSACT::EnDecryptInit(const char * passwd, int, BLOWFISH_CTX *ctx)
63 {
64 unsigned char * keyL = NULL;
65
66 keyL = new unsigned char[PASSWD_LEN];
67
68 memset(keyL, 0, PASSWD_LEN);
69
70 strncpy((char *)keyL, passwd, PASSWD_LEN);
71
72 Blowfish_Init(ctx, keyL, PASSWD_LEN);
73
74 delete[] keyL;
75 }
76 //-----------------------------------------------------------------------------
77 void NETTRANSACT::Encrypt(char * d, const char * s, BLOWFISH_CTX *ctx)
78 {
79 EncodeString(d, s, ctx);
80 }
81 //---------------------------------------------------------------------------
82 void NETTRANSACT::Decrypt(char * d, const char * s, BLOWFISH_CTX *ctx)
83 {
84 DecodeString(d, s, ctx);
85 }
86 //---------------------------------------------------------------------------
87 int NETTRANSACT::Connect()
88 {
89 int ret;
90
91 outerSocket = socket(PF_INET, SOCK_STREAM, 0);
92 if (outerSocket < 0)
93     {
94     errorMsg = CREATE_SOCKET_ERROR;
95     return st_conn_fail;
96     }
97
98 struct sockaddr_in outerAddr;
99 memset(&outerAddr, 0, sizeof(outerAddr));
100
101 struct hostent he;
102 struct hostent * phe;
103
104 unsigned long ip;
105 ip = inet_addr(server.c_str());
106
107 if (ip == INADDR_NONE)
108     {
109     phe = gethostbyname(server.c_str());
110     if (phe == NULL)
111         {
112         errorMsg = "DNS error.\nCan not reslove " + server;
113         return st_dns_err;
114         }
115
116     memcpy(&he, phe, sizeof(he));
117     ip = *((long*)he.h_addr_list[0]);
118     }
119 outerAddr.sin_family = AF_INET;
120 outerAddr.sin_port = htons(port);
121 outerAddr.sin_addr.s_addr = ip;
122
123 ret = connect(outerSocket, (struct sockaddr*)&outerAddr, sizeof(outerAddr));
124
125 if (ret < 0)
126     {
127     errorMsg = CONNECT_FAILED;
128     close(outerSocket);
129     return st_conn_fail;
130     }
131 return st_ok;
132 }
133 //---------------------------------------------------------------------------
134 int NETTRANSACT::Disconnect()
135 {
136 close(outerSocket);
137 return 0;
138 }
139 //---------------------------------------------------------------------------
140 int NETTRANSACT::Transact(const char * data)
141 {
142 int ret;
143 if ((ret = TxHeader()) != st_ok)
144     {
145     Disconnect();
146     return ret;
147     }
148
149 if ((ret = RxHeaderAnswer()) != st_ok)
150     {
151     Disconnect();
152     return ret;
153     }
154
155 if ((ret = TxLogin()) != st_ok)
156     {
157     Disconnect();
158     return ret;
159     }
160
161 if ((ret = RxLoginAnswer()) != st_ok)
162     {
163     Disconnect();
164     return ret;
165     }
166
167 if ((ret = TxLoginS()) != st_ok)
168     {
169     Disconnect();
170     return ret;
171     }
172
173 if ((ret = RxLoginSAnswer()) != st_ok)
174     {
175     Disconnect();
176     return ret;
177     }
178
179 if ((ret = TxData(data)) != st_ok)
180     {
181     Disconnect();
182     return ret;
183     }
184
185 if ((ret = RxDataAnswer()) != st_ok)
186     {
187     Disconnect();
188     return ret;
189     }
190
191 return st_ok;
192 }
193 //---------------------------------------------------------------------------
194 int NETTRANSACT::TxHeader()
195 {
196 int ret;
197 ret = send(outerSocket, STG_HEADER, strlen(STG_HEADER), 0);
198 if (ret <= 0)
199     {
200     errorMsg = SEND_HEADER_ERROR;
201     return st_send_fail;
202     }
203
204 return st_ok;
205 }
206 //---------------------------------------------------------------------------
207 int NETTRANSACT::RxHeaderAnswer()
208 {
209 char buffer[sizeof(STG_HEADER)+1];
210 int ret;
211
212 ret = recv(outerSocket, buffer, strlen(OK_HEADER), 0);
213 if (ret <= 0)
214     {
215     errorMsg = RECV_HEADER_ANSWER_ERROR;
216     return st_recv_fail;
217     }
218
219 if (strncmp(OK_HEADER, buffer, strlen(OK_HEADER)) == 0)
220     {
221     return st_ok;
222     }
223 else
224     {
225     if (strncmp(ERR_HEADER, buffer, strlen(ERR_HEADER)) == 0)
226         {
227         errorMsg = INCORRECT_HEADER;
228         return st_header_err;
229         }
230     else
231         {
232         errorMsg = UNKNOWN_ERROR;
233         return st_unknown_err;
234         }
235     }
236 }
237 //---------------------------------------------------------------------------
238 int NETTRANSACT::TxLogin()
239 {
240 char loginZ[ADM_LOGIN_LEN];
241 int ret;
242
243 memset(loginZ, 0, ADM_LOGIN_LEN);
244 strncpy(loginZ, login.c_str(), ADM_LOGIN_LEN);
245 ret = send(outerSocket, loginZ, ADM_LOGIN_LEN, 0);
246
247 if (ret <= 0)
248     {
249     errorMsg = SEND_LOGIN_ERROR;
250     return st_send_fail;
251     }
252
253 return st_ok;
254 }
255 //---------------------------------------------------------------------------
256 int NETTRANSACT::RxLoginAnswer()
257 {
258 char buffer[sizeof(OK_LOGIN)+1];
259 int ret;
260
261 ret = recv(outerSocket, buffer, strlen(OK_LOGIN), 0);
262 if (ret <= 0)
263     {
264     errorMsg = RECV_LOGIN_ANSWER_ERROR;
265     return st_recv_fail;
266     }
267
268 if (strncmp(OK_LOGIN, buffer, strlen(OK_LOGIN)) == 0)
269     {
270     return st_ok;
271     }
272 else
273     {
274     if (strncmp(ERR_LOGIN, buffer, strlen(ERR_LOGIN)) == 0)
275         {
276         errorMsg = INCORRECT_LOGIN;
277         return st_login_err;
278         }
279     else
280         {
281         errorMsg = UNKNOWN_ERROR;
282         return st_unknown_err;
283         }
284     }
285 }
286 //---------------------------------------------------------------------------
287 int NETTRANSACT::TxLoginS()
288 {
289 char loginZ[ADM_LOGIN_LEN];
290 char ct[ENC_MSG_LEN];
291 int ret;
292
293 memset(loginZ, 0, ADM_LOGIN_LEN);
294 strncpy(loginZ, login.c_str(), ADM_LOGIN_LEN);
295
296 BLOWFISH_CTX ctx;
297 EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
298
299 for (int j = 0; j < ADM_LOGIN_LEN / ENC_MSG_LEN; j++)
300     {
301     Encrypt(ct, loginZ + j*ENC_MSG_LEN, &ctx);
302     ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
303     if (ret <= 0)
304         {
305         errorMsg = SEND_LOGIN_ERROR;
306         return st_send_fail;
307         }
308     }
309
310 return st_ok;
311 }
312 //---------------------------------------------------------------------------
313 int NETTRANSACT::RxLoginSAnswer()
314 {
315 char buffer[sizeof(OK_LOGINS)+1];
316 int ret;
317
318 ret = recv(outerSocket, buffer, strlen(OK_LOGINS), 0);
319 if (ret <= 0)
320     {
321     errorMsg = RECV_LOGIN_ANSWER_ERROR;
322     return st_recv_fail;
323     }
324
325 if (strncmp(OK_LOGINS, buffer, strlen(OK_LOGINS)) == 0)
326     {
327     return st_ok;
328     }
329 else
330     {
331     if (strncmp(ERR_LOGINS, buffer, strlen(ERR_LOGINS)) == 0)
332         {
333         errorMsg = INCORRECT_LOGIN;
334         return st_logins_err;
335         }
336     else
337         {
338         errorMsg = UNKNOWN_ERROR;
339         return st_unknown_err;
340         }
341     }
342 }
343 //---------------------------------------------------------------------------
344 int NETTRANSACT::TxData(const char * text)
345 {
346 char textZ[ENC_MSG_LEN];
347 char ct[ENC_MSG_LEN];
348 int ret;
349 int j;
350
351 int n = strlen(text) / ENC_MSG_LEN;
352 int r = strlen(text) % ENC_MSG_LEN;
353
354 BLOWFISH_CTX ctx;
355 EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
356
357 for (j = 0; j < n; j++)
358     {
359     strncpy(textZ, text + j*ENC_MSG_LEN, ENC_MSG_LEN);
360     Encrypt(ct, textZ, &ctx);
361     ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
362     if (ret <= 0)
363         {
364         errorMsg = SEND_DATA_ERROR;
365         return st_send_fail;
366         }
367     }
368
369 memset(textZ, 0, ENC_MSG_LEN);
370 if (r)
371     strncpy(textZ, text + j*ENC_MSG_LEN, ENC_MSG_LEN);
372
373 EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
374
375 Encrypt(ct, textZ, &ctx);
376 ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
377 if (ret <= 0)
378     {
379     errorMsg = SEND_DATA_ERROR;
380     return st_send_fail;
381     }
382
383 return st_ok;
384 }
385 //---------------------------------------------------------------------------
386 int NETTRANSACT::TxData(char * data)
387 {
388 char buff[ENC_MSG_LEN];
389 char buffS[ENC_MSG_LEN];
390 char passwd[ADM_PASSWD_LEN];
391
392 memset(passwd, 0, ADM_PASSWD_LEN);
393 strncpy(passwd, password.c_str(), ADM_PASSWD_LEN);
394 memset(buff, 0, ENC_MSG_LEN);
395
396 int l = strlen(data)/ENC_MSG_LEN;
397 if (strlen(data)%ENC_MSG_LEN)
398     l++;
399
400 BLOWFISH_CTX ctx;
401 EnDecryptInit(passwd, PASSWD_LEN, &ctx);
402
403 for (int j = 0; j < l; j++)
404     {
405     strncpy(buff, &data[j*ENC_MSG_LEN], ENC_MSG_LEN);
406     Encrypt(buffS, buff, &ctx);
407     send(outerSocket, buffS, ENC_MSG_LEN, 0);
408     }
409
410 return 0;
411 }
412 //---------------------------------------------------------------------------
413 int NETTRANSACT::RxDataAnswer()
414 {
415 int n = 0;
416 int ret;
417 char bufferS[ENC_MSG_LEN];
418 char buffer[ENC_MSG_LEN + 1];
419
420 BLOWFISH_CTX ctx;
421 EnDecryptInit(password.c_str(), PASSWD_LEN, &ctx);
422
423 while (1)
424     {
425     ret = recv(outerSocket, &bufferS[n++], 1, 0);
426     if (ret <= 0)
427         {
428         close(outerSocket);
429         errorMsg = RECV_DATA_ANSWER_ERROR;
430         return st_recv_fail;
431         }
432
433     if (n == ENC_MSG_LEN)
434         {
435         n = 0;
436         Decrypt(buffer, bufferS, &ctx);
437         buffer[ENC_MSG_LEN] = 0;
438
439         answerList.push_back(buffer);
440
441         for (int j = 0; j < ENC_MSG_LEN; j++)
442             {
443             if (buffer[j] == 0)
444                 {
445                 if (RxCallBack)
446                     if (st_ok != RxCallBack(dataRxCallBack, &answerList))
447                         {
448                         return st_xml_parse_error;
449                         }
450                 return st_ok;
451                 }
452             }
453         }
454     }
455 }
456 //---------------------------------------------------------------------------
457 void NETTRANSACT::SetLogin(const char * l)
458 {
459 login = l;
460 }
461 //---------------------------------------------------------------------------
462 void NETTRANSACT::SetPassword(const char * p)
463 {
464 password = p;
465 }
466 //---------------------------------------------------------------------------
467 void NETTRANSACT::SetServer(const char * serverName)
468 {
469 server = serverName;
470 }
471 //---------------------------------------------------------------------------
472 void NETTRANSACT::SetServerPort(short unsigned p)
473 {
474 port = p;
475 }
476 //---------------------------------------------------------------------------
477 void NETTRANSACT::SetRxCallback(void * data, RxCallback_t cb)
478 {
479 RxCallBack = cb;
480 dataRxCallBack = data;
481 }
482 //---------------------------------------------------------------------------
483 const std::string & NETTRANSACT::GetError() const
484 {
485 return errorMsg;
486 }
487 //---------------------------------------------------------------------------
488 void NETTRANSACT::Reset()
489 {
490 answerList.clear();
491 }
492 //---------------------------------------------------------------------------