source: trunk/module-camd33.c@ 3181

Last change on this file since 3181 was 3181, checked in by dingo35, 10 years ago

Adding threadsafety FIXMEs, feel free to join checking..

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