Project

General

Profile

RE: unsupported CA system - Will not forward EMMs ยป cwc.c

Beat Michel Liechti, 2011-03-27 19:42

 
1
/*
2
 *  tvheadend, CWC interface
3
 *  Copyright (C) 2007 Andreas ?man
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation, either version 3 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

    
19
#include <pthread.h>
20
#include <assert.h>
21
#include <string.h>
22
#include <stdio.h>
23
#include <unistd.h>
24
#include <stdlib.h>
25
#include <stdarg.h>
26
#include <errno.h>
27
#include <netinet/in.h>
28
#include <arpa/inet.h>
29
#include <ctype.h>
30

    
31
#include "tvheadend.h"
32
#include "tcp.h"
33
#include "psi.h"
34
#include "tsdemux.h"
35
#include "ffdecsa/FFdecsa.h"
36
#include "cwc.h"
37
#include "notify.h"
38
#include "atomic.h"
39
#include "dtable.h"
40
#include "subscriptions.h"
41

    
42
#include <openssl/des.h>
43

    
44
/**
45
 *
46
 */
47

    
48
#define CWC_KEEPALIVE_INTERVAL 30
49

    
50
#define CWS_NETMSGSIZE 272
51
#define CWS_FIRSTCMDNO 0xe0
52

    
53
/**
54
 * cards for which emm updates are handled
55
 */
56
typedef enum {
57
  CARD_IRDETO,
58
  CARD_DRE,
59
  CARD_CONAX,
60
  CARD_SECA,
61
  CARD_VIACCESS,
62
  CARD_UNKNOWN
63
} card_type_t;
64

    
65
typedef enum {
66
  MSG_CLIENT_2_SERVER_LOGIN = CWS_FIRSTCMDNO,
67
  MSG_CLIENT_2_SERVER_LOGIN_ACK,
68
  MSG_CLIENT_2_SERVER_LOGIN_NAK,
69
  MSG_CARD_DATA_REQ,
70
  MSG_CARD_DATA,
71
  MSG_SERVER_2_CLIENT_NAME,
72
  MSG_SERVER_2_CLIENT_NAME_ACK,
73
  MSG_SERVER_2_CLIENT_NAME_NAK,
74
  MSG_SERVER_2_CLIENT_LOGIN,
75
  MSG_SERVER_2_CLIENT_LOGIN_ACK,
76
  MSG_SERVER_2_CLIENT_LOGIN_NAK,
77
  MSG_ADMIN,
78
  MSG_ADMIN_ACK,
79
  MSG_ADMIN_LOGIN,
80
  MSG_ADMIN_LOGIN_ACK,
81
  MSG_ADMIN_LOGIN_NAK,
82
  MSG_ADMIN_COMMAND,
83
  MSG_ADMIN_COMMAND_ACK,
84
  MSG_ADMIN_COMMAND_NAK,
85
  MSG_KEEPALIVE = CWS_FIRSTCMDNO + 0x1d
86
} net_msg_type_t;
87

    
88

    
89
/**
90
 *
91
 */
92
TAILQ_HEAD(cwc_queue, cwc);
93
LIST_HEAD(cwc_service_list, cwc_service);
94
TAILQ_HEAD(cwc_message_queue, cwc_message);
95
LIST_HEAD(ecm_section_list, ecm_section);
96
static struct cwc_queue cwcs;
97
static pthread_cond_t cwc_config_changed;
98
static pthread_mutex_t cwc_mutex;
99
static char *crypt_md5(const char *pw, const char *salt);
100

    
101
/**
102
 *
103
 */
104
typedef struct ecm_section {
105
  int es_section;
106
  int es_channel;
107

    
108
  uint16_t es_seq;
109
  char es_nok;
110
  char es_pending;
111
  int64_t es_time;  // time request was sent
112
  size_t es_ecmsize;
113
  uint8_t es_ecm[4070];
114

    
115
} ecm_section_t;
116

    
117

    
118
/**
119
 *
120
 */
121
typedef struct ecm_pid {
122
  LIST_ENTRY(ecm_pid) ep_link;
123
  
124
  uint16_t ep_pid;
125

    
126
  int ep_last_section;
127
  struct ecm_section *ep_sections[256];
128
} ecm_pid_t;
129

    
130

    
131
/**
132
 *
133
 */
134
typedef struct cwc_service {
135
  th_descrambler_t cs_head;
136

    
137
  service_t *cs_service;
138

    
139
  struct cwc *cs_cwc;
140

    
141
  LIST_ENTRY(cwc_service) cs_link;
142

    
143
  int cs_okchannel;
144

    
145
  /**
146
   * Status of the key(s) in cs_keys
147
   */
148
  enum {
149
    CS_UNKNOWN,
150
    CS_RESOLVED,
151
    CS_FORBIDDEN
152
  } cs_keystate;
153

    
154
  void *cs_keys;
155

    
156

    
157
  uint8_t cs_cw[16];
158
  int cs_pending_cw_update;
159

    
160
  /**
161
   * CSA
162
   */
163
  int cs_cluster_size;
164
  uint8_t *cs_tsbcluster;
165
  int cs_fill;
166

    
167
  LIST_HEAD(, ecm_pid) cs_pids;
168

    
169
} cwc_service_t;
170

    
171

    
172
/**
173
 *
174
 */
175
typedef struct cwc_message {
176
  TAILQ_ENTRY(cwc_message) cm_link;
177
  int cm_len;
178
  uint8_t cm_data[CWS_NETMSGSIZE];
179
} cwc_message_t;
180

    
181

    
182
/**
183
 *
184
 */
185
typedef struct cwc_provider {
186
  uint32_t id;
187
  uint8_t sa[8];
188
} cwc_provider_t;
189

    
190
/**
191
 *
192
 */
193
typedef struct cwc {
194
  int cwc_fd;
195
  int cwc_connected;
196

    
197
  int cwc_retry_delay;
198

    
199
  pthread_cond_t cwc_cond;
200

    
201
  pthread_mutex_t cwc_writer_mutex; 
202
  pthread_cond_t cwc_writer_cond; 
203
  int cwc_writer_running;
204
  struct cwc_message_queue cwc_writeq;
205

    
206
  TAILQ_ENTRY(cwc) cwc_link; /* Linkage protected via cwc_mutex */
207

    
208
  struct cwc_service_list cwc_services;
209

    
210
  uint16_t cwc_caid;
211

    
212
  int cwc_seq;
213

    
214
  DES_key_schedule cwc_k1, cwc_k2;
215

    
216
  uint8_t cwc_buf[256];
217
  int cwc_bufptr;
218

    
219
  /* Card Unique Address */
220
  uint8_t cwc_ua[8];
221

    
222
  /* Provider IDs */
223
  cwc_provider_t cwc_providers[256];
224
  int cwc_num_providers;
225

    
226
  /* Emm forwarding */
227
  int cwc_forward_emm;
228

    
229
  /* Emm duplicate cache */
230
  struct {
231
#define EMM_CACHE_SIZE (1<<5)
232
#define EMM_CACHE_MASK (EMM_CACHE_SIZE-1)
233
    uint32_t cache[EMM_CACHE_SIZE];
234
    uint32_t w;
235
    uint32_t n;
236
  } cwc_emm_cache;
237

    
238
  /* Viaccess EMM assemble state */
239
  struct {
240
    int shared_toggle;
241
    int shared_len;
242
    uint8_t * shared_emm;
243
  } cwc_viaccess_emm;
244

    
245
  /* Card type */
246
  card_type_t cwc_card_type;
247
  
248
  /* From configuration */
249

    
250
  uint8_t cwc_confedkey[14];
251
  char *cwc_username;
252
  char *cwc_password;
253
  char *cwc_password_salted;   /* salted version */
254
  char *cwc_comment;
255
  char *cwc_hostname;
256
  int cwc_port;
257
  char *cwc_id;
258
  int cwc_emm;
259

    
260
  const char *cwc_errtxt;
261

    
262
  int cwc_enabled;
263
  int cwc_running;
264
  int cwc_reconfigure;
265
} cwc_t;
266

    
267

    
268
/**
269
 *
270
 */
271

    
272
static void cwc_service_destroy(th_descrambler_t *td);
273
static void cwc_detect_card_type(cwc_t *cwc);
274
void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len);
275
void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len);
276
void cwc_emm_dre(cwc_t *cwc, uint8_t *data, int len);
277
void cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len);
278
void cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int len);
279

    
280

    
281
/**
282
 *
283
 */
284
static void 
285
des_key_parity_adjust(uint8_t *key, uint8_t len)
286
{
287
  uint8_t i, j, parity;
288
  
289
  for (i = 0; i < len; i++) {
290
    parity = 1;
291
    for (j = 1; j < 8; j++) if ((key[i] >> j) & 0x1) parity = ~parity & 0x01;
292
    key[i] |= parity;
293
  }
294
}
295

    
296

    
297
/**
298
 *
299
 */
