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