Перейти до

Модификация консольного конфигуратора


Рекомендованные сообщения

Нужно было реализовать перенос неистраченного бесплатного траффика на следующий месяц, а возможности установить freemb в КК не было...

Поэтому решил немного модифицировать КК для того чтобы можно было менять скриптами любые параметры пользователя без перезагрузки сервера.

Изменения заключаются в том, что выкинут код, формирующий запрос к серверу (его проще сформировать в скрипте) и запрос читается из файлика, кодируется и отсылается серверу.

Изменился только файл main.cpp :

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#include "common.h"
#include "netunit.h"

#define FN_LEN          512
#define REQ_STR_LEN    300
char fileName[FN_LEN];

char * ParseServerAddress(char * a);
short int ParseServerPort(const char * p);
char * ParseAdminLogin(char * adm);
char * ParseAdminPassword(char * pass);
char * ParseUser(char * usr);
int CheckLogin(const char * login);
int Process(REQUEST * r);
int CheckParameters(REQUEST * req);
void ParseReply(const char * ans);
void Usage();
void Encode12(char * dst, const char * src, int srcLen);

struct option long_options[] = {
{"server",      1, 0, 's'},  //Server
{"port",        1, 0, 'p'},  //Port
{"admin",       1, 0, 'a'},  //Admin
{"admin_pass",  1, 0, 'w'},  //passWord
{"file",      	1, 0, 'f'},  //File
{0, 0, 0, 0}};


int main (int argc, char **argv) 
{
int c;
int digit_optind = 0;
REQUEST req;
memset(&req, 0, sizeof(req));

while (1)
   {
   int this_option_optind = optind ? optind : 1;
   int option_index = 0;

   c = getopt_long(argc, argv, "s:p:a:w:f:", long_options, &option_index);
   if (c == -1)
       break;

   switch ©
       {
       case 's': //server
           strcpy(req.server, ParseServerAddress(optarg));
           req.serverReq = 1;
           break;
       case 'p': //port
           req.port = ParseServerPort(optarg);
           req.portReq = 1;
           break;
       case 'a': //admin
           strcpy(req.admLogin, ParseAdminLogin(optarg));
           req.admLoginReq = 1;
           break;
       case 'w': //admon password
           strcpy(req.admPasswd, ParseAdminPassword(optarg));
           req.admPasswdReq = 1;
           break;
       case 'f': //file
           strcpy(fileName,optarg);
           break;
       case '?':
           //printf ("Unknown option \n");
           break;
       default:
           printf ("?? getopt returned character code 0%o ??\n", c);
       }
   }

if (optind < argc)
   {
   printf ("non-option ARGV-elements: ");
   while (optind < argc)
       printf ("%s ", argv[optind++]);
   printf ("\n");
   exit(PARAMETER_PARSING_ERR_CODE);
   }

if (CheckParameters(&req) == 0)
   {
   //printf("Parameter needed\n");
   Usage();
   exit(PARAMETER_PARSING_ERR_CODE);
   }

Process(&req);

return 0;
}
//-----------------------------------------------------------------------------
char * ParseServerAddress(char * a)
{
/*long int addr = inet_addr(a);

if(INADDR_NONE == addr)
   {
   printf("Incorrect server address %s\n", a);
   exit(NETWORK_ERR_CODE);
   }*/
if (strlen(a) >= SERVER_NAME_LEN)
   {
   printf("Server name too long %s\n", a);
   exit(PARAMETER_PARSING_ERR_CODE);
   }

return a;
}
//-----------------------------------------------------------------------------
short int ParseServerPort(const char * p)
{
int port;
if (strtoi2(p, port) != 0)
   {
   printf("Incorresct server port %s\n", p);
   exit(NETWORK_ERR_CODE);
   }
return (short)port;
}
//-----------------------------------------------------------------------------
char * ParseAdminLogin(char * adm)
{
if (CheckLogin(adm))
   {
   printf("Incorresct admin login %s\n", adm);
   exit(PARAMETER_PARSING_ERR_CODE);
   }
return adm;
}
//-----------------------------------------------------------------------------
char * ParseAdminPassword(char * pass)
{
if (strlen(pass) >= ADM_PASSWD_LEN)
   {
   printf("Password too big %s\n", pass);
   exit(PARAMETER_PARSING_ERR_CODE);
   }

return pass;
}
//-----------------------------------------------------------------------------
int CheckLogin(const char * login)
{
for (int i = 0; i < strlen(login); i++)
   {
   if (!(( login[i] >= 'a' && login[i] <= 'z')
       || (login[i] >= 'A' && login[i] <= 'Z')
       || (login[i] >= '0' && login[i] <= '9')
       ||  login[i] == '_'))
       {
       return 1;
       }
   }
return 0;
}
//-----------------------------------------------------------------------------
void FileRequest(char * r)
{
char str[1024];
FILE *f;

r[0] = 0;
f = NULL;
f = fopen(fileName, "rt");
if (!f)
{
 printf("Can't open request file\n");
 exit(PARAMETER_PARSING_ERR_CODE);
}
char ts[REQ_STR_LEN];
while (fgets(ts, REQ_STR_LEN, f))
   { strncat(r, ts, REQ_STR_LEN);}
fclose(f);
}