300
static void
301
des_key_spread(uint8_t *normal, uint8_t *spread)
302
{
303
  spread[ 0] = normal[ 0] & 0xfe;
304
  spread[ 1] = ((normal[ 0] << 7) | (normal[ 1] >> 1)) & 0xfe;
305
  spread[ 2] = ((normal[ 1] << 6) | (normal[ 2] >> 2)) & 0xfe;
306
  spread[ 3] = ((normal[ 2] << 5) | (normal[ 3] >> 3)) & 0xfe;
307
  spread[ 4] = ((normal[ 3] << 4) | (normal[ 4] >> 4)) & 0xfe;
308
  spread[ 5] = ((normal[ 4] << 3) | (normal[ 5] >> 5)) & 0xfe;
309
  spread[ 6] = ((normal[ 5] << 2) | (normal[ 6] >> 6)) & 0xfe;
310
  spread[ 7] = normal[ 6] << 1;
311
  spread[ 8] = normal[ 7] & 0xfe;
312
  spread[ 9] = ((normal[ 7] << 7) | (normal[ 8] >> 1)) & 0xfe;
313
  spread[10] = ((normal[ 8] << 6) | (normal[ 9] >> 2)) & 0xfe;
314
  spread[11] = ((normal[ 9] << 5) | (normal[10] >> 3)) & 0xfe;
315
  spread[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe;
316
  spread[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe;
317
  spread[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe;
318
  spread[15] = normal[13] << 1;
319

    
320
  des_key_parity_adjust(spread, 16);
321
}
322

    
323
/**
324
 *
325
 */
326
static void 
327
des_random_get(uint8_t *buffer, uint8_t len)
328
{
329
  uint8_t idx = 0;
330
  int randomNo = 0;
331
  
332
  for (idx = 0; idx < len; idx++) {
333
      if (!(idx % 3)) randomNo = rand();
334
      buffer[idx] = (randomNo >> ((idx % 3) << 3)) & 0xff;
335
    }
336
}
337

    
338
/**
339
 *
340
 */
341
static int
342
des_encrypt(uint8_t *buffer, int len, cwc_t *cwc)
343
{
344
  uint8_t checksum = 0;
345
  uint8_t noPadBytes;
346
  uint8_t padBytes[7];
347
  DES_cblock ivec;
348
  uint16_t i;
349

    
350
  noPadBytes = (8 - ((len - 1) % 8)) % 8;
351
  if (len + noPadBytes + 1 >= CWS_NETMSGSIZE-8) return -1;
352
  des_random_get(padBytes, noPadBytes);
353
  for (i = 0; i < noPadBytes; i++) buffer[len++] = padBytes[i];
354
  for (i = 2; i < len; i++) checksum ^= buffer[i];
355
  buffer[len++] = checksum;
356
  des_random_get((uint8_t *)ivec, 8);
357
  memcpy(buffer+len, ivec, 8);
358
  for (i = 2; i < len; i += 8) {
359
    DES_ncbc_encrypt(buffer+i, buffer+i, 8,  &cwc->cwc_k1, &ivec, 1);
360

    
361
    DES_ecb_encrypt((DES_cblock *)(buffer+i), (DES_cblock *)(buffer+i),
362
		    &cwc->cwc_k2, 0);
363

    
364
    DES_ecb_encrypt((DES_cblock *)(buffer+i), (DES_cblock *)(buffer+i),
365
		    &cwc->cwc_k1, 1);
366
    memcpy(ivec, buffer+i, 8);
367
  }
368
  len += 8;
369
  return len;
370
}
371

    
372
/**
373
 *
374
 */
375
static int 
376
des_decrypt(uint8_t *buffer, int len, cwc_t *cwc)
377
{
378
  DES_cblock ivec;
379
  DES_cblock nextIvec;
380
  int i;
381
  uint8_t checksum = 0;
382

    
383
  if ((len-2) % 8 || (len-2) < 16) return -1;
384
  len -= 8;
385
  memcpy(nextIvec, buffer+len, 8);
386
  for (i = 2; i < len; i += 8)
387
    {
388
      memcpy(ivec, nextIvec, 8);
389
      memcpy(nextIvec, buffer+i, 8);
390

    
391
      DES_ecb_encrypt((DES_cblock *)(buffer+i), (DES_cblock *)(buffer+i),
392
		      &cwc->cwc_k1, 0);
393
      DES_ecb_encrypt((DES_cblock *)(buffer+i), (DES_cblock *)(buffer+i),
394
		      &cwc->cwc_k2, 1);
395

    
396
      DES_ncbc_encrypt(buffer+i, buffer+i, 8,  &cwc->cwc_k1, &ivec, 0);
397
    } 
398
  for (i = 2; i < len; i++) checksum ^= buffer[i];
399
  if (checksum) return -1;
400
  return len;
401
}
402

    
403
/**
404
 *
405
 */
406
static void
407
des_make_login_key(cwc_t *cwc, uint8_t *k)
408
{
409
  uint8_t des14[14], spread[16];
410
  int i;
411

    
412
  for (i = 0; i < 14; i++) 
413
    des14[i] = cwc->cwc_confedkey[i] ^ k[i];
414
  des_key_spread(des14, spread);
415
  
416
  DES_set_key_unchecked((DES_cblock *)spread,     &cwc->cwc_k1);
417
  DES_set_key_unchecked((DES_cblock *)(spread+8), &cwc->cwc_k2);
418
}
419

    
420
/**
421
 *
422
 */
423
static void
424
des_make_session_key(cwc_t *cwc)
425
{
426
  uint8_t des14[14], spread[16], *k2 = (uint8_t *)cwc->cwc_password_salted;
427
  int i, l = strlen(cwc->cwc_password_salted);
428

    
429
  memcpy(des14, cwc->cwc_confedkey, 14);
430

    
431
  for (i = 0; i < l; i++)
432
    des14[i % 14] ^= k2[i];
433

    
434
  des_key_spread(des14, spread);
435
  DES_set_key_unchecked((DES_cblock *)spread,     &cwc->cwc_k1);
436
  DES_set_key_unchecked((DES_cblock *)(spread+8), &cwc->cwc_k2);
437
}
438

    
439
/**
440
 * Note, this function is called from multiple threads so beware of
441
 * locking / race issues (Note how we use atomic_add() to generate
442
 * the ID)
443
 */
444
static int
445
cwc_send_msg(cwc_t *cwc, const uint8_t *msg, size_t len, int sid, int enq)
446
{
447
  cwc_message_t *cm = malloc(sizeof(cwc_message_t));
448
  uint8_t *buf = cm->cm_data;
449
  int seq, n;
450

    
451
  if(len + 12 > CWS_NETMSGSIZE)
452
    return -1;
453

    
454
  memset(buf, 0, 12);
455
  memcpy(buf + 12, msg, len);
456

    
457
  len += 12;
458

    
459
  seq = atomic_add(&cwc->cwc_seq, 1);
460

    
461
  buf[2] = seq >> 8;
462
  buf[3] = seq;
463
  buf[4] = sid >> 8;
464
  buf[5] = sid;
465

    
466
  if((len = des_encrypt(buf, len, cwc)) < 0) {
467
    free(buf);
468
    return -1;
469
  }
470

    
471
  buf[0] = (len - 2) >> 8;
472
  buf[1] =  len - 2;
473

    
474

    
475
  if(enq) {
476
    cm->cm_len = len;
477
    pthread_mutex_lock(&cwc->cwc_writer_mutex);
478
    TAILQ_INSERT_TAIL(&cwc->cwc_writeq, cm, cm_link);
479
    pthread_cond_signal(&cwc->cwc_writer_cond);
480
    pthread_mutex_unlock(&cwc->cwc_writer_mutex);
481
  } else {
482
    n = write(cwc->cwc_fd, buf, len);
483
    free(cm);
484
  }
485
  return seq & 0xffff;
486
}
487

    
488

    
489

    
490
/**
491
 * Card data command
492
 */
493

    
494
static void
495
cwc_send_data_req(cwc_t *cwc)
496
{
497
  uint8_t buf[CWS_NETMSGSIZE];
498

    
499
  buf[0] = MSG_CARD_DATA_REQ;
500
  buf[1] = 0;
501
  buf[2] = 0;
502

    
503
  cwc_send_msg(cwc, buf, 3, 0, 0);
504
}
505

    
506

    
507
/**
508
 * Send keep alive
509
 */
510
static void
511
cwc_send_ka(cwc_t *cwc)
512
{
513
  uint8_t buf[CWS_NETMSGSIZE];
514

    
515
  buf[0] = MSG_KEEPALIVE;
516
  buf[1] = 0;
517
  buf[2] = 0;
518

    
519
  cwc_send_msg(cwc, buf, 3, 0, 0);
520
}
521

    
522
/**
523
 *
524
 */
525
static void 
526
cwc_comet_status_update(cwc_t *cwc)
527
{
528
  htsmsg_t *m = htsmsg_create_map();
529

    
530
  htsmsg_add_str(m, "id", cwc->cwc_id);
531
  htsmsg_add_u32(m, "connected", !!cwc->cwc_connected);
532
  notify_by_msg("cwcStatus", m);
533
}
534

    
535
/**
536
 * Handle reply to card data request
537
 */
538
static int
539
cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len)
540
{
541
  int plen, i;
542
  unsigned int nprov;
543
  const char *n;
544

    
545
  msg += 12;
546
  len -= 12;
547

    
548
  if(len < 3) {
549
    tvhlog(LOG_INFO, "cwc", "Invalid card data reply");
550
    return -1;
551
  }
552

    
553
  plen = (msg[1] & 0xf) << 8 | msg[2];
554

    
555
  if(plen < 14) {
556
    tvhlog(LOG_INFO, "cwc", "Invalid card data reply (message)");
557
    return -1;
558
  }
559

    
560
  nprov = msg[14];
561

    
562
  if(plen < nprov * 11) {
563
    tvhlog(LOG_INFO, "cwc", "Invalid card data reply (provider list)");
564
    return -1;
565
  }
566

    
567
  cwc->cwc_connected = 1;
568
  cwc_comet_status_update(cwc);
569
  cwc->cwc_caid = (msg[4] << 8) | msg[5];
570
  n = psi_caid2name(cwc->cwc_caid) ?: "Unknown";
571

    
572
  memcpy(cwc->cwc_ua, &msg[6], 8);
573

    
574
  tvhlog(LOG_INFO, "cwc", "%s: Connected as user 0x%02x "
575
	 "to a %s-card [0x%04x : %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x] "
576
	 "with %d providers", 
577
	 cwc->cwc_hostname,
578
	 msg[3], n, cwc->cwc_caid, 
579
	 cwc->cwc_ua[0], cwc->cwc_ua[1], cwc->cwc_ua[2], cwc->cwc_ua[3], cwc->cwc_ua[4], cwc->cwc_ua[5], cwc->cwc_ua[6], cwc->cwc_ua[7],
580
	 nprov);
581

    
582
  cwc_detect_card_type(cwc);
583

    
584
  msg  += 15;
585
  plen -= 12;
586

    
587
  cwc->cwc_num_providers = nprov;
588

    
589
  for(i = 0; i < nprov; i++) {
590
    cwc->cwc_providers[i].id = (msg[0] << 16) | (msg[1] << 8) | msg[2];
591
    cwc->cwc_providers[i].sa[0] = msg[3];
592
    cwc->cwc_providers[i].sa[1] = msg[4];
593
    cwc->cwc_providers[i].sa[2] = msg[5];
594
    cwc->cwc_providers[i].sa[3] = msg[6];
595
    cwc->cwc_providers[i].sa[4] = msg[7];
596
    cwc->cwc_providers[i].sa[5] = msg[8];
597
    cwc->cwc_providers[i].sa[6] = msg[9];
598
    cwc->cwc_providers[i].sa[7] = msg[10];
599

    
600
    tvhlog(LOG_INFO, "cwc", "%s: Provider ID #%d: 0x%06x %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x",
601
	   cwc->cwc_hostname, i + 1,
602
	   cwc->cwc_providers[i].id,
603
	   cwc->cwc_providers[i].sa[0],
604
	   cwc->cwc_providers[i].sa[1],
605
	   cwc->cwc_providers[i].sa[2],
606
	   cwc->cwc_providers[i].sa[3],
607
	   cwc->cwc_providers[i].sa[4],
608
	   cwc->cwc_providers[i].sa[5],
609
	   cwc->cwc_providers[i].sa[6],
610
	   cwc->cwc_providers[i].sa[7]);
611

    
612
    msg += 11;
613
  }
614

    
615
  cwc->cwc_forward_emm = 0;
616
  if (cwc->cwc_emm) {
617
    int emm_allowed = (cwc->cwc_ua[0] || cwc->cwc_ua[1] ||
618
		       cwc->cwc_ua[2] || cwc->cwc_ua[3] ||
619
		       cwc->cwc_ua[4] || cwc->cwc_ua[5] ||
620
		       cwc->cwc_ua[6] || cwc->cwc_ua[7]);
621

    
622
    if (!emm_allowed) {
623
      tvhlog(LOG_INFO, "cwc", 
624
	     "%s: Will not forward EMMs (not allowed by server)",
625
	     cwc->cwc_hostname);
626
	} else {
627
		tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs",
628
	     cwc->cwc_hostname);
629
      cwc->cwc_forward_emm = 1;
630
    }
631
    
632
	/*
633
    } else if (cwc->cwc_card_type != CARD_UNKNOWN) {
634
      tvhlog(LOG_INFO, "cwc", "%s: Will forward EMMs",
635
	     cwc->cwc_hostname);
636
      cwc->cwc_forward_emm = 1;
637
    } else {
638
      tvhlog(LOG_INFO, "cwc", 
639
	     "%s: Will not forward EMMs (unsupported CA system)",
640
	     cwc->cwc_hostname);
641
    }
642
    */
643
  }
644

    
645
  return 0;
646
}
647

    
648
/**
649
 * Detects the cam card type
650
 * If you want to add another card, have a look at
651
 * http://www.dvbservices.com/identifiers/ca_system_id?page=3
652
 * 
653
 * based on the equivalent in sasc-ng
654
 */
655
static void
656
cwc_detect_card_type(cwc_t *cwc)
657
{
658
  uint8_t c_sys = cwc->cwc_caid >> 8;
659
		
660
  switch(c_sys) {
661
  case 0x17:
662
  case 0x06: 
663
    cwc->cwc_card_type = CARD_IRDETO;
664
    tvhlog(LOG_INFO, "cwc", "%s: irdeto card",
665
	   cwc->cwc_hostname);
666
    break;
667
  case 0x05:
668
    cwc->cwc_card_type = CARD_VIACCESS;
669
    tvhlog(LOG_INFO, "cwc", "%s: viaccess card",
670
	   cwc->cwc_hostname);
671
    break;
672
  case 0x0b:
673
    cwc->cwc_card_type = CARD_CONAX;
674
    tvhlog(LOG_INFO, "cwc", "%s: conax card",
675
	   cwc->cwc_hostname);
676
    break;
677
  case 0x01:
678
    cwc->cwc_card_type = CARD_SECA;
679
    tvhlog(LOG_INFO, "cwc", "%s: seca card",
680
	   cwc->cwc_hostname);
681
  case 0x4a:
682
    cwc->cwc_card_type = CARD_DRE;
683
    tvhlog(LOG_INFO, "cwc", "%s: dre card",
684
	   cwc->cwc_hostname);
685
    break;
686
  default:
687
    cwc->cwc_card_type = CARD_UNKNOWN;
688
    break;
689
  }
690
}
691

    
692
/**
693
 * Login command
694
 */
695
static void
696
cwc_send_login(cwc_t *cwc)
697
{
698
  uint8_t buf[CWS_NETMSGSIZE];
699
  int ul = strlen(cwc->cwc_username) + 1;
700
  int pl = strlen(cwc->cwc_password_salted) + 1;
701

    
702
  buf[0] = MSG_CLIENT_2_SERVER_LOGIN;
703
  buf[1] = 0;
704
  buf[2] = ul + pl;
705
  memcpy(buf + 3,      cwc->cwc_username, ul);
706
  memcpy(buf + 3 + ul, cwc->cwc_password_salted, pl);
707
 
708
  cwc_send_msg(cwc, buf, ul + pl + 3, 0, 0);
709
}
710

    
711

    
712

    
713
static void
714
handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg,
715
		 int len, int seq)
