Browse Source

Add struct camd35

Georgi Chorbadzhiyski 13 years ago
parent
commit
ad7c9f1e6b
4 changed files with 92 additions and 81 deletions
  1. 44
    58
      camd.c
  2. 23
    5
      camd.h
  3. 4
    2
      tables.c
  4. 21
    16
      tsdecrypt.c

+ 44
- 58
camd.c View File

@@ -17,24 +17,6 @@
17 17
 #include "util.h"
18 18
 #include "camd.h"
19 19
 
20
-extern struct key key;
21
-
22
-static int camd35_server_fd;
23
-extern struct in_addr camd35_server_addr;
24
-extern unsigned int camd35_server_port;
25
-extern char *camd35_user;
26
-extern char *camd35_pass;
27
-
28
-static uint32_t camd35_auth = 0;
29
-static AES_KEY camd35_aes_encrypt_key;
30
-static AES_KEY camd35_aes_decrypt_key;
31
-
32
-static uint8_t invalid_cw[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
33
-
34
-static inline int valid_cw(uint8_t *cw) {
35
-	return memcmp(cw, invalid_cw, 16) != 0;
36
-}
37
-
38 20
 static int connect_to(struct in_addr ip, int port) {
39 21
 	ts_LOGf("Connecting to %s:%d\n", inet_ntoa(ip), port);
40 22
 
@@ -61,55 +43,61 @@ static int connect_to(struct in_addr ip, int port) {
61 43
 #define HDR_LEN     (20)
62 44
 #define BUF_SIZE	(4 + HDR_LEN + 256 + 16)
63 45
 
64
-static void camd35_init_auth(char *user, char *pass) {
46
+static void camd35_init_auth(struct camd35 *c) {
65 47
 	unsigned char dump[16];
66
-	camd35_auth = crc32(0L, MD5((unsigned char *)user, strlen(user), dump), 16);
67 48
 
68
-	MD5((unsigned char *)pass, strlen(pass), dump);
49
+	if (c->auth_token)
50
+		return;
69 51
 
70
-	AES_set_encrypt_key(dump, 128, &camd35_aes_encrypt_key);
71
-	AES_set_decrypt_key(dump, 128, &camd35_aes_decrypt_key);
52
+	c->auth_token = crc32(0L, MD5((unsigned char *)c->user, strlen(c->user), dump), 16);
53
+
54
+	MD5((unsigned char *)c->pass, strlen(c->pass), dump);
55
+
56
+	AES_set_encrypt_key(dump, 128, &c->aes_encrypt_key);
57
+	AES_set_decrypt_key(dump, 128, &c->aes_decrypt_key);
72 58
 }
73 59
 
74
-int camd35_connect() {
75
-	if (camd35_server_fd < 0)
76
-		camd35_server_fd = connect_to(camd35_server_addr, camd35_server_port);
77
-	return camd35_server_fd;
60
+int camd35_connect(struct camd35 *c) {
61
+	if (c->server_fd < 0)
62
+		c->server_fd = connect_to(c->server_addr, c->server_port);
63
+	return c->server_fd;
78 64
 }
79 65
 
80
-void camd35_disconnect() {
81
-	shutdown_fd(&camd35_server_fd);
66
+void camd35_disconnect(struct camd35 *c) {
67
+	shutdown_fd(&c->server_fd);
82 68
 }
83 69
 
84
-static int camd35_recv(uint8_t *data, int *data_len) {
70
+static int camd35_recv(struct camd35 *c, uint8_t *data, int *data_len) {
85 71
 	int i;
86 72
 
87 73
 	// Read AUTH token
88
-	ssize_t r = fdread(camd35_server_fd, (char *)data, 4);
74
+	ssize_t r = fdread(c->server_fd, (char *)data, 4);
89 75
 	if (r < 4)
90 76
 		return -1;
91 77
 	uint32_t auth_token = (((data[0] << 24) | (data[1] << 16) | (data[2]<<8) | data[3]) & 0xffffffffL);
92
-	if (auth_token != camd35_auth)
93
-		ts_LOGf("WARN: recv auth 0x%08x != camd35_auth 0x%08x\n", auth_token, camd35_auth);
78
+	if (auth_token != c->auth_token)
79
+		ts_LOGf("WARN: recv auth 0x%08x != camd35_auth 0x%08x\n", auth_token, c->auth_token);
94 80
 
95 81
 	*data_len = 256;
96 82
 	for (i = 0; i < *data_len; i += 16) { // Read and decrypt payload
97
-		fdread(camd35_server_fd, (char *)data + i, 16);
98
-		AES_decrypt(data + i, data + i, &camd35_aes_decrypt_key);
83
+		fdread(c->server_fd, (char *)data + i, 16);
84
+		AES_decrypt(data + i, data + i, &c->aes_decrypt_key);
99 85
 		if (i == 0)
100 86
 			*data_len = boundary(4, data[1] + 20); // Initialize real data length
101 87
 	}
102 88
 	return *data_len;
103 89
 }
104 90
 
105
-#define ERR(x) do { ts_LOGf("%s", x); return NULL; } while (0)
91
+#define ERR(x) do { ts_LOGf("%s\n", x); return NULL; } while (0)
106 92
 
107
-static uint8_t *camd35_recv_cw() {
93
+
94
+static uint8_t *camd35_recv_cw(struct camd35 *c) {
95
+	static uint8_t invalid_cw[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
108 96
 	uint8_t data[BUF_SIZE];
109 97
 	int data_len = 0;
110 98
 
111 99
 NEXT:
112
-	if (camd35_recv(data, &data_len) < 0)
100
+	if (camd35_recv(c, data, &data_len) < 0)
113 101
 		ERR("No data!");
114 102
 
115 103
 	if (data[0] < 0x01) {
@@ -126,15 +114,15 @@ NEXT:
126 114
 	uint16_t ca_id = (data[10] << 8) | data[11];
127 115
 	uint16_t idx   = (data[16] << 8) | data[17];
128 116
 	uint8_t *cw = data + 20;
129
-	memcpy(key.cw, cw, 16);
117
+	memcpy(c->key->cw, cw, 16);
130 118
 
131 119
 	char cw_dump[16 * 6];
132 120
 	ts_hex_dump_buf(cw_dump, 16 * 6, cw, 16, 0);
133 121
 	ts_LOGf("CW  | CAID: 0x%04x ---------------------------------- IDX: 0x%04x Data: %s\n", ca_id, idx, cw_dump);
134 122
 
135
-	key.is_valid_cw = valid_cw(key.cw);
136
-	dvbcsa_key_set(key.cw    , key.csakey[0]);
137
-	dvbcsa_key_set(key.cw + 8, key.csakey[1]);
123
+	c->key->is_valid_cw = memcmp(c->key->cw, invalid_cw, 16) != 0;
124
+	dvbcsa_key_set(c->key->cw    , c->key->csakey[0]);
125
+	dvbcsa_key_set(c->key->cw + 8, c->key->csakey[1]);
138 126
 
139 127
 	return NULL;
140 128
 }
@@ -142,26 +130,24 @@ NEXT:
142 130
 #undef ERR
143 131
 
144 132
 
145
-static int camd35_send(uint8_t *data, uint8_t data_len) {
133
+static int camd35_send(struct camd35 *c, uint8_t *data, uint8_t data_len) {
146 134
 	unsigned int i;
147 135
 	uint8_t buf[BUF_SIZE];
148 136
 	uint8_t *bdata = buf + 4;
149 137
 
150
-	camd35_connect();
138
+	camd35_connect(c);
139
+	camd35_init_auth(c);
151 140
 
152
-	if (!camd35_auth)
153
-		camd35_init_auth(camd35_user, camd35_pass);
154
-
155
-	init_4b(camd35_auth, buf); // Put authentication token
141
+	init_4b(c->auth_token, buf); // Put authentication token
156 142
 	memcpy(bdata, data, data_len); // Put data
157 143
 
158 144
 	for (i = 0; i < data_len; i += 16) // Encrypt payload
159
-		AES_encrypt(data + i, bdata + i, &camd35_aes_encrypt_key);
145
+		AES_encrypt(data + i, bdata + i, &c->aes_encrypt_key);
160 146
 
161
-	return fdwrite(camd35_server_fd, (char *)buf, data_len + 4);
147
+	return fdwrite(c->server_fd, (char *)buf, data_len + 4);
162 148
 }
163 149
 
164
-static void camd35_buf_init(uint8_t *buf, uint8_t *data, uint8_t data_len) {
150
+static void camd35_buf_init(struct camd35 *c, uint8_t *buf, uint8_t *data, uint8_t data_len) {
165 151
 	memset(buf, 0, HDR_LEN); // Reset header
166 152
 	memset(buf + HDR_LEN, 0xff, BUF_SIZE - HDR_LEN); // Reset data
167 153
 	buf[1] = data_len; // Data length
@@ -169,12 +155,12 @@ static void camd35_buf_init(uint8_t *buf, uint8_t *data, uint8_t data_len) {
169 155
 	memcpy(buf + HDR_LEN, data, data_len); // Copy data to buf
170 156
 }
171 157
 
172
-int camd35_send_ecm(uint16_t service_id, uint16_t ca_id, uint16_t idx, uint8_t *data, uint8_t data_len) {
158
+int camd35_send_ecm(struct camd35 *c, uint16_t service_id, uint16_t ca_id, uint16_t idx, uint8_t *data, uint8_t data_len) {
173 159
 	uint8_t buf[BUF_SIZE];
174 160
 	uint32_t provider_id = 0;
175 161
 	int to_send = boundary(4, HDR_LEN + data_len);
176 162
 
177
-	camd35_buf_init(buf, data, data_len);
163
+	camd35_buf_init(c, buf, data, data_len);
178 164
 
179 165
 	buf[0] = 0x00; // CMD ECM request
180 166
 	init_2b(service_id , buf + 8);
@@ -184,21 +170,21 @@ int camd35_send_ecm(uint16_t service_id, uint16_t ca_id, uint16_t idx, uint8_t *
184 170
 	buf[18] = 0xff;
185 171
 	buf[19] = 0xff;
186 172
 
187
-	camd35_send(buf, to_send);
188
-	camd35_recv_cw();
173
+	camd35_send(c, buf, to_send);
174
+	camd35_recv_cw(c);
189 175
 	return 0;
190 176
 }
191 177
 
192
-int camd35_send_emm(uint16_t ca_id, uint8_t *data, uint8_t data_len) {
178
+int camd35_send_emm(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t data_len) {
193 179
 	uint8_t buf[BUF_SIZE];
194 180
 	uint32_t prov_id = 0;
195 181
 	int to_send = boundary(4, data_len + HDR_LEN);
196 182
 
197
-	camd35_buf_init(buf, data, data_len);
183
+	camd35_buf_init(c, buf, data, data_len);
198 184
 
199 185
 	buf[0] = 0x06; // CMD incomming EMM
200 186
 	init_2b(ca_id  , buf + 10);
201 187
 	init_4b(prov_id, buf + 12);
202 188
 
203
-	return camd35_send(buf, to_send);
189
+	return camd35_send(c, buf, to_send);
204 190
 }

+ 23
- 5
camd.h View File

@@ -1,12 +1,30 @@
1 1
 #ifndef CAMD_H
2 2
 #define CAMD_H
3 3
 
4
-#include <inttypes.h>
4
+#include <openssl/aes.h>
5
+#include <openssl/md5.h>
5 6
 
6
-int camd35_connect();
7
-void camd35_disconnect();
7
+#include "data.h"
8 8
 
9
-int camd35_send_ecm(uint16_t service_id, uint16_t ca_id, uint16_t idx, uint8_t *data, uint8_t data_len);
10
-int camd35_send_emm(uint16_t ca_id, uint8_t *data, uint8_t data_len);
9
+struct camd35 {
10
+	int				server_fd;
11
+	struct in_addr	server_addr;
12
+	unsigned int	server_port;
13
+	char			user[64];
14
+	char			pass[64];
15
+
16
+	AES_KEY			aes_encrypt_key;
17
+	AES_KEY			aes_decrypt_key;
18
+
19
+	uint32_t		auth_token;
20
+
21
+	struct key		*key;
22
+};
23
+
24
+int camd35_connect		(struct camd35 *c);
25
+void camd35_disconnect	(struct camd35 *c);
26
+
27
+int camd35_send_ecm		(struct camd35 *c, uint16_t service_id, uint16_t ca_id, uint16_t idx, uint8_t *data, uint8_t data_len);
28
+int camd35_send_emm		(struct camd35 *c, uint16_t ca_id, uint8_t *data, uint8_t data_len);
11 29
 
12 30
 #endif

+ 4
- 2
tables.c View File

@@ -5,6 +5,8 @@
5 5
 #include "libts/tsfuncs.h"
6 6
 #include "libfuncs/libfuncs.h"
7 7
 
8
+extern struct camd35 camd35;
9
+
8 10
 extern enum CA_system req_CA_sys;
9 11
 extern int debug_level;
10 12
 extern int emm_send;
@@ -108,7 +110,7 @@ void process_emm(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
108 110
 			sec->section_data_len,
109 111
 			dump);
110 112
 	}
111
-	camd35_send_emm(ts->emm_caid, sec->section_data, sec->section_data_len);
113
+	camd35_send_emm(&camd35, ts->emm_caid, sec->section_data, sec->section_data_len);
112 114
 	ts_privsec_copy(ts->emm, ts->last_emm);
113 115
 	ts_privsec_clear(ts->emm);
114 116
 }
@@ -134,7 +136,7 @@ void process_ecm(struct ts *ts, uint16_t pid, uint8_t *ts_packet) {
134 136
 			sec->section_data_len,
135 137
 			ts->ecm_counter,
136 138
 			dump);
137
-		camd35_send_ecm(ts->service_id, ts->ecm_caid, ts->ecm_counter++, sec->section_data, sec->section_data_len);
139
+		camd35_send_ecm(&camd35, ts->service_id, ts->ecm_caid, ts->ecm_counter++, sec->section_data, sec->section_data_len);
138 140
 	} else if (debug_level >= 3) {
139 141
 		ts_LOGf("ECM | CAID: 0x%04x PID 0x%04x Table: 0x%02x Length: %3d IDX: 0x%04x Data: -dup-\n",
140 142
 			ts->ecm_caid,

+ 21
- 16
tsdecrypt.c View File

@@ -14,17 +14,13 @@
14 14
 #include "tables.h"
15 15
 
16 16
 struct key key;
17
+struct camd35 camd35;
17 18
 
18 19
 int debug_level = 0;
19 20
 unsigned long ts_pack = 0;
20 21
 int ts_pack_shown = 0;
21 22
 
22 23
 enum CA_system req_CA_sys = CA_CONNAX;
23
-struct in_addr camd35_server_addr;
24
-unsigned int camd35_server_port = 2233;
25
-char *camd35_user = "user";
26
-char *camd35_pass = "pass";
27
-uint32_t camd35_auth = 0;
28 24
 
29 25
 int emm_send = 1;
30 26
 int pid_filter = 0;
@@ -45,8 +41,8 @@ void show_help() {
45 41
 	printf("\n");
46 42
 	printf("  CAMD35 server options:\n");
47 43
 	printf("    -s server_addr | default: disabled (format 1.2.3.4:2233)\n");
48
-	printf("    -U server_user | default: %s\n", camd35_user);
49
-	printf("    -P server_pass | default: %s\n", camd35_pass);
44
+	printf("    -U server_user | default: %s\n", camd35.user);
45
+	printf("    -P server_pass | default: %s\n", camd35.pass);
50 46
 	printf("\n");
51 47
 	printf("  Output options (if output is disabled stdout is used for output):\n");
52 48
 	printf("    -o output_addr | default: disabled (format: 239.78.78.78:5000)\n");
@@ -90,9 +86,9 @@ void parse_options(int argc, char **argv) {
90 86
 				p = strrchr(optarg, ':');
91 87
 				if (p) {
92 88
 					*p = 0x00;
93
-					camd35_server_port = atoi(p + 1);
89
+					camd35.server_port = atoi(p + 1);
94 90
 				}
95
-				if (inet_aton(optarg, &camd35_server_addr) == 0)
91
+				if (inet_aton(optarg, &camd35.server_addr) == 0)
96 92
 					server_err = 1;
97 93
 				else
98 94
 					server_err = 0;
@@ -116,10 +112,12 @@ void parse_options(int argc, char **argv) {
116 112
 				break;
117 113
 
118 114
 			case 'U':
119
-				camd35_user = optarg;
115
+				strncpy(camd35.user, optarg, sizeof(camd35.user) - 1);
116
+				camd35.user[sizeof(camd35.user) - 1] = 0;
120 117
 				break;
121 118
 			case 'P':
122
-				camd35_pass = optarg;
119
+				strncpy(camd35.pass, optarg, sizeof(camd35.pass) - 1);
120
+				camd35.pass[sizeof(camd35.pass) - 1] = 0;
123 121
 				break;
124 122
 
125 123
 			case 'e':
@@ -151,9 +149,9 @@ void parse_options(int argc, char **argv) {
151 149
 		exit(1);
152 150
 	}
153 151
 	ts_LOGf("CA System  : %s\n", ts_get_CA_sys_txt(req_CA_sys));
154
-	ts_LOGf("Server addr: %s:%u\n", inet_ntoa(camd35_server_addr), camd35_server_port);
155
-	ts_LOGf("Server user: %s\n", camd35_user);
156
-	ts_LOGf("Server pass: %s\n", camd35_pass);
152
+	ts_LOGf("Server addr: %s:%u\n", inet_ntoa(camd35.server_addr), camd35.server_port);
153
+	ts_LOGf("Server user: %s\n", camd35.user);
154
+	ts_LOGf("Server pass: %s\n", camd35.pass);
157 155
 	if (output_port) {
158 156
 		ts_LOGf("Output addr: %s:%u\n", inet_ntoa(output_addr), output_port);
159 157
 		ts_LOGf("Output intf: %s\n", inet_ntoa(output_intf));
@@ -222,11 +220,18 @@ int main(int argc, char **argv) {
222 220
 	key.csakey[0] = dvbcsa_key_alloc();
223 221
 	key.csakey[1] = dvbcsa_key_alloc();
224 222
 
223
+	memset(&camd35, 0, sizeof(camd35));
224
+	camd35.server_fd = -1;
225
+	camd35.server_port = 2233;
226
+	strcpy(camd35.user, "user");
227
+	strcpy(camd35.pass, "pass");
228
+	camd35.key = &key;
229
+
225 230
 	ts_set_log_func(LOG_func);
226 231
 
227 232
 	parse_options(argc, argv);
228 233
 
229
-	camd35_connect();
234
+	camd35_connect(&camd35);
230 235
 
231 236
 	struct ts *ts = ts_alloc();
232 237
 	do {
@@ -241,6 +246,6 @@ int main(int argc, char **argv) {
241 246
 	dvbcsa_key_free(key.csakey[0]);
242 247
 	dvbcsa_key_free(key.csakey[1]);
243 248
 
244
-	camd35_disconnect();
249
+	camd35_disconnect(&camd35);
245 250
 	exit(0);
246 251
 }

Loading…
Cancel
Save