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