716
{
717
  service_t *t = ct->cs_service;
718
  ecm_pid_t *ep;
719
  char chaninfo[32];
720
  int i;
721
  int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms
722

    
723
  if(es->es_channel != -1) {
724
    snprintf(chaninfo, sizeof(chaninfo), " (channel %d)", es->es_channel);
725
  } else {
726
    chaninfo[0] = 0;
727
  }
728

    
729
  es->es_pending = 0;
730

    
731
  if(len < 19) {
732
    
733
    /* ERROR */
734

    
735
    if(ct->cs_okchannel == es->es_channel)
736
      ct->cs_okchannel = -1;
737

    
738
    if(ct->cs_keystate == CS_FORBIDDEN)
739
      return; // We already know it's bad
740

    
741
    es->es_nok = 1;
742

    
743
    tvhlog(LOG_DEBUG, "cwc", "Received NOK for service \"%s\"%s (seqno: %d "
744
	   "Req delay: %lld ms)", t->s_svcname, chaninfo, seq, delay);
745

    
746
    LIST_FOREACH(ep, &ct->cs_pids, ep_link) {
747
      for(i = 0; i <= ep->ep_last_section; i++)
748
	if(ep->ep_sections[i] == NULL || 
749
	   ep->ep_sections[i]->es_pending ||
750
	   ep->ep_sections[i]->es_nok == 0)
751
	  return;
752
    }
753
    tvhlog(LOG_ERR, "cwc",
754
	   "Can not descramble service \"%s\", access denied (seqno: %d "
755
	   "Req delay: %lld ms)",
756
	   t->s_svcname, seq, delay);
757
    ct->cs_keystate = CS_FORBIDDEN;
758
    return;
759

    
760
  } else {
761

    
762
    ct->cs_okchannel = es->es_channel;
763
    es->es_nok = 0;
764

    
765
    tvhlog(LOG_DEBUG, "cwc",
766
	   "Received ECM reply%s for service \"%s\" "
767
	   "even: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"
768
	   " odd: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x (seqno: %d "
769
	   "Req delay: %lld ms)",
770
	   chaninfo,
771
	   t->s_svcname,
772
	   msg[3 + 0], msg[3 + 1], msg[3 + 2], msg[3 + 3], msg[3 + 4],
773
	   msg[3 + 5], msg[3 + 6], msg[3 + 7], msg[3 + 8], msg[3 + 9],
774
	   msg[3 + 10],msg[3 + 11],msg[3 + 12],msg[3 + 13],msg[3 + 14],
775
	   msg[3 + 15], seq, delay);
776
    
777
    if(ct->cs_keystate != CS_RESOLVED)
778
      tvhlog(LOG_INFO, "cwc",
779
	     "Obtained key for for service \"%s\" in %lld ms, from %s",
780
	     t->s_svcname, delay, ct->cs_cwc->cwc_hostname);
781
    
782
    ct->cs_keystate = CS_RESOLVED;
783
    memcpy(ct->cs_cw, msg + 3, 16);
784
    ct->cs_pending_cw_update = 1;
785
  }
786
}
787

    
788

    
789
/**
790
 * Handle running reply
791
 * cwc_mutex is held
792
 */
793
static int
794
cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len)
795
{
796
  cwc_service_t *ct;
797
  ecm_pid_t *ep;
798
  ecm_section_t *es;
799
  uint16_t seq = (msg[2] << 8) | msg[3];
800
  int i;
801

    
802
  len -= 12;
803
  msg += 12;
804

    
805
  switch(msgtype) {
806
  case 0x80:
807
  case 0x81:
808
    LIST_FOREACH(ct, &cwc->cwc_services, cs_link) {
809
      LIST_FOREACH(ep, &ct->cs_pids, ep_link) {
810
	for(i = 0; i <= ep->ep_last_section; i++) {
811
	  es = ep->ep_sections[i];
812
	  if(es != NULL) {
813
	    if(es->es_seq == seq && es->es_pending) {
814
	      handle_ecm_reply(ct, es, msg, len, seq);
815
	      return 0;
816
	    }
817
	  }
818
	}
819
      }
820
    }
821
    tvhlog(LOG_WARNING, "cwc", "Got unexpected ECM reply (seqno: %d)", seq);
822
    break;
823
  }
824
  return 0;
825
}
826

    
827

    
828

    
829
/**
830
 *
831
 */
