source: trunk/module-camd33.c@ 4149

Last change on this file since 4149 was 4141, checked in by dingo35, 13 years ago

all: simplify debug system, add D_DVBAPI = -d128, eliminate cs_ptyp which complicates stuff unnecc

File size: 5.4 KB
Line 
1#include "globals.h"
2
3#define REQ_SIZE 4
4
5static int camd33_send(uchar *buf, int ml)
6{
7 int 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 int camd33_recv(struct s_client * client, uchar *buf, int l)
18{
19 int 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=cur_client()->aureader;
35 if (!aureader) return; // TODO
36 if (aureader->hexserial[0])
37 {
38 log_emm_request(aureader);
39 mbuf[0]=0;
40 mbuf[1]=aureader->caid[0]>>8;
41 mbuf[2]=aureader->caid[0]&0xff;
42 memcpy(mbuf+3, aureader->hexserial, 4);
43 memcpy(mbuf+7, &aureader->prid[0][1], 3);
44 memcpy(mbuf+10, &aureader->prid[2][1], 3);
45 camd33_send(mbuf, 13);
46 }
47}
48
49static void camd33_auth_client()
50{
51 int i, rc;
52 uchar *usr=NULL, *pwd=NULL;
53 struct s_auth *account;
54 uchar mbuf[1024];
55
56 cur_client()->crypted=cfg->c33_crypted;
57 if (cur_client()->crypted)
58 {
59 struct s_ip *p_ip;
60 for (p_ip=cfg->c33_plain; (p_ip) && (cur_client()->crypted); p_ip=p_ip->next)
61 if ((cur_client()->ip>=p_ip->ip[0]) && (cur_client()->ip<=p_ip->ip[1]))
62 cur_client()->crypted=0;
63 }
64 if (cur_client()->crypted)
65 aes_set_key((char *) cfg->c33_key);
66
67 mbuf[0]=0;
68 camd33_send(mbuf, 1); // send login-request
69
70 for (rc=0, cur_client()->camdbug[0]=0, mbuf[0]=1; (rc<2) && (mbuf[0]); rc++)
71 {
72 i=process_input(mbuf, sizeof(mbuf), 1);
73 if ((i>0) && (!mbuf[0]))
74 {
75 usr=mbuf+1;
76 pwd=usr+strlen((char *)usr)+2;
77 }
78 else
79 memcpy(cur_client()->camdbug+1, mbuf, cur_client()->camdbug[0]=i);
80 }
81 for (rc=-1, account=cfg->account; (usr) && (account) && (rc<0); account=account->next)
82 if ((!strcmp((char *)usr, account->usr)) && (!strcmp((char *)pwd, account->pwd)))
83 rc=cs_auth_client(cur_client(), account, NULL);
84 if (!rc)
85 camd33_request_emm();
86 else
87 {
88 if (rc<0) cs_auth_client(cur_client(), 0, usr ? "invalid account" : "no user given");
89 cs_exit(0);
90 }
91}
92
93static int get_request(uchar *buf, int n)
94{
95 int rc, w;
96
97 if (cur_client()->camdbug[0])
98 {
99 memcpy(buf, cur_client()->camdbug+1, rc=cur_client()->camdbug[0]);
100 cur_client()->camdbug[0]=0;
101 return(rc);
102 }
103 for (rc=w=0; !rc;)
104 {
105 switch (rc=process_input(buf, 16, (w) ? cfg->ctimeout : cfg->cmaxidle))
106 {
107 case -9:
108 rc=0;
109 case 0:
110 if ((w) || cfg->c33_passive)
111 rc=-1;
112 else
113 {
114 buf[0]=0;
115 camd33_send(buf, 1);
116 w++;
117 }
118 case -1:
119 break;
120 default:
121 if (!memcmp(buf+1, cur_client()->usr, strlen(cur_client()->usr)))
122 {
123 cs_log("%s still alive", cs_inet_ntoa(cur_client()->ip));
124 rc=w=0;
125 }
126 else
127 {
128 switch (buf[0])
129 {
130 case 2:
131 case 3: w=boundary(4, buf[9]+10); break;
132 default: w=n; // garbage ?
133 }
134 w=process_input(buf+16, w-16, 0);
135 if (w>0) rc+=w;
136 }
137 }
138 }
139 if (rc<0) rc=0;
140 return(rc);
141}
142
143static void camd33_send_dcw(struct s_client *client, ECM_REQUEST *er)
144{
145 uchar mbuf[1024];
146 mbuf[0]=2;
147 memcpy(mbuf+1, client->req+(er->cpti*REQ_SIZE), 4); // get pin
148 memcpy(mbuf+5, er->cw, 16);
149 camd33_send(mbuf, 21);
150 if (!cfg->c33_passive)
151 camd33_request_emm();
152}
153
154static void camd33_process_ecm(uchar *buf, int l)
155{
156 ECM_REQUEST *er;
157 if (!(er=get_ecmtask()))
158 return;
159 memcpy(cur_client()->req+(er->cpti*REQ_SIZE), buf+3, 4); // save pin
160 er->l=l-7;
161 er->caid=b2i(2, buf+1);
162 memcpy(er->ecm , buf+7, er->l);
163 get_cw(cur_client(), er);
164}
165
166static void camd33_process_emm(uchar *buf, int l)
167{
168 EMM_PACKET epg;
169 memset(&epg, 0, sizeof(epg));
170 epg.l=l-7;
171 memcpy(epg.caid , buf+1, 2);
172 memcpy(epg.hexserial, buf+3, 4);
173 memcpy(epg.emm , buf+7, epg.l);
174 do_emm(cur_client(), &epg);
175}
176
177static void * camd33_server(void* cli)
178{
179 int n;
180 uchar mbuf[1024];
181
182 struct s_client * client = (struct s_client *) cli;
183 client->thread=pthread_self();
184 pthread_setspecific(getclient, cli);
185
186 client->req=(uchar *)malloc(CS_MAXPENDING*REQ_SIZE);
187 if (!client->req)
188 {
189 cs_log("Cannot allocate memory (errno=%d)", errno);
190 cs_exit(1);
191 }
192 memset(client->req, 0, CS_MAXPENDING*REQ_SIZE);
193
194 camd33_auth_client();
195
196 while ((n=get_request(mbuf, sizeof(mbuf)))>0)
197 {
198 switch(mbuf[0])
199 {
200 case 2:
201 camd33_process_ecm(mbuf, n);
202 break;
203 case 3:
204 camd33_process_emm(mbuf, n);
205 break;
206 default:
207 cs_debug_mask(D_CLIENT, "unknown command !");
208 }
209 }
210 cs_disconnect_client(client);
211 return NULL;
212}
213
214void module_camd33(struct s_module *ph)
215{
216 static PTAB ptab; //since there is always only 1 camd33 server running, this is threadsafe
217 ptab.ports[0].s_port = cfg->c33_port;
218 ph->ptab = &ptab;
219 ph->ptab->nports = 1;
220
221 strcpy(ph->desc, "camd33");
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.