source: trunk/module-camd33.c@ 3172

Last change on this file since 3172 was 3172, checked in by _network, 10 years ago

remove global mbuf

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