832
static int
833
cwc_must_break(cwc_t *cwc)
834
{
835
  return !cwc->cwc_running || !cwc->cwc_enabled || cwc->cwc_reconfigure;
836
}
837

    
838
/**
839
 *
840
 */
841
static int
842
cwc_read(cwc_t *cwc, void *buf, size_t len, int timeout)
843
{
844
  int r;
845

    
846
  pthread_mutex_unlock(&cwc_mutex);
847
  r = tcp_read_timeout(cwc->cwc_fd, buf, len, timeout);
848
  pthread_mutex_lock(&cwc_mutex);
849

    
850
  if(cwc_must_break(cwc))
851
    return ECONNABORTED;
852

    
853
  return r;
854
}
855

    
856

    
857
/**
858
 *
859
 */
860
static int
861
cwc_read_message(cwc_t *cwc, const char *state, int timeout)
862
{
863
  char buf[2];
864
  int msglen, r;
865

    
866
  if((r = cwc_read(cwc, buf, 2, timeout))) {
867
    tvhlog(LOG_INFO, "cwc", "%s: %s: Read error (header): %s",
868
	   cwc->cwc_hostname, state, strerror(r));
869
    return -1;
870
  }
871

    
872
  msglen = (buf[0] << 8) | buf[1];
873
  if(msglen >= CWS_NETMSGSIZE) {
874
    tvhlog(LOG_INFO, "cwc", "%s: %s: Invalid message size: %d",
875
	   cwc->cwc_hostname, state, msglen);
876
    return -1;
877
  }
878

    
879
  /* We expect the rest of the message to arrive fairly quick,
880
     so just wait 1 second here */
881

    
882
  if((r = cwc_read(cwc, cwc->cwc_buf + 2, msglen, 1000))) {
883
    tvhlog(LOG_INFO, "cwc", "%s: %s: Read error: %s",
884
	   cwc->cwc_hostname, state, strerror(r));
885
    return -1;
886
  }
887

    
888
  if((msglen = des_decrypt(cwc->cwc_buf, msglen + 2, cwc)) < 15) {
889
    tvhlog(LOG_INFO, "cwc", "%s: %s: Decrypt failed",
890
	   state, cwc->cwc_hostname);
891
    return -1;
892
  }
893
  return msglen;
894
}
895

    
896
/**
897
 *
898
 */
899
static void *
900
cwc_writer_thread(void *aux)
901
{
902
  cwc_t *cwc = aux;
903
  cwc_message_t *cm;
904
  struct timespec ts;
905
  int r;
906

    
907
  pthread_mutex_lock(&cwc->cwc_writer_mutex);
908

    
909
  while(cwc->cwc_writer_running) {
910

    
911
    if((cm = TAILQ_FIRST(&cwc->cwc_writeq)) != NULL) {
912
      TAILQ_REMOVE(&cwc->cwc_writeq, cm, cm_link);
913
      pthread_mutex_unlock(&cwc->cwc_writer_mutex);
914
      //      int64_t ts = getmonoclock();
915
      r = write(cwc->cwc_fd, cm->cm_data, cm->cm_len);
916
      //      printf("Write took %lld usec\n", getmonoclock() - ts);
917
      free(cm);
918
      pthread_mutex_lock(&cwc->cwc_writer_mutex);
919
      continue;
920
    }
921

    
922

    
923
    /* If nothing is to be sent in CWC_KEEPALIVE_INTERVAL seconds we
924
       need to send a keepalive */
925
    ts.tv_sec  = time(NULL) + CWC_KEEPALIVE_INTERVAL;
926
    ts.tv_nsec = 0;
927
    r = pthread_cond_timedwait(&cwc->cwc_writer_cond, 
928
			       &cwc->cwc_writer_mutex, &ts);
929
    if(r == ETIMEDOUT)
930
      cwc_send_ka(cwc);
931
  }
932

    
933
  pthread_mutex_unlock(&cwc->cwc_writer_mutex);
934
  return NULL;
935
}
936

    
937

    
938

    
939
/**
940
 *
941
 */
942
static void
943
cwc_session(cwc_t *cwc)
944
{
945
  int r;
946
  pthread_t writer_thread_id;
947

    
948
  /**
949
   * Get login key
950
   */
951
  if((r = cwc_read(cwc, cwc->cwc_buf, 14, 5000))) {
952
    tvhlog(LOG_INFO, "cwc", "%s: No login key received: %s",
953
	   cwc->cwc_hostname, strerror(r));
954
    return;
955
  }
956

    
957
  des_make_login_key(cwc, cwc->cwc_buf);
958

    
959
  /**
960
   * Login
961
   */
962
  cwc_send_login(cwc);
963
  
964
  if(cwc_read_message(cwc, "Wait login response", 5000) < 0)
965
    return;
966

    
967
  if(cwc->cwc_buf[12] != MSG_CLIENT_2_SERVER_LOGIN_ACK) {
968
    tvhlog(LOG_INFO, "cwc", "%s: Login failed", cwc->cwc_hostname);
969
    return;
970
  }
971

    
972
  des_make_session_key(cwc);
973

    
974
  /**
975
   * Request card data
976
   */
977
  cwc_send_data_req(cwc);
978
  if((r = cwc_read_message(cwc, "Request card data", 5000)) < 0)
979
    return;
980

    
981
  if(cwc->cwc_buf[12] != MSG_CARD_DATA) {
982
    tvhlog(LOG_INFO, "cwc", "%s: Card data request failed", cwc->cwc_hostname);
983
    return;
984
  }
985

    
986
  if(cwc_decode_card_data_reply(cwc, cwc->cwc_buf, r) < 0)
987
    return;
988

    
989
  /**
990
   * Ok, connection good, reset retry delay to zero
991
   */
992
  cwc->cwc_retry_delay = 0;
993

    
994
  /**
995
   * We do all requests from now on in a separate thread
996
   */
997
  cwc->cwc_writer_running = 1;
998
  pthread_cond_init(&cwc->cwc_writer_cond, NULL);
999
  pthread_mutex_init(&cwc->cwc_writer_mutex, NULL);
1000
  TAILQ_INIT(&cwc->cwc_writeq);
1001
  pthread_create(&writer_thread_id, NULL, cwc_writer_thread, cwc);
1002

    
1003
  /**
1004
   * Mainloop
1005
   */
1006
  while(!cwc_must_break(cwc)) {
1007

    
1008
    if((r = cwc_read_message(cwc, "Decoderloop", 
1009
			     CWC_KEEPALIVE_INTERVAL * 2 * 1000)) < 0)
1010
      break;
1011
    cwc_running_reply(cwc, cwc->cwc_buf[12], cwc->cwc_buf, r);
1012
  }
1013

    
1014
  /**
1015
   * Collect the writer thread
1016
   */
1017
  shutdown(cwc->cwc_fd, SHUT_RDWR);
1018
  cwc->cwc_writer_running = 0;
1019
  pthread_cond_signal(&cwc->cwc_writer_cond);
1020
  pthread_join(writer_thread_id, NULL);
1021
  tvhlog(LOG_DEBUG, "cwc", "Write thread joined");
1022
}
1023

    
1024

    
1025
/**
1026
 *
1027
 */
1028
static void *
1029
cwc_thread(void *aux)
1030
{
1031
  cwc_service_t *ct;
1032
  cwc_t *cwc = aux;
1033
  int fd, d;
1034
  char errbuf[100];
1035
  service_t *t;
1036
  char hostname[256];
1037
  int port;
1038
  struct timespec ts;
1039
  int attempts = 0;
1040

    
1041
  pthread_mutex_lock(&cwc_mutex);
1042

    
1043
  while(cwc->cwc_running) {
1044
    
1045
    while(cwc->cwc_running && cwc->cwc_enabled == 0)
1046
      pthread_cond_wait(&cwc->cwc_cond, &cwc_mutex);
1047

    
1048
    snprintf(hostname, sizeof(hostname), "%s", cwc->cwc_hostname);
1049
    port = cwc->cwc_port;
1050

    
1051
    tvhlog(LOG_INFO, "cwc", "Attemping to connect to %s:%d", hostname, port);
1052

    
1053
    pthread_mutex_unlock(&cwc_mutex);
1054

    
1055
    fd = tcp_connect(hostname, port, errbuf, sizeof(errbuf), 10);
1056

    
1057
    pthread_mutex_lock(&cwc_mutex);
1058

    
1059
    if(fd == -1) {
1060
      attempts++;
1061
      tvhlog(LOG_INFO, "cwc", 
1062
	     "Connection attempt to %s:%d failed: %s",
1063
	     hostname, port, errbuf);
1064
    } else {
1065

    
1066
      if(cwc->cwc_running == 0) {
1067
	close(fd);
1068
	break;
1069
      }
1070

    
1071
      tvhlog(LOG_INFO, "cwc", "Connected to %s:%d", hostname, port);
1072
      attempts = 0;
1073

    
1074
      cwc->cwc_fd = fd;
1075
      cwc->cwc_reconfigure = 0;
1076

    
1077
      cwc_session(cwc);
1078

    
1079
      cwc->cwc_fd = -1;
1080
      close(fd);
1081
      cwc->cwc_caid = 0;
1082
      cwc->cwc_connected = 0;
1083
      cwc_comet_status_update(cwc);
1084
      tvhlog(LOG_INFO, "cwc", "Disconnected from %s",  cwc->cwc_hostname);
1085
    }
1086

    
1087
    if(subscriptions_active()) {
1088
      if(attempts == 1)
1089
	continue; // Retry immediately
1090
      d = 3;
1091
    } else {
1092
      d = 60;
1093
    }
1094

    
1095
    ts.tv_sec = time(NULL) + d;
1096
    ts.tv_nsec = 0;
1097

    
1098
    tvhlog(LOG_INFO, "cwc", 
1099
	   "%s: Automatic connection attempt in in %d seconds",
1100
	   cwc->cwc_hostname, d);
1101

    
1102
    pthread_cond_timedwait(&cwc_config_changed, &cwc_mutex, &ts);
1103
  }
1104

    
1105
  tvhlog(LOG_INFO, "cwc", "%s destroyed", cwc->cwc_hostname);
1106

    
1107
  while((ct = LIST_FIRST(&cwc->cwc_services)) != NULL) {
1108
    t = ct->cs_service;
1109
    pthread_mutex_lock(&t->s_stream_mutex);
1110
    cwc_service_destroy(&ct->cs_head);
1111
    pthread_mutex_unlock(&t->s_stream_mutex);
1112
  }
1113

    
1114
  free((void *)cwc->cwc_password);
1115
  free((void *)cwc->cwc_password_salted);
1116
  free((void *)cwc->cwc_username);
1117
  free((void *)cwc->cwc_hostname);
1118
  free(cwc);
1119

    
1120
  pthread_mutex_unlock(&cwc_mutex);
1121
  return NULL;
1122
}
1123

    
1124

    
1125
/**
1126
 *
1127
 */
