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: 2009/10/31 15:44:02 $
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>
49 #include <sys/errno.h>
53 #include <sys/errno.h>
58 #include "configproto.h"
74 //-----------------------------------------------------------------------------
75 int CONFIGPROTO::Prepare()
77 list<string> ansList; //óÀÄÁ ÂÕÄÅÔ ÐÏÍÅÝÅÎ ÏÔ×ÅÔ ÄÌÑ ÍÅÎÅÄÖÅÒÁ ËÌÉÅÎÔÏ×
79 struct sockaddr_in listenAddr;
81 sigset_t sigmask, oldmask;
82 sigemptyset(&sigmask);
83 sigaddset(&sigmask, SIGINT);
84 sigaddset(&sigmask, SIGTERM);
85 sigaddset(&sigmask, SIGUSR1);
86 sigaddset(&sigmask, SIGHUP);
87 pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
89 listenSocket = socket(PF_INET, SOCK_STREAM, 0);
93 errorStr = "Create NET_CONFIGURATOR socket failed.";
97 listenAddr.sin_family = PF_INET;
98 listenAddr.sin_port = htons(port);
99 listenAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
103 if (0 != setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &lng, 4))
105 errorStr = "Setsockopt failed. " + string(strerror(errno));
109 res = bind(listenSocket, (struct sockaddr*)&listenAddr, sizeof(listenAddr));
113 errorStr = "Bind admin socket failed";
117 res = listen(listenSocket, 0);
120 errorStr = "Listen admin socket failed";
123 outerAddrLen = sizeof(outerAddr);
125 /*if (0 != fcntl(listenSocket, F_SETFL, O_NONBLOCK))
127 errorStr = "fcntl error!";
135 //-----------------------------------------------------------------------------
136 int CONFIGPROTO::Stop()
142 struct sockaddr_in addr;
144 addr.sin_family = PF_INET;
145 addr.sin_port = htons(port);
146 addr.sin_addr.s_addr = inet_addr("127.0.0.1");
148 addrLen = sizeof(outerAddr);
149 sock = socket(PF_INET, SOCK_STREAM, 0);
150 connect(sock, (sockaddr*)&addr, addrLen);
155 //-----------------------------------------------------------------------------
156 // æÕÎËÃÉÑ ÏÂÝÅÎÉÑ Ó ËÏÎÆÉÇÕÒÁÔÏÒÏÍ
157 void * CONFIGPROTO::Run(void * a)
160 * Function Name:ReciveSendConf
161 * Parameters: void * a ÕËÁÚÁÔÅÌØ ÎÁ ÜËÚÅÍÐÌÑÒ ËÌÁÓÓÁ CONFIGPROTO
162 * Description: üÔÁ ÆÕÎËÃÉÑ ÏÂÅÓÐÅÞÉ×ÁÅÔ ÓÅÔÅ×ÏÅ ×ÚÁÉÍÏÄÅÊÓÔ×ÉÅ
163 * Ó íÅÎÅÄÖÅÒÏÍ ëÌÉÅÎÔÏ×. ÷ ÅÅ ÚÁÄÁÞÉ ×ÈÏÄÉÔ: ÐÒÉÅÍ ÚÁÐÒÏÓÏ× ÐÏ TCP/IP
164 * ÉÈ ÒÁÓÛÉÆÒÏ×ËÁ, ÐÅÒÅÄÁÞÁ ÐÒÉÎÑÔÙÈ ÄÁÎÎÙÈ ÁÎÁÌÉÚÁÔÏÒÕ É ÏÔÐÒÁ×ËÁ ÏÔ×ÅÔÁ ÎÁÚÁÄ.
165 * Returns: ×ÏÚ×ÒÁÝÁÅÔ NULL
168 CONFIGPROTO * cp = (CONFIGPROTO*)a;
174 cp->outerSocket = accept(cp->listenSocket,
175 (struct sockaddr*)(&cp->outerAddr),
183 if (cp->outerSocket == -1)
185 printfd(__FILE__, "accept failed\n");
190 cp->adminIP = *(unsigned int*)&(cp->outerAddr.sin_addr);
193 if (!cp->hostAllow->HostAllowed(cp->adminIP))
199 printfd(__FILE__, "Connection accepted from %s\n", inet_ntostring(cp->outerAddr.sin_addr.s_addr).c_str());
201 if (cp->state == confHdr)
203 if (cp->RecvHdr(cp->outerSocket) < 0)
205 close(cp->outerSocket);
208 if (cp->state == confLogin)
210 if (cp->SendHdrAnswer(cp->outerSocket, ans_ok) < 0)
212 close(cp->outerSocket);
216 if (cp->RecvLogin(cp->outerSocket) < 0)
218 close(cp->outerSocket);
222 if (cp->state == confLoginCipher)
224 if (cp->SendLoginAnswer(cp->outerSocket, ans_ok) < 0)
226 close(cp->outerSocket);
229 if (cp->RecvLoginS(cp->outerSocket) < 0)
231 close(cp->outerSocket);
235 if (cp->state == confData)
237 if (cp->SendLoginSAnswer(cp->outerSocket, ans_ok) < 0)
239 close(cp->outerSocket);
242 if (cp->RecvData(cp->outerSocket) < 0)
244 close(cp->outerSocket);
251 if (cp->SendLoginSAnswer(cp->outerSocket, ans_err) < 0)
253 close(cp->outerSocket);
256 cp->WriteLogAccessFailed(cp->adminIP);
261 cp->WriteLogAccessFailed(cp->adminIP);
266 cp->WriteLogAccessFailed(cp->adminIP);
267 if (cp->SendHdrAnswer(cp->outerSocket, ans_err) < 0)
269 close(cp->outerSocket);
276 cp->WriteLogAccessFailed(cp->adminIP);
278 close(cp->outerSocket);
283 //-----------------------------------------------------------------------------
284 int CONFIGPROTO::RecvHdr(int sock)
286 char buf[sizeof(STG_HEADER)];
287 memset(buf, 0, sizeof(STG_HEADER));
289 int stgHdrLen = strlen(STG_HEADER);
290 for (int i = 0; i < stgHdrLen; i++)
292 ret = recv(sock, &buf[i], 1, 0);
300 if (0 == strncmp(buf, STG_HEADER, strlen(STG_HEADER)))
307 SendError("Bad request");
313 //-----------------------------------------------------------------------------
314 int CONFIGPROTO::SendHdrAnswer(int sock, int err)
320 ret = send(sock, ERR_HEADER, sizeof(ERR_HEADER)-1, 0);
323 WriteServLog("send ERR_HEADER error in SendHdrAnswer.");
329 ret = send(sock, OK_HEADER, sizeof(OK_HEADER)-1, 0);
332 WriteServLog("send OK_HEADER error in SendHdrAnswer.");
339 //-----------------------------------------------------------------------------
340 int CONFIGPROTO::RecvLogin(int sock)
342 char login[ADM_LOGIN_LEN+1];
345 memset(login, 0, ADM_LOGIN_LEN + 1);
347 //printfd(__FILE__, "RecvLogin\n");
349 /*for (int i = 0; i < ADM_LOGIN_LEN; i++)
351 ret = recv(sock, &login[i], 1, 0);
361 ret = recv(sock, login, ADM_LOGIN_LEN, 0);
371 if (ret < ADM_LOGIN_LEN)
379 currAdmin = admins->FindAdmin(login);
381 state = confLoginCipher;
384 //-----------------------------------------------------------------------------
385 int CONFIGPROTO::SendLoginAnswer(int sock, int)
389 ret = send(sock, OK_LOGIN, sizeof(OK_LOGIN)-1, 0);
392 WriteServLog("Send OK_LOGIN error in SendLoginAnswer.");
397 //-----------------------------------------------------------------------------
398 int CONFIGPROTO::RecvLoginS(int sock)
400 char loginS[ADM_LOGIN_LEN + 1];
401 char login[ADM_LOGIN_LEN + 1];
404 memset(loginS, 0, ADM_LOGIN_LEN + 1);
406 //printfd(__FILE__, "RecvLoginS\n");
408 /*for (int i = 0; i < ADM_LOGIN_LEN; i++)
410 ret = recv(sock, &loginS[i], 1, 0);
414 //printfd(__FILE__, "RecvLoginS close\n");
423 while (total < ADM_LOGIN_LEN)
425 ret = recv(sock, &loginS[total], ADM_LOGIN_LEN - total, 0);
430 printfd(__FILE__, "recv error: '%s'\n", strerror(errno));
439 // TODO: implement select on socket
440 /*if (total < ADM_LOGIN_LEN)
443 printfd(__FILE__, "Protocol error. Need %d bytes of cryptologin. Got %d bytes.\n", ADM_LOGIN_LEN, ret);
449 if (currAdmin == NULL)
455 EnDecodeInit(currAdmin->GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
457 for (int i = 0; i < ADM_LOGIN_LEN/8; i++)
459 DecodeString(login + i*8, loginS + i*8, &ctx);
462 if (currAdmin == admins->GetNoAdmin())
464 // If there are no admins registered in the system - give access with any password
469 if (strncmp(currAdmin->GetLogin().c_str(), login, ADM_LOGIN_LEN) != 0)
478 //-----------------------------------------------------------------------------
479 int CONFIGPROTO::SendLoginSAnswer(int sock, int err)
485 ret = send(sock, ERR_LOGINS, sizeof(ERR_LOGINS)-1, 0);
488 WriteServLog("send ERR_LOGIN error in SendLoginAnswer.");
494 ret = send(sock, OK_LOGINS, sizeof(OK_LOGINS)-1, 0);
497 WriteServLog("send OK_LOGINS error in SendLoginSAnswer.");
503 //-----------------------------------------------------------------------------
504 int CONFIGPROTO::RecvData(int sock)
506 //printfd(__FILE__, "RecvData\n");
517 EnDecodeInit(currAdmin->GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
521 /*ret = recv(sock, &bufferS[n++], 1, 0);
524 //printfd(__FILE__, "RecvData close\n");
532 ret = recv(sock, &bufferS[total], 8 - total, 0);
542 if (memchr(buffer, 0, ret) != NULL)
552 DecodeString(buffer, bufferS, &ctx);
553 requestList.push_back(std::string(buffer, total));
555 if (done || memchr(buffer, 0, total) != NULL)
560 SendError("Bad command");
562 return SendDataAnswer(sock);
568 DecodeString(buffer, bufferS, &ctx);
569 requestList.push_back(std::string(buffer, 8));
570 for (int j = 0; j < 8; j++)
577 SendError("Bad command");
579 return SendDataAnswer(sock);
586 //-----------------------------------------------------------------------------
587 int CONFIGPROTO::SendDataAnswer(int sock)
589 list<string>::iterator li;
590 li = answerList.begin();
600 EnDecodeInit(currAdmin->GetPassword().c_str(), ADM_PASSWD_LEN, &ctx);
602 while (li != answerList.end())
604 while ((*li).c_str()[k])
606 buff[n%8] = (*li).c_str()[k];
612 EncodeString(buffS, buff, &ctx);
613 ret = send(sock, buffS, 8, 0);
624 if (answerList.empty()) {
629 EncodeString(buffS, buff, &ctx);
633 return send(sock, buffS, 8, 0);
635 //-----------------------------------------------------------------------------
636 void CONFIGPROTO::SendError(const char * text)
640 sprintf(s, "<Error value=\"%s\"/>", text);
641 answerList.push_back(s);
643 //-----------------------------------------------------------------------------
644 void CONFIGPROTO::WriteLogAccessFailed(uint32_t ip)
646 WriteServLog("Admin's connect failed. IP %s", inet_ntostring(ip).c_str());
648 //-----------------------------------------------------------------------------