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