1128
static int
1129
verify_provider(cwc_t *cwc, uint32_t providerid)
1130
{
1131
  int i;
1132

    
1133
  if(providerid == 0)
1134
    return 1;
1135
  
1136
  for(i = 0; i < cwc->cwc_num_providers; i++) 
1137
    if(providerid == cwc->cwc_providers[i].id)
1138
      return 1;
1139
  return 0;
1140
}
1141

    
1142
/**
1143
 *
1144
 */
1145
static void
1146
cwc_emm_cache_insert(cwc_t *cwc, uint32_t crc)
1147
{
1148
  /* evict the oldest entry */
1149
  cwc->cwc_emm_cache.cache[cwc->cwc_emm_cache.w] = crc;
1150
  cwc->cwc_emm_cache.w = (cwc->cwc_emm_cache.w+1)&EMM_CACHE_MASK;
1151
  if (cwc->cwc_emm_cache.n < EMM_CACHE_SIZE)
1152
    cwc->cwc_emm_cache.n++;
1153
}
1154

    
1155
static int
1156
cwc_emm_cache_lookup(cwc_t *cwc, uint32_t crc)
1157
{
1158
  int i;
1159
  for (i=0; i<cwc->cwc_emm_cache.n; i++)
1160
    if (cwc->cwc_emm_cache.cache[i] == crc)
1161
      return 1;
1162
  return 0;
1163
}
1164

    
1165

    
1166
/**
1167
 *
1168
 */
1169
void
1170
cwc_emm(uint8_t *data, int len)
1171
{
1172
  cwc_t *cwc;
1173

    
1174
  pthread_mutex_lock(&cwc_mutex);
1175

    
1176
  TAILQ_FOREACH(cwc, &cwcs, cwc_link) {
1177
    if(cwc->cwc_forward_emm && cwc->cwc_writer_running) {
1178
      switch (cwc->cwc_card_type) {
1179
      case CARD_CONAX:
1180
	cwc_emm_conax(cwc, data, len);
1181
	break;
1182
      case CARD_IRDETO:
1183
	cwc_emm_irdeto(cwc, data, len);
1184
	break;
1185
      case CARD_SECA:
1186
	cwc_emm_seca(cwc, data, len);
1187
	break;
1188
      case CARD_VIACCESS:
1189
	cwc_emm_viaccess(cwc, data, len);
1190
	break;
1191
      case CARD_DRE:
1192
	cwc_emm_dre(cwc, data, len);
1193
	break;
1194
      case CARD_UNKNOWN:
1195
	break;
1196
      }
1197
    }
1198
  }
1199
  pthread_mutex_unlock(&cwc_mutex);
1200
}
1201

    
1202

    
1203
/**
1204
 * conax emm handler
1205
 */
1206
void
1207
cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len)
1208
{
1209
  if (data[0] == 0x82) {
1210
    int i;
1211
    for (i=0; i < cwc->cwc_num_providers; i++) {
1212
      if (memcmp(&data[3], &cwc->cwc_providers[i].sa[1], 7) == 0) {
1213
        cwc_send_msg(cwc, data, len, 0, 1);
1214
        break;
1215
      }
1216
    }
1217
  }
1218
}
1219

    
1220

    
1221
/**
1222
 * irdeto emm handler
1223
 * inspired by opensasc-ng, https://opensvn.csie.org/traccgi/opensascng/
1224
 */
1225
void
1226
cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len)
1227
{
1228
  int emm_mode = data[3] >> 3;
1229
  int emm_len = data[3] & 0x07;
1230
  int match = 0;
1231
  
1232
  if (emm_mode & 0x10){
1233
    // try to match card
1234
    match = (emm_mode == cwc->cwc_ua[4] && 
1235
	     (!emm_len || // zero length
1236
	      !memcmp(&data[4], &cwc->cwc_ua[5], emm_len))); // exact match
1237
  } else {
1238
    // try to match provider
1239
    int i;
1240
    for(i=0; i < cwc->cwc_num_providers; i++) {
1241
      match = (emm_mode == cwc->cwc_providers[i].sa[4] && 
1242
	       (!emm_len || // zero length
1243
		!memcmp(&data[4], &cwc->cwc_providers[i].sa[5], emm_len)));
1244
      // exact match
1245
      if (match) break;
1246
    }
1247
  }
1248
  
1249
  if (match)
1250
    cwc_send_msg(cwc, data, len, 0, 1);
1251
}
1252

    
1253

    
1254
/**
1255
 * seca emm handler
1256
 * inspired by opensasc-ng, https://opensvn.csie.org/traccgi/opensascng/
1257
 */
1258
void
1259
cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len)
1260
{
1261
  int match = 0;
1262

    
1263
  if (data[0] == 0x82) {
1264
    if (memcmp(&data[3], &cwc->cwc_ua[2], 6) == 0) {
1265
      match = 1;
1266
    }
1267
  } 
1268
  else if (data[0] == 0x84) {
1269
    /* XXX this part is untested but should do no harm */
1270
    int i;
1271
    for (i=0; i < cwc->cwc_num_providers; i++) {
1272
      if (memcmp(&data[5], &cwc->cwc_providers[i].sa[5], 3) == 0) {
1273
        match = 1;
1274
        break;
1275
      }
1276
    }
1277
  }
1278

    
1279
  if (match)
1280
    cwc_send_msg(cwc, data, len, 0, 1);
1281
}
1282

    
1283
/**
1284
 * viaccess emm handler
1285
 * inspired by opensasc-ng, https://opensvn.csie.org/traccgi/opensascng/
1286
 */
