source: trunk/module-camd33.c @ 5375

Last change on this file since 5375 was 5299, checked in by Admin, 8 years ago

Replace all malloc/calloc calls (in main OSCam directory) with cs_malloc and add handling for memory allocation failures.

File size: 5.4 KB
Line 
1#include "globals.h"
2
3#define REQ_SIZE    4
4
5static int32_t camd33_send(uchar *buf, int32_t ml)
6{
7  int32_t l;
8  if (!cur_client()->pfd) return(-1);
9  l=boundary(4, ml);
10  memset(buf+ml, 0, l-ml);
11  cs_ddump_mask(D_CLIENT, buf, l, "send %d bytes to client", l);
12  if (cur_client()->crypted)
13    aes_encrypt(buf, l);
14  return(send(cur_client()->pfd, buf, l, 0));
15}
16
17static int32_t camd33_recv(struct s_client * client, uchar *buf, int32_t l)
18{
19  int32_t n;
20  if (!client->pfd) return(-1);
21  if ((n=recv(client->pfd, buf, l, 0))>0)
22  {
23    client->last=time((time_t *) 0);
24    if (client->crypted)
25      aes_decrypt(buf, n);
26  }
27  cs_ddump_mask(D_CLIENT, buf, n, "received %d bytes from client", n);
28  return(n);
29}
30
31static void camd33_request_emm()
32{
33  uchar mbuf[20];
34    struct s_reader *aureader = NULL, *rdr = NULL;
35
36    //TODO: just take the first reader in list
37    LL_ITER itr = ll_iter_create(cur_client()->aureader_list);
38    while ((rdr = ll_iter_next(&itr))) {
39        aureader=rdr;
40        break;
41    }
42
43    if (!aureader) return;
44
45  if (aureader->hexserial[0])
46  {
47    log_emm_request(aureader);
48    mbuf[0]=0;
49    mbuf[1]=aureader->caid>>8;
50    mbuf[2]=aureader->caid&0xff;
51    memcpy(mbuf+3, aureader->hexserial, 4);
52    memcpy(mbuf+7, &aureader->prid[0][1], 3);
53    memcpy(mbuf+10, &aureader->prid[2][1], 3);
54    camd33_send(mbuf, 13);
55  }
56}
57
58static void camd33_auth_client(uchar *camdbug)
59{
60  int32_t i, rc;
61  uchar *usr=NULL, *pwd=NULL;
62  struct s_auth *account;
63  uchar mbuf[1024];
64
65  cur_client()->crypted=cfg.c33_crypted;
66
67  if (cur_client()->crypted)
68    cur_client()->crypted = check_ip(cfg.c33_plain, cur_client()->ip) ? 0 : 1;
69
70  if (cur_client()->crypted)
71    aes_set_key((char *) cfg.c33_key);
72
73  mbuf[0]=0;
74  camd33_send(mbuf, 1); // send login-request
75
76  for (rc=0, camdbug[0]=0, mbuf[0]=1; (rc<2) && (mbuf[0]); rc++)
77  {
78    i=process_input(mbuf, sizeof(mbuf), 1);
79    if ((i>0) && (!mbuf[0]))
80    {
81      usr=mbuf+1;
82      pwd=usr+strlen((char *)usr)+2;
83    }
84    else
85      memcpy(camdbug+1, mbuf, camdbug[0]=i);
86  }
87  for (rc=-1, account=cfg.account; (usr) && (account) && (rc<0); account=account->next)
88    if ((!strcmp((char *)usr, account->usr)) && (!strcmp((char *)pwd, account->pwd)))
89      rc=cs_auth_client(cur_client(), account, NULL);
90  if (!rc)
91    camd33_request_emm();
92  else
93  {
94    if (rc<0) cs_auth_client(cur_client(), 0, usr ? "invalid account" : "no user given");
95    cs_exit(0);
96  }
97}
98
99static int32_t get_request(uchar *buf, int32_t n, uchar *camdbug)
100{
101  int32_t rc, w;
102  struct s_client *cur_cl = cur_client();
103
104  if (camdbug[0])
105  {
106    memcpy(buf, camdbug+1, rc=camdbug[0]);
107    camdbug[0]=0;
108    return(rc);
109  }
110  for (rc=w=0; !rc;)
111  {
112    switch (rc=process_input(buf, 16, (w) ? cfg.ctimeout : cfg.cmaxidle))
113    {
114      case -9:
115        rc=0;
116      case  0:
117        if ((w) || cfg.c33_passive)
118          rc=-1;
119        else
120        {
121          buf[0]=0;
122          camd33_send(buf, 1);
123          w++;
124        }
125      case -1:
126        break;
127      default:
128        if (cur_cl->account && !memcmp(buf+1, cur_cl->account->usr, strlen(cur_cl->account->usr)))
129        {
130          cs_log("%s still alive", cs_inet_ntoa(cur_cl->ip));
131          rc=w=0;
132        }
133          else
134        {
135          switch (buf[0])
136          {
137            case  2:
138            case  3: w=boundary(4, buf[9]+10); break;
139            default: w=n;   // garbage ?
140          }
141          w=process_input(buf+16, w-16, 0);
142          if (w>0) rc+=w;
143        }
144    }
145  }
146  if (rc<0) rc=0;
147  return(rc);
148}
149
150static void camd33_send_dcw(struct s_client *client, ECM_REQUEST *er)
151{
152  uchar mbuf[1024];
153  mbuf[0]=2;
154  memcpy(mbuf+1, client->req+(er->cpti*REQ_SIZE), 4);   // get pin
155  memcpy(mbuf+5, er->cw, 16);
156  camd33_send(mbuf, 21);
157  if (!cfg.c33_passive)
158    camd33_request_emm();
159}
160
161static void camd33_process_ecm(uchar *buf, int32_t l)
162{
163  ECM_REQUEST *er;
164  if (!(er=get_ecmtask()))
165    return;
166  memcpy(cur_client()->req+(er->cpti*REQ_SIZE), buf+3, 4);  // save pin
167  er->l=l-7;
168  er->caid=b2i(2, buf+1);
169  memcpy(er->ecm , buf+7, er->l);
170  get_cw(cur_client(), er);
171}
172
173static void camd33_process_emm(uchar *buf, int32_t l)
174{
175  EMM_PACKET epg;
176  memset(&epg, 0, sizeof(epg));
177  epg.l=l-7;
178  memcpy(epg.caid     , buf+1, 2);
179  memcpy(epg.hexserial, buf+3, 4);
180  memcpy(epg.emm      , buf+7, epg.l);
181  do_emm(cur_client(), &epg);
182}
183
184static void * camd33_server(void* cli)
185{
186  int32_t n;
187  uchar mbuf[1024];
188  uchar camdbug[256];
189
190  struct s_client * client = (struct s_client *) cli;
191  client->thread=pthread_self();
192  pthread_setspecific(getclient, cli);
193
194  cs_malloc(&client->req,CS_MAXPENDING*REQ_SIZE, 1);
195
196  camd33_auth_client(camdbug);
197
198  while ((n=get_request(mbuf, sizeof(mbuf), camdbug))>0)
199  {
200    switch(mbuf[0])
201    {
202      case 2:
203        camd33_process_ecm(mbuf, n);
204        break;
205      case 3:
206        camd33_process_emm(mbuf, n);
207        break;
208      default:
209        cs_debug_mask(D_CLIENT, "unknown command !");
210    }
211  }
212  cs_disconnect_client(client);
213  return NULL;
214}
215
216void module_camd33(struct s_module *ph)
217{
218  static PTAB ptab; //since there is always only 1 camd33 server running, this is threadsafe
219  ptab.ports[0].s_port = cfg.c33_port;
220  ph->ptab = &ptab;
221  ph->ptab->nports = 1;
222
223  cs_strncpy(ph->desc, "camd33", sizeof(ph->desc));
224  ph->type=MOD_CONN_TCP;
225  ph->logtxt=cfg.c33_crypted ? ", crypted" : ", UNCRYPTED!";
226  ph->multi=1;
227  ph->watchdog=1;
228  ph->s_ip=cfg.c33_srvip;
229  ph->s_handler=camd33_server;
230  ph->recv=camd33_recv;
231  ph->send_dcw=camd33_send_dcw;
232  ph->num=R_CAMD33;
233}
Note: See TracBrowser for help on using the repository browser.