]> git.stg.codes - stg.git/blob - stglibs/srvconf.lib/netunit.cpp
8d5591934ecbc1afa02a503264d7c96b5eb6b491
[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 "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     memset(login, 0, ADM_LOGIN_LEN);
61     memset(password, 0, ADM_PASSWD_LEN);
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     errorMsg = RECV_HEADER_ANSWER_ERROR;
218     return st_recv_fail;
219     }
220
221 if (strncmp(OK_HEADER, buffer, strlen(OK_HEADER)) == 0)
222     {
223     return st_ok;
224     }
225 else
226     {
227     if (strncmp(ERR_HEADER, buffer, strlen(ERR_HEADER)) == 0)
228         {
229         errorMsg = INCORRECT_HEADER;
230         return st_header_err;
231         }
232     else
233         {
234         errorMsg = UNKNOWN_ERROR;
235         return st_unknown_err;
236         }
237     }
238 }
239 //---------------------------------------------------------------------------
240 int NETTRANSACT::TxLogin()
241 {
242 char loginZ[ADM_LOGIN_LEN];
243 int ret;
244
245 memset(loginZ, 0, ADM_LOGIN_LEN);
246 strncpy(loginZ, login, ADM_LOGIN_LEN);
247 ret = send(outerSocket, loginZ, ADM_LOGIN_LEN, 0);
248
249 if (ret <= 0)
250     {
251     errorMsg = SEND_LOGIN_ERROR;
252     return st_send_fail;
253     }
254
255 return st_ok;
256 }
257 //---------------------------------------------------------------------------
258 int NETTRANSACT::RxLoginAnswer()
259 {
260 char buffer[sizeof(OK_LOGIN)+1];
261 int ret;
262
263 ret = recv(outerSocket, buffer, strlen(OK_LOGIN), 0);
264 if (ret <= 0)
265     {
266     errorMsg = RECV_LOGIN_ANSWER_ERROR;
267     return st_recv_fail;
268     }
269
270 if (strncmp(OK_LOGIN, buffer, strlen(OK_LOGIN)) == 0)
271     {
272     return st_ok;
273     }
274 else
275     {
276     if (strncmp(ERR_LOGIN, buffer, strlen(ERR_LOGIN)) == 0)
277         {
278         errorMsg = INCORRECT_LOGIN;
279         return st_login_err;
280         }
281     else
282         {
283         errorMsg = UNKNOWN_ERROR;
284         return st_unknown_err;
285         }
286     }
287 }
288 //---------------------------------------------------------------------------
289 int NETTRANSACT::TxLoginS()
290 {
291 char loginZ[ADM_LOGIN_LEN];
292 char ct[ENC_MSG_LEN];
293 int ret;
294
295 memset(loginZ, 0, ADM_LOGIN_LEN);
296 strncpy(loginZ, login, ADM_LOGIN_LEN);
297
298 BLOWFISH_CTX ctx;
299 EnDecryptInit(password, PASSWD_LEN, &ctx);
300
301 for (int j = 0; j < ADM_LOGIN_LEN / ENC_MSG_LEN; j++)
302     {
303     Encrypt(ct, loginZ + j*ENC_MSG_LEN, &ctx);
304     ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
305     if (ret <= 0)
306         {
307         errorMsg = SEND_LOGIN_ERROR;
308         return st_send_fail;
309         }
310     }
311
312 return st_ok;
313 }
314 //---------------------------------------------------------------------------
315 int NETTRANSACT::RxLoginSAnswer()
316 {
317 char buffer[sizeof(OK_LOGINS)+1];
318 int ret;
319
320 ret = recv(outerSocket, buffer, strlen(OK_LOGINS), 0);
321 if (ret <= 0)
322     {
323     errorMsg = RECV_LOGIN_ANSWER_ERROR;
324     return st_recv_fail;
325     }
326
327 if (strncmp(OK_LOGINS, buffer, strlen(OK_LOGINS)) == 0)
328     {
329     return st_ok;
330     }
331 else
332     {
333     if (strncmp(ERR_LOGINS, buffer, strlen(ERR_LOGINS)) == 0)
334         {
335         errorMsg = INCORRECT_LOGIN;
336         return st_logins_err;
337         }
338     else
339         {
340         errorMsg = UNKNOWN_ERROR;
341         return st_unknown_err;
342         }
343     }
344 }
345 //---------------------------------------------------------------------------
346 int NETTRANSACT::TxData(const char * text)
347 {
348 char textZ[ENC_MSG_LEN];
349 char ct[ENC_MSG_LEN];
350 int ret;
351 int j;
352
353 int n = strlen(text) / ENC_MSG_LEN;
354 int r = strlen(text) % ENC_MSG_LEN;
355
356 BLOWFISH_CTX ctx;
357 EnDecryptInit(password, PASSWD_LEN, &ctx);
358
359 for (j = 0; j < n; j++)
360     {
361     strncpy(textZ, text + j*ENC_MSG_LEN, ENC_MSG_LEN);
362     Encrypt(ct, textZ, &ctx);
363     ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
364     if (ret <= 0)
365         {
366         errorMsg = SEND_DATA_ERROR;
367         return st_send_fail;
368         }
369     }
370
371 memset(textZ, 0, ENC_MSG_LEN);
372 if (r)
373     strncpy(textZ, text + j*ENC_MSG_LEN, ENC_MSG_LEN);
374
375 EnDecryptInit(password, PASSWD_LEN, &ctx);
376
377 Encrypt(ct, textZ, &ctx);
378 ret = send(outerSocket, ct, ENC_MSG_LEN, 0);
379 if (ret <= 0)
380     {
381     errorMsg = SEND_DATA_ERROR;
382     return st_send_fail;
383     }
384
385 return st_ok;
386 }
387 //---------------------------------------------------------------------------
388 int NETTRANSACT::TxData(char * data)
389 {
390 char buff[ENC_MSG_LEN];
391 char buffS[ENC_MSG_LEN];
392 char passwd[ADM_PASSWD_LEN];
393
394 memset(passwd, 0, ADM_PASSWD_LEN);
395 strncpy(passwd, password, ADM_PASSWD_LEN);
396 memset(buff, 0, ENC_MSG_LEN);
397
398 int l = strlen(data)/ENC_MSG_LEN;
399 if (strlen(data)%ENC_MSG_LEN)
400     l++;
401
402 BLOWFISH_CTX ctx;
403 EnDecryptInit(passwd, PASSWD_LEN, &ctx);
404
405 for (int j = 0; j < l; j++)
406     {
407     strncpy(buff, &data[j*ENC_MSG_LEN], ENC_MSG_LEN);
408     Encrypt(buffS, buff, &ctx);
409     send(outerSocket, buffS, ENC_MSG_LEN, 0);
410     }
411
412 return 0;
413 }
414 //---------------------------------------------------------------------------
415 int NETTRANSACT::RxDataAnswer()
416 {
417 int n = 0;
418 int ret;
419 char bufferS[ENC_MSG_LEN];
420 char buffer[ENC_MSG_LEN + 1];
421
422 BLOWFISH_CTX ctx;
423 EnDecryptInit(password, PASSWD_LEN, &ctx);
424
425 while (1)
426     {
427     ret = recv(outerSocket, &bufferS[n++], 1, 0);
428     if (ret <= 0)
429         {
430         close(outerSocket);
431         errorMsg = RECV_DATA_ANSWER_ERROR;
432         return st_recv_fail;
433         }
434
435     if (n == ENC_MSG_LEN)
436         {
437
438         n = 0;
439         Decrypt(buffer, bufferS, &ctx);
440         buffer[ENC_MSG_LEN] = 0;
441
442         answerList.push_back(buffer);
443
444         for (int j = 0; j < ENC_MSG_LEN; j++)
445             {
446             if (buffer[j] == 0)
447                 {
448                 if (RxCallBack)
449                     if (st_ok != RxCallBack(dataRxCallBack, &answerList))
450                         {
451                         return st_xml_parse_error;
452                         }
453                 return st_ok;
454                 }
455             }
456         }
457     }
458 }
459 //---------------------------------------------------------------------------
460 void NETTRANSACT::SetLogin(const char * l)
461 {
462 strncpy(login, l, ADM_LOGIN_LEN);
463 }
464 //---------------------------------------------------------------------------
465 void NETTRANSACT::SetPassword(const char * p)
466 {
467 strncpy(password, p, ADM_PASSWD_LEN);
468 }
469 //---------------------------------------------------------------------------
470 void NETTRANSACT::SetServer(const char * serverName)
471 {
472 server = serverName;
473 }
474 //---------------------------------------------------------------------------
475 void NETTRANSACT::SetServerPort(short unsigned p)
476 {
477 port = p;
478 }
479 //---------------------------------------------------------------------------
480 void NETTRANSACT::SetRxCallback(void * data, RxCallback_t cb)
481 {
482 RxCallBack = cb;
483 dataRxCallBack = data;
484 }
485 //---------------------------------------------------------------------------
486 const std::string & NETTRANSACT::GetError() const
487 {
488 return errorMsg;
489 }
490 //---------------------------------------------------------------------------
491 void NETTRANSACT::Reset()
492 {
493 answerList.clear();
494 }
495 //---------------------------------------------------------------------------