1287
static
1288
uint8_t * nano_start(uint8_t * data)
1289
{
1290
  switch(data[0]) {
1291
  case 0x88: return &data[8];
1292
  case 0x8e: return &data[7];
1293
  case 0x8c:
1294
  case 0x8d: return &data[3];
1295
  case 0x80:
1296
  case 0x81: return &data[4];
1297
  }
1298
  return NULL;
1299
}
1300

    
1301
static
1302
uint8_t * nano_checknano90fromnano(uint8_t * data)
1303
{
1304
  if(data && data[0]==0x90 && data[1]==0x03) return data;
1305
  return 0;
1306
}
1307

    
1308
static
1309
uint8_t * nano_checknano90(uint8_t * data)
1310
{
1311
  return nano_checknano90fromnano(nano_start(data));
1312
}
1313

    
1314
static
1315
int sort_nanos(uint8_t *dest, const uint8_t *src, int len)
1316
{
1317
  int w = 0, c = -1;
1318

    
1319
  while (1) {
1320
    int j, n;
1321
    n = 0x100;
1322
    for (j = 0; j < len;) {
1323
      int l = src[j + 1] + 2;
1324
      if (src[j] == c) {
1325
	if (w + l > len) {
1326
	  return -1;
1327
	}
1328
	memcpy(dest + w, src + j, l);
1329
	w += l;
1330
      }
1331
      else if (src[j] > c && src[j] < n) {
1332
	n = src[j];
1333
      }
1334
      j += l;
1335
    }
1336
    if (n == 0x100) {
1337
      break;
1338
    }
1339
    c = n;
1340
  }
1341
  return 0;
1342
}
1343

    
1344
static int via_provider_id(uint8_t * data)
1345
{
1346
  const uint8_t * tmp;
1347
  tmp = nano_checknano90(data);
1348
  if (!tmp) return 0;
1349
  return (tmp[2] << 16) | (tmp[3] << 8) | (tmp[4]&0xf0);
1350
}
1351

    
1352

    
1353
void
1354
cwc_emm_viaccess(cwc_t *cwc, uint8_t *data, int mlen)
1355
{
1356
  /* Get SCT len */
1357
  int len = 3 + ((data[1] & 0x0f) << 8) + data[2];
1358

    
1359
  switch (data[0])
1360
    {
1361
    case 0x8c:
1362
    case 0x8d:
1363
      {
1364
	int match = 0;
1365
	int i;
1366
	uint32_t id;
1367

    
1368
	/* Match provider id */
1369
	id = via_provider_id(data);
1370
	if (!id) break;
1371

    
1372
	for(i = 0; i < cwc->cwc_num_providers; i++)
1373
	  if(cwc->cwc_providers[i].id == id) {
1374
	    match = 1;
1375
	    break;
1376
	  }
1377
	if (!match) break;
1378

    
1379
	if (data[0] != cwc->cwc_viaccess_emm.shared_toggle) {
1380
	  cwc->cwc_viaccess_emm.shared_len = 0;
1381
	  free(cwc->cwc_viaccess_emm.shared_emm);
1382
	  cwc->cwc_viaccess_emm.shared_emm = (uint8_t*)malloc(len);
1383
	  if (cwc->cwc_viaccess_emm.shared_emm) {
1384
	    cwc->cwc_viaccess_emm.shared_len = len;
1385
	    memcpy(cwc->cwc_viaccess_emm.shared_emm, data, len);
1386
	  }
1387
	  cwc->cwc_viaccess_emm.shared_toggle = data[0];
1388
	}
1389
      }
1390
      break;
1391
    case 0x8e:
1392
      if (cwc->cwc_viaccess_emm.shared_emm) {
1393
	int match = 0;
1394
	int i;
1395
	/* Match SA and provider in shared */
1396
	for(i = 0; i < cwc->cwc_num_providers; i++) {
1397
	  if(memcmp(&data[3],&cwc->cwc_providers[i].sa[4], 3)) continue;
1398
	  if((data[6]&2)) continue;
1399
	  if(via_provider_id(cwc->cwc_viaccess_emm.shared_emm) != cwc->cwc_providers[i].id) continue;
1400
	  match = 1;
1401
	  break;
1402
	}
1403
	if (!match) break;
1404

    
1405
	uint8_t * tmp = alloca(len + cwc->cwc_viaccess_emm.shared_len);
1406
	uint8_t * ass = nano_start(data);
1407
	len -= (ass - data);
1408
	if((data[6] & 2) == 0)  {
1409
	  int addrlen = len - 8;
1410
	  len=0;
1411
	  tmp[len++] = 0x9e;
1412
	  tmp[len++] = addrlen;
1413
	  memcpy(&tmp[len], &ass[0], addrlen); len += addrlen;
1414
	  tmp[len++] = 0xf0;
1415
	  tmp[len++] = 0x08;
1416
	  memcpy(&tmp[len],&ass[addrlen],8); len += 8;
1417
	} else {
1418
	  memcpy(tmp, ass, len);
1419
	}
1420
	ass = nano_start(cwc->cwc_viaccess_emm.shared_emm);
1421
	int l = cwc->cwc_viaccess_emm.shared_len - (ass - cwc->cwc_viaccess_emm.shared_emm);
1422
	memcpy(&tmp[len], ass, l); len += l;
1423

    
1424
	ass = (uint8_t*) alloca(len+7);
1425
	if(ass) {
1426
	  uint32_t crc;
1427

    
1428
	  memcpy(ass, data, 7);
1429
	  if (sort_nanos(ass + 7, tmp, len)) {
1430
	    return;
1431
	  }
1432

    
1433
	  /* Set SCT len */
1434
	  len += 4;
1435
	  ass[1] = (len>>8) | 0x70;
1436
	  ass[2] = len & 0xff;
1437
	  len += 3;
1438

    
1439
	  crc = crc32(ass, len, 0xffffffff);
1440
	  if (!cwc_emm_cache_lookup(cwc, crc)) {
1441
	    tvhlog(LOG_DEBUG, "cwc",
1442
		   "Send EMM "
1443
		   "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x"
1444
		   "...%02x.%02x.%02x.%02x",
1445
		   ass[0], ass[1], ass[2], ass[3],
1446
		   ass[4], ass[5], ass[6], ass[7],
1447
		   ass[len-4], ass[len-3], ass[len-2], ass[len-1]);
1448
	    cwc_send_msg(cwc, ass, len, 0, 1);
1449
	    cwc_emm_cache_insert(cwc, crc);
1450
	  }
1451
	}
1452
      }
1453
      break;
1454
    }
1455
}
1456

    
1457
/**
1458
 * t->s_streaming_mutex is held
1459
 */
1460
static void
1461
cwc_table_input(struct th_descrambler *td, struct service *t,
1462
		struct elementary_stream *st, const uint8_t *data, int len)
1463
{
1464
  cwc_service_t *ct = (cwc_service_t *)td;
1465
  uint16_t sid = t->s_dvb_service_id;
1466
  cwc_t *cwc = ct->cs_cwc;
1467
  int channel;
1468
  int section;
1469
  ecm_pid_t *ep;
1470
  ecm_section_t *es;
1471
  char chaninfo[32];
1472
  caid_t *c;
1473

    
1474
  if(len > 4096)
1475
    return;
1476

    
1477
  if((data[0] & 0xf0) != 0x80)
1478
    return;
1479

    
1480
  LIST_FOREACH(ep, &ct->cs_pids, ep_link) {
1481
    if(ep->ep_pid == st->es_pid)
1482
      break;
1483
  }
1484

    
1485
  if(ep == NULL) {
1486
    ep = calloc(1, sizeof(ecm_pid_t));
1487
    ep->ep_pid = st->es_pid;
1488
    LIST_INSERT_HEAD(&ct->cs_pids, ep, ep_link);
1489
  }
1490

    
1491

    
1492
  LIST_FOREACH(c, &st->es_caids, link) {
1493
    if(cwc->cwc_caid == c->caid)
1494
      break;
1495
  }
1496

    
1497
  if(c == NULL)
1498
    return;
1499

    
1500
  if(!verify_provider(cwc, c->providerid))
1501
    return;
1502

    
1503
  switch(data[0]) {
1504
  case 0x80:
1505
  case 0x81:
1506
    /* ECM */
1507
    
1508
    if(cwc->cwc_caid >> 8 == 6) {
1509
      channel = data[6] << 8 | data[7];
1510
      snprintf(chaninfo, sizeof(chaninfo), " (channel %d)", channel);
1511
      ep->ep_last_section = data[5]; 
1512
      section = data[4];
1513
    } else {
1514
      channel = -1;
1515
      chaninfo[0] = 0;
1516
      ep->ep_last_section = 0; 
1517
      section = 0;
1518
    }
1519

    
1520
    if(ep->ep_sections[section] == NULL)
1521
      ep->ep_sections[section] = calloc(1, sizeof(ecm_section_t));
1522

    
1523
    es = ep->ep_sections[section];
1524

    
1525
    if(es->es_ecmsize == len && !memcmp(es->es_ecm, data, len))
1526
      break; /* key already sent */
1527

    
1528
    if(cwc->cwc_fd == -1) {
1529
      // New key, but we are not connected (anymore), can not descramble
1530
      ct->cs_keystate = CS_UNKNOWN;
1531
      break;
1532
    }
1533

    
1534
    es->es_channel = channel;
1535
    es->es_section = section;
1536
    es->es_pending = 1;
1537

    
1538
    memcpy(es->es_ecm, data, len);
1539
    es->es_ecmsize = len;
1540

    
1541
    if(ct->cs_okchannel != -1 && channel != -1 && 
1542
       ct->cs_okchannel != channel) {
1543
      tvhlog(LOG_DEBUG, "cwc", "Filtering ECM channel %d", channel);
1544
      return;
1545
    }
1546

    
1547
    es->es_seq = cwc_send_msg(cwc, data, len, sid, 1);
1548

    
1549
    tvhlog(LOG_DEBUG, "cwc", 
1550
	   "Sending ECM%s section=%d/%d, for service %s (seqno: %d) PID %d", 
1551
	   chaninfo, section, ep->ep_last_section, t->s_svcname, es->es_seq,
1552
	   st->es_pid);
1553
    es->es_time = getmonoclock();
1554
    break;
1555

    
1556
  default:
1557
    /* EMM */
1558
    if (cwc->cwc_forward_emm)
1559
      cwc_send_msg(cwc, data, len, sid, 1);
1560
    break;
1561
  }
1562
}
1563

    
1564
/**
1565
 * dre emm handler
1566
 */
1567
void
1568
cwc_emm_dre(cwc_t *cwc, uint8_t *data, int len)
1569
{
1570
  int match = 0;
1571

    
1572
  if (data[0] == 0x87) {
1573
    if (memcmp(&data[3], &cwc->cwc_ua[4], 4) == 0) {
1574
      match = 1;
1575
    }
1576
  } 
1577
  else if (data[0] == 0x86) {
1578
    int i;
1579
    for (i=0; i < cwc->cwc_num_providers; i++) {
1580
      if (memcmp(&data[40], &cwc->cwc_providers[i].sa[4], 4) == 0) {
1581
/*      if (memcmp(&data[3], &cwc->cwc_providers[i].sa[4], 1) == 0) { */
1582
        match = 1;
1583
        break;
1584
      }
1585
    }
1586
  }
1587

    
1588
  if (match)
1589
    cwc_send_msg(cwc, data, len, 0, 1);
1590
}
1591

    
1592

    
1593
/**
1594
 *
1595
 */
1596
static void
1597
update_keys(cwc_service_t *ct)
1598
{
1599
  int i;
1600
  ct->cs_pending_cw_update = 0;
1601
  for(i = 0; i < 8; i++)
1602
    if(ct->cs_cw[i]) {
1603
      set_even_control_word(ct->cs_keys, ct->cs_cw);
1604
      break;
1605
    }
1606
  
1607
  for(i = 0; i < 8; i++)
1608
    if(ct->cs_cw[8 + i]) {
1609
      set_odd_control_word(ct->cs_keys, ct->cs_cw + 8);
1610
      break;
1611
    }
1612
}
1613

    
1614

    
1615
/**
1616
 *
1617
 */
1618
static int
1619
cwc_descramble(th_descrambler_t *td, service_t *t, struct elementary_stream *st,
1620
	       const uint8_t *tsb)