int Process(REQUEST * r)
{
char str[2048];
NETTRANSACT nt;
nt.SetServer(r->server);
nt.SetServerPort(r->port);
nt.SetLogin(r->admLogin);
nt.SetPassword(r->admPasswd);
nt.SetRxCallback(ParseReply);

FileRequest(str);

if (nt.Connect())
   {
   printf("Connect failed.\n");
   exit(NETWORK_ERR_CODE);
   }

if (nt.Transact(str))
   {
   printf("Login or password failed.\n");
   exit(LOGIN_OR_PASS_ERR_CODE);
   }

nt.Disconnect();

printf("Ok\n");
return 0;
}
//-----------------------------------------------------------------------------
int CheckParameters(REQUEST * req)
{
int a = req->admLoginReq 
   && req->admPasswdReq
   && req->serverReq
   && req->portReq;
return a;
}
//-----------------------------------------------------------------------------
void Usage()
{
printf("Use:\n");
printf("sgconf -s <server> -p <port> -a <admin> -w <admin_pass> -f <request_file>\n");
}

 

Теперь для того чтобы, например установить счет пользователя, достаточно создать файл

<SetUser>
<login value="test"/>
<cash set="10.0"/>
</SetUser>

и передать его в качесте параметра конфигуратору

Ссылка на сообщение
Поделиться на других сайтах

Про заморозку, немного непонятно как ее перевели...

Вероятно:

<SetUser>
<login value="test"/>
<passive value="1"/>
</SetUser>

 

А вообще хорошо бы на практике проверить все параметры, отрабатывают ли. Смотрю я их в файле parser.cpp в исходниках сервера.

Ссылка на сообщение
Поделиться на других сайтах

login

NewLogin

ip

password

address

aonline

cash

CashExpire

CreditExpire

credit

freemb

down

email

userdata0

userdata1

group

iface

note

passive

phone

Name

traff

tariff

Это то что доступно, однако работать со строковымы параметрами у меня не вышло

<SetUser>

<login value="test"/>

<address value="test"/>

<iface value="eth0"/>

</SetUser>

в поле адреса вместо тест появляеться SB

деньги интерфейс установка пасива и замарозки работает на ура

и еще я как понял если вместо параметра логин отправлять параметр NewLorin по идеи должен регистрировать нового пользователя

Ссылка на сообщение
Поделиться на других сайтах

А со строковыми параметрами не так все просто. Для их кодирования применяется функция

void Encode12(char * dst, const char * src, int srcLen)
{
char c1, c2;
int i;
for (i = 0; i <= srcLen; i++)
   {
   c1 = src[i] & 0x0f;
   c2 = (src[i] & 0xf0) >> 4;

   c1 += 'a';
   c2 += 'a';

   dst[i*2] = c1;
   dst[i*2 + 1] = c2;
   }
dst[i*2] = 0;

Вот ёё то и придется повторить в скрипте, чтобы иметь возможность отсылать серверу строковые параметры. А суть ее заключается в том что каждый байт кодируется в 2 буквы от 'a' до 'p'

 

А для создания юзера, похоже, надо просто указать все параметры и заключить их в теги <AddUser> </AddUser>

Ссылка на сообщение
Поделиться на других сайтах
  • 1 month later...

<AddUser>
<login value="login_name"/>
<ip value=""/>
<password value="123456"/>
<phone value=""/>
<email value=""/>
<tariff value="ehbgchjggggg"/>
<address value=""/>
<note value=""/>
<name value=""/>
<userdata0 value=""/>
<userdata1 value=""/>
<cash value="0.0"/>
<credit value="0.0"/>
<iface value="eth0"/>
<group value=""/>
<passive value="0"/>
<down value="0"/>
<aonline value="0"/>
</AddUser>

Вот так работает добавление пользователя. В данном примере тариф=encode12("tariff")

если послать <GetUser> <login value="login_name"/></GetUser> должно вернуть параметры пользователя

Ссылка на сообщение
Поделиться на других сайтах

Для получения данных желательно подправить функцию в файле netunit.cpp:

int NETTRANSACT::RxDataAnswer()
{
int n = 0;
int ret;
char bufferS[ENC_MSG_LEN];
char buffer[ENC_MSG_LEN];

BLOWFISH_CTX ctx;
EnDecryptInit(password, PASSWD_LEN, &ctx);
FILE *f=fopen("output.xml","w");
while (1)
   {
   ret = recv(outerSocket, &bufferS[n++], 1, 0);
   if (ret <= 0)
       {
       fclose(f);
       close(outerSocket);
       strcpy(errorMsg, RECV_DATA_ANSWER_ERROR);
       return 0;
       }


   if (n == 8)
       {
       n = 0;
       Decrypt(buffer, bufferS, &ctx);

       for (int j = 0; j < 8; j++)
           {
           if (buffer[j] == 0)
               {
                   fwrite(buffer,j,1,f);
                   if (RxCallBack)  RxCallBack(answer);
                   return st_ok;
               }
           }
           fwrite(buffer,8,1,f);
       }

   }
}

Полученные данные будут записаны в файл output.xml.

<GetUser login="test"/>

Вернет данные пользователя.

Другие варианты запросов:

GetServerInfo

GetUsers

GetTariffs

GetTariff

и тд

Ссылка на сообщение
Поделиться на других сайтах
  • 11 months later...

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Вхід

Уже зарегистрированы? Войдите здесь.

Войти сейчас
  • Зараз на сторінці   0 користувачів

    Немає користувачів, що переглядають цю сторінку.

×
×
  • Створити нове...