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
17 /*******************************************************************
19 * DESCRIPTION: æÁÊÌ Ó ÏÓÎÏ×ÎÙÍÉ ÆÕÎËÃÉÑÍÉ ÄÌÑ ÓÅÔÅ×ÏÇÏ ÏÂÍÅÎÁ ÄÁÎÎÙÍÉ
20 * Ó ÍÅÎÅÄÖÅÒÏÍ ËÌÉÅÎÔÏ×. ðÒÉÅÍ, ÐÅÒÅÄÁÞÁ É ÛÉÆÒÏ×ÁÎÉÅ ÓÏÏÂÝÅÎÉÊ.
22 * AUTHOR: Boris Mikhailenko <stg34@stargazer.dp.ua>
25 * $Date: 2010/10/04 20:24:54 $
27 *******************************************************************/
31 #include <netinet/in.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <arpa/inet.h>
35 #include <netinet/tcp.h>
36 #include <netinet/in.h>
41 #include <pthread.h>*/
46 #include "configproto.h"
63 //-----------------------------------------------------------------------------
64 int CONFIGPROTO::Prepare()
66 list<string> ansList; //óÀÄÁ ÂÕÄÅÔ ÐÏÍÅÝÅÎ ÏÔ×ÅÔ ÄÌÑ ÍÅÎÅÄÖÅÒÁ ËÌÉÅÎÔÏ×
68 struct sockaddr_in listenAddr;
70 sigset_t sigmask, oldmask;
71 sigemptyset(&sigmask);
72 sigaddset(&sigmask, SIGINT);
73 sigaddset(&sigmask, SIGTERM);
74 sigaddset(&sigmask, SIGUSR1);
75 sigaddset(&sigmask, SIGHUP);
76 pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
78 listenSocket = socket(PF_INET, SOCK_STREAM, 0);
82 errorStr = "Create NET_CONFIGURATOR socket failed.";
86 listenAddr.sin_family = PF_INET;
87 listenAddr.sin_port = htons(port);
88 listenAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
92 if (0 != setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &lng, 4))
94 errorStr = "Setsockopt failed. " + string(strerror(errno));
98 res = bind(listenSocket, (struct sockaddr*)&listenAddr, sizeof(listenAddr));
102 errorStr = "Bind admin socket failed";
106 res = listen(listenSocket, 0);
109 errorStr = "Listen admin socket failed";
112 outerAddrLen = sizeof(outerAddr);
114 /*if (0 != fcntl(listenSocket, F_SETFL, O_NONBLOCK))
116 errorStr = "fcntl error!";
124 //-----------------------------------------------------------------------------
125 int CONFIGPROTO::Stop()
131 struct sockaddr_in addr;
133 addr.sin_family = PF_INET;
134 addr.sin_port = htons(port);
135 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
137 addrLen = sizeof(outerAddr);
138 sock = socket(PF_INET, SOCK_STREAM, 0);
139 connect(sock, (sockaddr*)&addr, addrLen);
144 //-----------------------------------------------------------------------------
145 // æÕÎËÃÉÑ ÏÂÝÅÎÉÑ Ó ËÏÎÆÉÇÕÒÁÔÏÒÏÍ
146 void * CONFIGPROTO::Run(void * a)
149 * Function Name:ReciveSendConf
150 * Parameters: void * a ÕËÁÚÁÔÅÌØ ÎÁ ÜËÚÅÍÐÌÑÒ ËÌÁÓÓÁ CONFIGPROTO
151 * Description: üÔÁ ÆÕÎËÃÉÑ ÏÂÅÓÐÅÞÉ×ÁÅÔ ÓÅÔÅ×ÏÅ ×ÚÁÉÍÏÄÅÊÓÔ×ÉÅ
152 * Ó íÅÎÅÄÖÅÒÏÍ ëÌÉÅÎÔÏ×. ÷ ÅÅ ÚÁÄÁÞÉ ×ÈÏÄÉÔ: ÐÒÉÅÍ ÚÁÐÒÏÓÏ× ÐÏ TCP/IP
153 * ÉÈ ÒÁÓÛÉÆÒÏ×ËÁ, ÐÅÒÅÄÁÞÁ ÐÒÉÎÑÔÙÈ ÄÁÎÎÙÈ ÁÎÁÌÉÚÁÔÏÒÕ É ÏÔÐÒÁ×ËÁ ÏÔ×ÅÔÁ ÎÁÚÁÄ.
154 * Returns: ×ÏÚ×ÒÁÝÁÅÔ NULL
157 CONFIGPROTO * cp = (CONFIGPROTO*)a;
163 cp->outerSocket = accept(cp->listenSocket,
164 (struct sockaddr*)(&cp->outerAddr),
172 if (cp->outerSocket == -1)
174 printfd(__FILE__, "accept failed\n");
179 cp->adminIP = *(unsigned int*)&(cp->outerAddr.sin_addr);
182 if (!cp->hostAllow->HostAllowed(cp->adminIP))
188 printfd(__FILE__, "Connection accepted from %s\n", inet_ntostring(cp->outerAddr.sin_addr.s_addr).c_str());
190 if (cp->state == confHdr)
192 if (cp->RecvHdr(cp->outerSocket) < 0)
194 close(cp->outerSocket);
197 if (cp->state == confLogin)
199 if (cp->SendHdrAnswer(cp->outerSocket, ans_ok) < 0)
201 close(cp->outerSocket);
205 if (cp->RecvLogin(cp->outerSocket) < 0)
207 close(cp->outerSocket);
211 if (cp->state == confLoginCipher)
213 if (cp->SendLoginAnswer(cp->outerSocket, ans_ok) < 0)
215 close(cp->outerSocket);
218 if (cp->RecvLoginS(cp->outerSocket) < 0)
220 close(cp->outerSocket);
224 if (cp->state == confData)
226 if (cp->SendLoginSAnswer(cp->outerSocket, ans_ok) < 0)
228 close(cp->outerSocket);
231 if (cp->RecvData(cp->outerSocket) < 0)
233 close(cp->outerSocket);
240 if (cp->SendLoginSAnswer(cp->outerSocket, ans_err) < 0)
242 close(cp->outerSocket);
245 cp->WriteLogAccessFailed(cp->adminIP);
250 cp->WriteLogAccessFailed(cp->adminIP);
255 cp->WriteLogAccessFailed(cp->adminIP);
256 if (cp->SendHdrAnswer(cp->outerSocket, ans_err) < 0)
258 close(cp->outerSocket);
265 cp->WriteLogAccessFailed(cp->adminIP);
267 close(cp->outerSocket);
272 //-----------------------------------------------------------------------------
273 int CONFIGPROTO::RecvHdr(int sock)
275 char buf[sizeof(STG_HEADER)];
276 memset(buf, 0, sizeof(STG_HEADER));
278 int stgHdrLen = strlen(STG_HEADER);
279 for (int i = 0; i < stgHdrLen; i++)
281 ret = recv(sock, &buf[i], 1, 0);
289 if (0 == strncmp(buf, STG_HEADER, strlen(STG_HEADER)))
296 SendError("Bad request");
302 //-----------------------------------------------------------------------------
303 int CONFIGPROTO::SendHdrAnswer(int sock, int err)
309 ret = send(sock, ERR_HEADER, sizeof(ERR_HEADER)-1, 0);
312 WriteServLog("send ERR_HEADER error in SendHdrAnswer.");
318 ret = send(sock, OK_HEADER, sizeof(OK_HEADER)-1, 0);
321 WriteServLog("send OK_HEADER error in SendHdrAnswer.");
328 //-----------------------------------------------------------------------------
329 int CONFIGPROTO::RecvLogin(int sock)
331 char login[ADM_LOGIN_LEN+1];
334 memset(login, 0, ADM_LOGIN_LEN + 1);
336 //printfd(__FILE__, "RecvLogin\n");
338 /*for (int i = 0; i < ADM_LOGIN_LEN; i++)
340 ret = recv(sock, &login[i], 1, 0);
350 ret = recv(sock, login, ADM_LOGIN_LEN, 0);
360 if (ret < ADM_LOGIN_LEN)
368 if (admins->FindAdmin(login, &currAdmin))
375 currAdmin.SetAdminIP(adminIP);
377 state = confLoginCipher;
380 //-----------------------------------------------------------------------------
381 int CONFIGPROTO::SendLoginAnswer(int sock, int)
385 ret = send(sock, OK_LOGIN, sizeof(OK_LOGIN)-1, 0);
388 WriteServLog("Send OK_LOGIN error in SendLoginAnswer.");
393 //-----------------------------------------------------------------------------
394 int CONFIGPROTO::RecvLoginS(int sock)
396 char loginS[ADM_LOGIN_LEN + 1];
397 char login[ADM_LOGIN_LEN + 1];
400 memset(loginS, 0, ADM_LOGIN_LEN + 1);
402 //printfd(__FILE__, "RecvLoginS\n");
404 /*for (int i = 0; i < ADM_LOGIN_LEN; i++)
406 ret = recv(sock, &loginS[i], 1, 0);
410 //printfd(__FILE__, "RecvLoginS close\n");
419 while (total < ADM_LOGIN_LEN)
421 ret = recv(sock, &loginS[total], ADM_LOGIN_LEN - total, 0);
426 printfd(__FILE__, "recv error: '%s'\n", strerror(errno));
435 // TODO: implement select on socket
436 /*if (total < ADM_LOGIN_LEN)
439 printfd(__FILE__, "Protocol error. Need %d bytes of cryptologin. Got %d bytes.\n", ADM_LOGIN_LEN, ret);
445 if (currAdmin.GetLogin() == "")
451 EnDecodeInit(currAdmin.GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
453 for (int i = 0; i < ADM_LOGIN_LEN/8; i++)
455 DecodeString(login + i*8, loginS + i*8, &ctx);
458 if (currAdmin == admins->GetNoAdmin())
460 // If there are no admins registered in the system - give access with any password
465 if (strncmp(currAdmin.GetLogin().c_str(), login, ADM_LOGIN_LEN) != 0)
474 //-----------------------------------------------------------------------------
475 int CONFIGPROTO::SendLoginSAnswer(int sock, int err)
481 ret = send(sock, ERR_LOGINS, sizeof(ERR_LOGINS)-1, 0);
484 WriteServLog("send ERR_LOGIN error in SendLoginAnswer.");
490 ret = send(sock, OK_LOGINS, sizeof(OK_LOGINS)-1, 0);
493 WriteServLog("send OK_LOGINS error in SendLoginSAnswer.");
499 //-----------------------------------------------------------------------------
500 int CONFIGPROTO::RecvData(int sock)
502 //printfd(__FILE__, "RecvData\n");
513 EnDecodeInit(currAdmin.GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
517 /*ret = recv(sock, &bufferS[n++], 1, 0);
520 //printfd(__FILE__, "RecvData close\n");
528 ret = recv(sock, &bufferS[total], 8 - total, 0);
538 if (memchr(buffer, 0, ret) != NULL)
548 DecodeString(buffer, bufferS, &ctx);
549 requestList.push_back(std::string(buffer, total));
551 if (done || memchr(buffer, 0, total) != NULL)
556 SendError("Bad command");
558 return SendDataAnswer(sock);
564 DecodeString(buffer, bufferS, &ctx);
565 requestList.push_back(std::string(buffer, 8));
566 for (int j = 0; j < 8; j++)
573 SendError("Bad command");
575 return SendDataAnswer(sock);
582 //-----------------------------------------------------------------------------
583 int CONFIGPROTO::SendDataAnswer(int sock)
585 list<string>::iterator li;
586 li = answerList.begin();
596 EnDecodeInit(currAdmin.GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
598 while (li != answerList.end())
600 while ((*li).c_str()[k])
602 buff[n%8] = (*li).c_str()[k];
608 EncodeString(buffS, buff, &ctx);
609 ret = send(sock, buffS, 8, 0);
620 if (answerList.empty()) {
625 EncodeString(buffS, buff, &ctx);
629 return send(sock, buffS, 8, 0);
631 //-----------------------------------------------------------------------------
632 void CONFIGPROTO::SendError(const char * text)
636 sprintf(s, "<Error value=\"%s\"/>", text);
637 answerList.push_back(s);
639 //-----------------------------------------------------------------------------
640 void CONFIGPROTO::WriteLogAccessFailed(uint32_t ip)
642 WriteServLog("Admin's connect failed. IP %s", inet_ntostring(ip).c_str());
644 //-----------------------------------------------------------------------------