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.
 
   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.
 
  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
 
  18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
 
  23  $Date: 2009/02/06 10:25:54 $
 
  27 //---------------------------------------------------------------------------
 
  31 #include "stg/servconf_types.h"
 
  32 #include "stg/common.h"
 
  33 #include "stg/blowfish.h"
 
  40 #include <arpa/inet.h>
 
  43 #include <sys/types.h>
 
  44 #include <sys/socket.h>
 
  45 #include <netinet/in.h>
 
  52 const std::string::size_type MAX_XML_CHUNK_LENGTH = 2048;
 
  56 //---------------------------------------------------------------------------
 
  58 #define SEND_DATA_ERROR             "Send data error!"
 
  59 #define RECV_DATA_ANSWER_ERROR      "Recv data answer error!"
 
  60 #define UNKNOWN_ERROR               "Unknown error!"
 
  61 #define CONNECT_FAILED              "Connect failed!"
 
  62 #define INCORRECT_LOGIN             "Incorrect login!"
 
  63 #define INCORRECT_HEADER            "Incorrect header!"
 
  64 #define SEND_LOGIN_ERROR            "Send login error!"
 
  65 #define RECV_LOGIN_ANSWER_ERROR     "Recv login answer error!"
 
  66 #define CREATE_SOCKET_ERROR         "Create socket failed!"
 
  67 #define WSASTARTUP_FAILED           "WSAStartup failed!"
 
  68 #define SEND_HEADER_ERROR           "Send header error!"
 
  69 #define RECV_HEADER_ANSWER_ERROR    "Recv header answer error!"
 
  71 //---------------------------------------------------------------------------
 
  72 NETTRANSACT::NETTRANSACT(const std::string & s, uint16_t p,
 
  73                          const std::string & l, const std::string & pwd)
 
  81 //---------------------------------------------------------------------------
 
  82 int NETTRANSACT::Connect()
 
  84 outerSocket = socket(PF_INET, SOCK_STREAM, 0);
 
  87     errorMsg = CREATE_SOCKET_ERROR;
 
  91 struct sockaddr_in outerAddr;
 
  92 memset(&outerAddr, 0, sizeof(outerAddr));
 
  94 unsigned long ip = inet_addr(server.c_str());
 
  96 if (ip == INADDR_NONE)
 
  98     struct hostent * phe = gethostbyname(server.c_str());
 
 101         errorMsg = "DNS error.\nCan not reslove " + server;
 
 106     memcpy(&he, phe, sizeof(he));
 
 107     ip = *((long *)he.h_addr_list[0]);
 
 110 outerAddr.sin_family = AF_INET;
 
 111 outerAddr.sin_port = htons(port);
 
 112 outerAddr.sin_addr.s_addr = ip;
 
 114 if (connect(outerSocket, (struct sockaddr *)&outerAddr, sizeof(outerAddr)) < 0)
 
 116     errorMsg = CONNECT_FAILED;
 
 123 //---------------------------------------------------------------------------
 
 124 void NETTRANSACT::Disconnect()
 
 128 //---------------------------------------------------------------------------
 
 129 int NETTRANSACT::Transact(const char * request, CALLBACK callback, void * data)
 
 132 if ((ret = TxHeader()) != st_ok)
 
 138 if ((ret = RxHeaderAnswer()) != st_ok)
 
 144 if ((ret = TxLogin()) != st_ok)
 
 150 if ((ret = RxLoginAnswer()) != st_ok)
 
 156 if ((ret = TxLoginS()) != st_ok)
 
 162 if ((ret = RxLoginSAnswer()) != st_ok)
 
 168 if ((ret = TxData(request)) != st_ok)
 
 174 if ((ret = RxDataAnswer(callback, data)) != st_ok)
 
 182 //---------------------------------------------------------------------------
 
 183 int NETTRANSACT::TxHeader()
 
 185 if (send(outerSocket, STG_HEADER, strlen(STG_HEADER), 0) <= 0)
 
 187     errorMsg = SEND_HEADER_ERROR;
 
 193 //---------------------------------------------------------------------------
 
 194 int NETTRANSACT::RxHeaderAnswer()
 
 196 char buffer[sizeof(STG_HEADER) + 1];
 
 198 if (recv(outerSocket, buffer, strlen(OK_HEADER), 0) <= 0)
 
 200     printf("Receive header answer error: '%s'\n", strerror(errno));
 
 201     errorMsg = RECV_HEADER_ANSWER_ERROR;
 
 205 if (strncmp(OK_HEADER, buffer, strlen(OK_HEADER)) == 0)
 
 211     if (strncmp(ERR_HEADER, buffer, strlen(ERR_HEADER)) == 0)
 
 213         errorMsg = INCORRECT_HEADER;
 
 214         return st_header_err;
 
 218         errorMsg = UNKNOWN_ERROR;
 
 219         return st_unknown_err;
 
 223 //---------------------------------------------------------------------------
 
 224 int NETTRANSACT::TxLogin()
 
 226 char loginZ[ADM_LOGIN_LEN];
 
 227 memset(loginZ, 0, ADM_LOGIN_LEN);
 
 228 strncpy(loginZ, login.c_str(), ADM_LOGIN_LEN);
 
 230 if (send(outerSocket, loginZ, ADM_LOGIN_LEN, 0) <= 0)
 
 232     errorMsg = SEND_LOGIN_ERROR;
 
 238 //---------------------------------------------------------------------------
 
 239 int NETTRANSACT::RxLoginAnswer()
 
 241 char buffer[sizeof(OK_LOGIN) + 1];
 
 243 if (recv(outerSocket, buffer, strlen(OK_LOGIN), 0) <= 0)
 
 245     printf("Receive login answer error: '%s'\n", strerror(errno));
 
 246     errorMsg = RECV_LOGIN_ANSWER_ERROR;
 
 250 if (strncmp(OK_LOGIN, buffer, strlen(OK_LOGIN)) == 0)
 
 256     if (strncmp(ERR_LOGIN, buffer, strlen(ERR_LOGIN)) == 0)
 
 258         errorMsg = INCORRECT_LOGIN;
 
 263         errorMsg = UNKNOWN_ERROR;
 
 264         return st_unknown_err;
 
 268 //---------------------------------------------------------------------------
 
 269 int NETTRANSACT::TxLoginS()
 
 271 char loginZ[ADM_LOGIN_LEN];
 
 272 memset(loginZ, 0, ADM_LOGIN_LEN);
 
 273 strncpy(loginZ, login.c_str(), ADM_LOGIN_LEN);
 
 276 EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx);
 
 278 for (int j = 0; j < ADM_LOGIN_LEN / ENC_MSG_LEN; j++)
 
 280     char ct[ENC_MSG_LEN];
 
 281     EncodeString(ct, loginZ + j * ENC_MSG_LEN, &ctx);
 
 282     if (send(outerSocket, ct, ENC_MSG_LEN, 0) <= 0)
 
 284         errorMsg = SEND_LOGIN_ERROR;
 
 291 //---------------------------------------------------------------------------
 
 292 int NETTRANSACT::RxLoginSAnswer()
 
 294 char buffer[sizeof(OK_LOGINS) + 1];
 
 296 if (recv(outerSocket, buffer, strlen(OK_LOGINS), 0) <= 0)
 
 298     printf("Receive secret login answer error: '%s'\n", strerror(errno));
 
 299     errorMsg = RECV_LOGIN_ANSWER_ERROR;
 
 303 if (strncmp(OK_LOGINS, buffer, strlen(OK_LOGINS)) == 0)
 
 309     if (strncmp(ERR_LOGINS, buffer, strlen(ERR_LOGINS)) == 0)
 
 311         errorMsg = INCORRECT_LOGIN;
 
 312         return st_logins_err;
 
 316         errorMsg = UNKNOWN_ERROR;
 
 317         return st_unknown_err;
 
 321 //---------------------------------------------------------------------------
 
 322 int NETTRANSACT::TxData(const char * text)
 
 324 int n = strlen(text) / ENC_MSG_LEN;
 
 325 int r = strlen(text) % ENC_MSG_LEN;
 
 328 EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx);
 
 330 char textZ[ENC_MSG_LEN];
 
 331 char ct[ENC_MSG_LEN];
 
 333 for (int j = 0; j < n; j++)
 
 335     strncpy(textZ, text + j * ENC_MSG_LEN, ENC_MSG_LEN);
 
 336     EncodeString(ct, textZ, &ctx);
 
 337     if (send(outerSocket, ct, ENC_MSG_LEN, 0) <= 0)
 
 339         errorMsg = SEND_DATA_ERROR;
 
 344 memset(textZ, 0, ENC_MSG_LEN);
 
 347     strncpy(textZ, text + n * ENC_MSG_LEN, ENC_MSG_LEN);
 
 349 EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx);
 
 351 EncodeString(ct, textZ, &ctx);
 
 352 if (send(outerSocket, ct, ENC_MSG_LEN, 0) <= 0)
 
 354     errorMsg = SEND_DATA_ERROR;
 
 360 //---------------------------------------------------------------------------
 
 361 int NETTRANSACT::TxData(char * data)
 
 363 char passwd[ADM_PASSWD_LEN];
 
 364 memset(passwd, 0, ADM_PASSWD_LEN);
 
 365 strncpy(passwd, password.c_str(), ADM_PASSWD_LEN);
 
 367 char buff[ENC_MSG_LEN];
 
 368 memset(buff, 0, ENC_MSG_LEN);
 
 370 int l = strlen(data) / ENC_MSG_LEN;
 
 371 if (strlen(data) % ENC_MSG_LEN)
 
 375 EnDecodeInit(passwd, PASSWD_LEN, &ctx);
 
 377 for (int j = 0; j < l; j++)
 
 379     strncpy(buff, &data[j * ENC_MSG_LEN], ENC_MSG_LEN);
 
 380     char buffS[ENC_MSG_LEN];
 
 381     EncodeString(buffS, buff, &ctx);
 
 382     send(outerSocket, buffS, ENC_MSG_LEN, 0);
 
 387 //---------------------------------------------------------------------------
 
 388 int NETTRANSACT::RxDataAnswer(CALLBACK callback, void * data)
 
 391 EnDecodeInit(password.c_str(), PASSWD_LEN, &ctx);
 
 396     char bufferS[ENC_MSG_LEN];
 
 397     size_t toRead = ENC_MSG_LEN;
 
 400         int ret = recv(outerSocket, &bufferS[ENC_MSG_LEN - toRead], toRead, 0);
 
 403             printf("Receive data error: '%s'\n", strerror(errno));
 
 405             errorMsg = RECV_DATA_ANSWER_ERROR;
 
 411     char buffer[ENC_MSG_LEN];
 
 412     DecodeString(buffer, bufferS, &ctx);
 
 416     for (; pos < ENC_MSG_LEN && buffer[pos] != 0; pos++) ;
 
 417     if (pos < ENC_MSG_LEN && buffer[pos] == 0)
 
 421         chunk.append(&buffer[0], &buffer[pos]);
 
 423     if (chunk.length() > MAX_XML_CHUNK_LENGTH || final)
 
 426             if (!callback(chunk, final, data))
 
 427                 return st_xml_parse_error;