1621
{
1622
  cwc_service_t *ct = (cwc_service_t *)td;
1623
  int r;
1624
  unsigned char *vec[3];
1625

    
1626
  if(ct->cs_keystate == CS_FORBIDDEN)
1627
    return 1;
1628

    
1629
  if(ct->cs_keystate != CS_RESOLVED)
1630
    return -1;
1631

    
1632
  if(ct->cs_fill == 0 && ct->cs_pending_cw_update)
1633
    update_keys(ct);
1634

    
1635
  memcpy(ct->cs_tsbcluster + ct->cs_fill * 188, tsb, 188);
1636
  ct->cs_fill++;
1637

    
1638
  if(ct->cs_fill != ct->cs_cluster_size)
1639
    return 0;
1640

    
1641
  while(1) {
1642

    
1643
    vec[0] = ct->cs_tsbcluster;
1644
    vec[1] = ct->cs_tsbcluster + ct->cs_fill * 188;
1645
    vec[2] = NULL;
1646
    
1647
    r = decrypt_packets(ct->cs_keys, vec);
1648
    if(r > 0) {
1649
      int i;
1650
      const uint8_t *t0 = ct->cs_tsbcluster;
1651

    
1652
      for(i = 0; i < r; i++) {
1653
	ts_recv_packet2(t, t0);
1654
	t0 += 188;
1655
      }
1656

    
1657
      r = ct->cs_fill - r;
1658
      assert(r >= 0);
1659

    
1660
      if(r > 0)
1661
	memmove(ct->cs_tsbcluster, t0, r * 188);
1662
      ct->cs_fill = r;
1663

    
1664
      if(ct->cs_pending_cw_update && r > 0)
1665
	continue;
1666
    } else {
1667
      ct->cs_fill = 0;
1668
    }
1669
    break;
1670
  }
1671
  if(ct->cs_pending_cw_update)
1672
    update_keys(ct);
1673

    
1674
  return 0;
1675
}
1676

    
1677
/**
1678
 * cwc_mutex is held
1679
 * s_stream_mutex is held
1680
 */
1681
static void 
1682
cwc_service_destroy(th_descrambler_t *td)
1683
{
1684
  cwc_service_t *ct = (cwc_service_t *)td;
1685
  ecm_pid_t *ep;
1686
  int i;
1687

    
1688
  while((ep = LIST_FIRST(&ct->cs_pids)) != NULL) {
1689
    for(i = 0; i < 256; i++)
1690
      free(ep->ep_sections[i]);
1691
    LIST_REMOVE(ep, ep_link);
1692
    free(ep);
1693
  }
1694

    
1695
  LIST_REMOVE(td, td_service_link);
1696

    
1697
  LIST_REMOVE(ct, cs_link);
1698

    
1699
  free_key_struct(ct->cs_keys);
1700
  free(ct->cs_tsbcluster);
1701
  free(ct);
1702
}
1703

    
1704
/**
1705
 *
1706
 */
1707
static inline elementary_stream_t *
1708
cwc_find_stream_by_caid(service_t *t, int caid)
1709
{
1710
  elementary_stream_t *st;
1711
  caid_t *c;
1712

    
1713
  TAILQ_FOREACH(st, &t->s_components, es_link) {
1714
    LIST_FOREACH(c, &st->es_caids, link) {
1715
      if(c->caid == caid)
1716
	return st;
1717
    }
1718
  }
1719
  return NULL;
1720
}
1721

    
1722

    
1723
/**
1724
 * Check if our CAID's matches, and if so, link
1725
 *
1726
 * global_lock is held. Not that we care about that, but either way, it is.
1727
 */
1728
void
1729
cwc_service_start(service_t *t)
1730
{
1731
  cwc_t *cwc;
1732
  cwc_service_t *ct;
1733
  th_descrambler_t *td;
1734

    
1735
  pthread_mutex_lock(&cwc_mutex);
1736
  TAILQ_FOREACH(cwc, &cwcs, cwc_link) {
1737
    if(cwc->cwc_caid == 0)
1738
      continue;
1739

    
1740
    if(cwc_find_stream_by_caid(t, cwc->cwc_caid) == NULL)
1741
      continue;
1742

    
1743
    ct = calloc(1, sizeof(cwc_service_t));
1744
    ct->cs_cluster_size = get_suggested_cluster_size();
1745
    ct->cs_tsbcluster = malloc(ct->cs_cluster_size * 188);
1746

    
1747
    ct->cs_keys = get_key_struct();
1748
    ct->cs_cwc = cwc;
1749
    ct->cs_service = t;
1750
    ct->cs_okchannel = -1;
1751

    
1752
    td = &ct->cs_head;
1753
    td->td_stop       = cwc_service_destroy;
1754
    td->td_table      = cwc_table_input;
1755
    td->td_descramble = cwc_descramble;
1756
    LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link);
1757

    
1758
    LIST_INSERT_HEAD(&cwc->cwc_services, ct, cs_link);
1759

    
1760
    tvhlog(LOG_DEBUG, "cwc", "%s using CWC %s:%d",
1761
	   service_nicename(t), cwc->cwc_hostname, cwc->cwc_port);
1762

    
1763
  }
1764
  pthread_mutex_unlock(&cwc_mutex);
1765
}
1766

    
1767

    
1768
/**
1769
 *
1770
 */
1771
static void
1772
cwc_destroy(cwc_t *cwc)
1773
{
1774
  pthread_mutex_lock(&cwc_mutex);
1775
  TAILQ_REMOVE(&cwcs, cwc, cwc_link);  
1776
  cwc->cwc_running = 0;
1777
  pthread_cond_signal(&cwc->cwc_cond);
1778
  pthread_mutex_unlock(&cwc_mutex);
1779
}
1780

    
1781

    
1782
/**
1783
 *
1784
 */
1785
static cwc_t *
1786
cwc_entry_find(const char *id, int create)
1787
{
1788
  pthread_attr_t attr;
1789
  pthread_t ptid;
1790
  char buf[20];
1791
  cwc_t *cwc;
1792
  static int tally;
1793

    
1794
  if(id != NULL) {
1795
    TAILQ_FOREACH(cwc, &cwcs, cwc_link)
1796
      if(!strcmp(cwc->cwc_id, id))
1797
	return cwc;
1798
  }
1799
  if(create == 0)
1800
    return NULL;
1801

    
1802
  if(id == NULL) {
1803
    tally++;
1804
    snprintf(buf, sizeof(buf), "%d", tally);
1805
    id = buf;
1806
  } else {
1807
    tally = MAX(atoi(id), tally);
1808
  }
1809

    
1810
  cwc = calloc(1, sizeof(cwc_t));
1811
  pthread_cond_init(&cwc->cwc_cond, NULL);
1812
  cwc->cwc_id = strdup(id); 
1813
  cwc->cwc_running = 1;
1814
  TAILQ_INSERT_TAIL(&cwcs, cwc, cwc_link);  
1815

    
1816
  pthread_attr_init(&attr);
1817
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1818
  pthread_create(&ptid, &attr, cwc_thread, cwc);
1819
  pthread_attr_destroy(&attr);
1820

    
1821
  return cwc;
1822
}
1823

    
1824

    
1825
/**
1826
 *
1827
 */
1828
static htsmsg_t *
1829
cwc_record_build(cwc_t *cwc)
1830
{
1831
  htsmsg_t *e = htsmsg_create_map();
1832
  char buf[100];
1833

    
1834
  htsmsg_add_str(e, "id", cwc->cwc_id);
1835
  htsmsg_add_u32(e, "enabled",  !!cwc->cwc_enabled);
1836
  htsmsg_add_u32(e, "connected", !!cwc->cwc_connected);
1837

    
1838
  htsmsg_add_str(e, "hostname", cwc->cwc_hostname ?: "");
1839
  htsmsg_add_u32(e, "port", cwc->cwc_port);
1840

    
1841
  htsmsg_add_str(e, "username", cwc->cwc_username ?: "");
1842
  htsmsg_add_str(e, "password", cwc->cwc_password ?: "");
1843
  snprintf(buf, sizeof(buf),
1844
	   "%02x:%02x:%02x:%02x:%02x:%02x:%02x:"
1845
	   "%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1846
	   cwc->cwc_confedkey[0x0],
1847
	   cwc->cwc_confedkey[0x1],
1848
	   cwc->cwc_confedkey[0x2],
1849
	   cwc->cwc_confedkey[0x3],
1850
	   cwc->cwc_confedkey[0x4],
1851
	   cwc->cwc_confedkey[0x5],
1852
	   cwc->cwc_confedkey[0x6],
1853
	   cwc->cwc_confedkey[0x7],
1854
	   cwc->cwc_confedkey[0x8],
1855
	   cwc->cwc_confedkey[0x9],
1856
	   cwc->cwc_confedkey[0xa],
1857
	   cwc->cwc_confedkey[0xb],
1858
	   cwc->cwc_confedkey[0xc],
1859
	   cwc->cwc_confedkey[0xd]);	   
1860
  
1861
  htsmsg_add_str(e, "deskey", buf);
1862
  htsmsg_add_u32(e, "emm", cwc->cwc_emm);
1863
  htsmsg_add_str(e, "comment", cwc->cwc_comment ?: "");
1864

    
1865
  return e;
1866
}
1867

    
1868

    
1869
/**
1870
 *
1871
 */
1872
static int
1873
nibble(char c)
1874
{
1875
  switch(c) {
1876
  case '0' ... '9':
1877
    return c - '0';
1878
  case 'a' ... 'f':
1879
    return c - 'a' + 10;
1880
  case 'A' ... 'F':
1881
    return c - 'A' + 10;
1882
  default:
1883
    return 0;
1884
  }
1885
}
1886

    
1887

    
1888
/**
1889
 *
1890
 */
1891
static htsmsg_t *
1892
cwc_entry_update(void *opaque, const char *id, htsmsg_t *values, int maycreate)
1893
{
1894
  cwc_t *cwc;
1895
  const char *s;
1896
  uint32_t u32;
1897
  uint8_t key[14];
1898
  int u, l, i;
1899

    
1900
  if((cwc = cwc_entry_find(id, maycreate)) == NULL)
1901
    return NULL;
1902

    
1903
  if((s = htsmsg_get_str(values, "username")) != NULL) {
1904
    free(cwc->cwc_username);
1905
    cwc->cwc_username = strdup(s);
1906
  }
1907

    
1908
  if((s = htsmsg_get_str(values, "password")) != NULL) {
1909
    free(cwc->cwc_password);
1910
    free(cwc->cwc_password_salted);
1911
    cwc->cwc_password = strdup(s);
1912
    cwc->cwc_password_salted = crypt_md5(s, "$1$abcdefgh$");
1913
  }
1914

    
1915
  if((s = htsmsg_get_str(values, "comment")) != NULL) {
1916
    free(cwc->cwc_comment);
1917
    cwc->cwc_comment = strdup(s);
1918
  }
1919

    
1920
  if((s = htsmsg_get_str(values, "hostname")) != NULL) {
1921
    free(cwc->cwc_hostname);
1922
    cwc->cwc_hostname = strdup(s);
1923
  }
1924

    
1925
  if(!htsmsg_get_u32(values, "enabled", &u32))
1926
    cwc->cwc_enabled = u32;
1927

    
1928
  if(!htsmsg_get_u32(values, "port", &u32))
1929
    cwc->cwc_port = u32;
1930

    
1931
  if((s = htsmsg_get_str(values, "deskey")) != NULL) {
1932
    for(i = 0; i < 14; i++) {
1933
      while(*s != 0 && !isxdigit(*s)) s++;
1934
      if(*s == 0)
1935
	break;
1936
      u = nibble(*s++);
1937
      while(*s != 0 && !isxdigit(*s)) s++;
1938
      if(*s == 0)
1939
	break;
1940
      l = nibble(*s++);
1941
      key[i] = (u << 4) | l;
1942
    }
1943
    memcpy(cwc->cwc_confedkey, key, 14);
1944
  }
1945

    
1946
  if(!htsmsg_get_u32(values, "emm", &u32))
1947
    cwc->cwc_emm = u32;
1948

    
1949
  cwc->cwc_reconfigure = 1;
1950

    
1951
  if(cwc->cwc_fd != -1)
1952
    shutdown(cwc->cwc_fd, SHUT_RDWR);
1953

    
1954
  pthread_cond_signal(&cwc->cwc_cond);
1955

    
1956
  pthread_cond_broadcast(&cwc_config_changed);
1957

    
1958
  return cwc_record_build(cwc);
1959
}
1960
  
1961

    
1962

    
1963
/**
1964
 *
1965
 */
1966
static int
1967
cwc_entry_delete(void *opaque, const char *id)
1968
{
1969
  cwc_t *cwc;
1970

    
1971
  pthread_cond_broadcast(&cwc_config_changed);
1972

    
1973
  if((cwc = cwc_entry_find(id, 0)) == NULL)
1974
    return -1;
1975
  cwc_destroy(cwc);
1976
  return 0;
1977
}
1978

    
1979

    
1980
/**
1981
 *
1982
 */
1983
static htsmsg_t *
1984
cwc_entry_get_all(void *opaque)
1985
{
1986
  htsmsg_t *r = htsmsg_create_list();
1987
  cwc_t *cwc;
1988

    
1989
  TAILQ_FOREACH(cwc, &cwcs, cwc_link)
1990
    htsmsg_add_msg(r, NULL, cwc_record_build(cwc));
1991

    
1992
  return r;
1993
}
1994

    
1995
/**
1996
 *
1997
 */
1998
static htsmsg_t *
1999
cwc_entry_get(void *opaque, const char *id)
2000
{
2001
  cwc_t *cwc;
2002

    
2003

    
2004
  if((cwc = cwc_entry_find(id, 0)) == NULL)
2005
    return NULL;
2006
  return cwc_record_build(cwc);
2007
}
2008

    
2009
/**
2010
 *
2011
 */
2012
/**
2013
 *
2014
 */
2015
static htsmsg_t *
2016
cwc_entry_create(void *opaque)
2017
{
2018
  pthread_cond_broadcast(&cwc_config_changed);
2019
  return cwc_record_build(cwc_entry_find(NULL, 1));
2020
}
2021

    
2022

    
2023

    
2024

    
2025
/**
2026
 *
2027
 */
2028
static const dtable_class_t cwc_dtc = {
2029
  .dtc_record_get     = cwc_entry_get,
2030
  .dtc_record_get_all = cwc_entry_get_all,
2031
  .dtc_record_create  = cwc_entry_create,
2032
  .dtc_record_update  = cwc_entry_update,
2033
  .dtc_record_delete  = cwc_entry_delete,
2034
  .dtc_read_access = ACCESS_ADMIN,
2035
  .dtc_write_access = ACCESS_ADMIN,
2036
  .dtc_mutex = &cwc_mutex,
2037
};
2038

    
2039

    
2040

    
2041
/**
2042
 *
2043
 */
2044
void
2045
cwc_init(void)
2046
{
2047
  dtable_t *dt;
2048

    
2049
  TAILQ_INIT(&cwcs);
2050
  pthread_mutex_init(&cwc_mutex, NULL);
2051
  pthread_cond_init(&cwc_config_changed, NULL);
2052

    
2053
  dt = dtable_create(&cwc_dtc, "cwc", NULL);
2054
  dtable_load(dt);
2055
}
2056

    
2057

    
2058
#include <openssl/md5.h>
2059

    
2060
/*
2061
 * "THE BEER-WARE LICENSE" (Revision 42):
2062
 * <[email protected]> wrote this file.  As long as you retain this notice you
2063
 * can do whatever you want with this stuff. If we meet some day, and you think
2064
 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
2065
 */
2066

    
2067
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
2068
        "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
2069

    
2070
/* to64 BUFFER VALUE NUM
2071
 * Write NUM base64 characters of VALUE into BUFFER. */
2072
static void to64(char *s, unsigned long v, int n)
2073
{
2074
    while (--n >= 0) {
2075
        *s++ = itoa64[v&0x3f];
2076
        v >>= 6;
2077
    }
2078
}
2079

    
2080
/* crypt_md5 PASSWORD SALT
2081
 * Poul-Henning Kamp's crypt(3)-alike using MD5. */
2082
static char *
2083
crypt_md5(const char *pw, const char *salt)
2084
{
2085
    const char *magic = "$1$";
2086
    /* This string is magic for this algorithm.  Having
2087
     * it this way, we can get get better later on */
2088
    char *p;
2089
    const char *sp,*ep;
2090
    unsigned char   final[16];
2091
    int sl,pl,i,j;
2092
    MD5_CTX ctx,ctx1;
2093
    unsigned long l;
2094

    
2095
    /* Refine the Salt first */
2096
    sp = salt;
2097

    
2098
    /* If it starts with the magic string, then skip that */
2099
    if(!strncmp(sp,magic,strlen(magic)))
2100
        sp += strlen(magic);
2101

    
2102
    /* It stops at the first '$', max 8 chars */
2103
    for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
2104
        continue;
2105

    
2106
    /* get the length of the true salt */
2107
    sl = ep - sp;
2108

    
2109
    MD5_Init(&ctx);
2110

    
2111
    /* The password first, since that is what is most unknown */
2112
    MD5_Update(&ctx,(unsigned char *)pw,strlen(pw));
2113

    
2114
    /* Then our magic string */
2115
    MD5_Update(&ctx,(unsigned char *)magic,strlen(magic));
2116

    
2117
    /* Then the raw salt */
2118
    MD5_Update(&ctx,(unsigned char *)sp,sl);
2119

    
2120
    /* Then just as many characters of the MD5_(pw,salt,pw) */
2121
    MD5_Init(&ctx1);
2122
    MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw));
2123
    MD5_Update(&ctx1,(unsigned char *)sp,sl);
2124
    MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw));
2125
    MD5_Final(final,&ctx1);
2126
    for(pl = strlen(pw); pl > 0; pl -= 16)
2127
        MD5_Update(&ctx,(unsigned char *)final,pl>16 ? 16 : pl);
2128

    
2129
    /* Don't leave anything around in vm they could use. */
2130
    memset(final,0,sizeof final);
2131

    
2132
    /* Then something really weird... */
2133
    for (j=0,i = strlen(pw); i ; i >>= 1)
2134
        if(i&1)
2135
            MD5_Update(&ctx, (unsigned char *)final+j, 1);
2136
        else
2137
            MD5_Update(&ctx, (unsigned char *)pw+j, 1);
2138

    
2139
    /* Now make the output string */
2140
    char *passwd = malloc(120);
2141

    
2142
    strcpy(passwd,magic);
2143
    strncat(passwd,sp,sl);
2144
    strcat(passwd,"$");
2145

    
2146
    MD5_Final(final,&ctx);
2147

    
2148
    /*
2149
     * and now, just to make sure things don't run too fast
2150
     * On a 60 Mhz Pentium this takes 34 msec, so you would
2151
     * need 30 seconds to build a 1000 entry dictionary...
2152
     */
2153
    for(i=0;i<1000;i++) {
2154
        MD5_Init(&ctx1);
2155
        if(i & 1)
2156
            MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw));
2157
        else
2158
            MD5_Update(&ctx1,(unsigned char *)final,16);
2159

    
2160
        if(i % 3)
2161
            MD5_Update(&ctx1,(unsigned char *)sp,sl);
2162

    
2163
        if(i % 7)
2164
            MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw));
2165

    
2166
        if(i & 1)
2167
            MD5_Update(&ctx1,(unsigned char *)final,16);
2168
        else
2169
            MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw));
2170
        MD5_Final(final,&ctx1);
2171
    }
2172

    
2173
    p = passwd + strlen(passwd);
2174

    
2175
    l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
2176
    l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
2177
    l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
2178
    l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
2179
    l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
2180
    l =                    final[11]                ; to64(p,l,2); p += 2;
2181
    *p = '\0';
2182

    
2183
    /* Don't leave anything around in vm they could use. */
2184
    memset(final,0,sizeof final);
2185

    
2186
    return passwd;
2187
}
    (1-1/1)