Changeset 452
- Timestamp:
- 10/11/09 14:11:24 (14 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Distribution/doc/man/oscam.server.5
r206 r452 172 172 .RE 173 173 .PP 174 \fBblocknano\fP = \fBnano[,nano]...\fP 175 .RS 3n 176 list of EMM-nanos to block (in hex w/o 0x) 174 \fBblocknano\fP = \fBnano[,nano]...\fP|\fPall\fP 175 .RS 3n 176 list of EMM-nanos to block (in hex w/o 0x) or all EMM-nanos, only valid for physical readers 177 177 178 178 example: blocknano = 45,93,7a,ff 179 blocknano = all 180 .RE 181 .PP 182 \fBsavenano\fP = \fBnano[,nano]....\fP|\fPall\fP 183 .RS 3n 184 list of EMM-nanos to save (in hex w/o 0x) or all EMM-nanos, only valid for physical readers 185 186 example: savenano = 45,93,7a,ff 187 savenano = all 188 .RE 189 .PP 190 \fBreadnano\fP = \fB[path]filename\fP 191 .RS 3n 192 write file (usually a copy of a file saved by savenano) to your smartcard, if no path is specified, the specified file is searched for in the configuration directory, only valid for physical readers 193 194 example: readnano = write.emm 195 readnano = /var/oscam/write.emm 179 196 .RE 180 197 .SH EXAMPLES -
trunk/Distribution/doc/txt/oscam.server.txt
r132 r452 123 123 2 = log all EMMs 124 124 125 blocknano = nano[,nano]... 126 list of EMM-nanos to block (in hex w/o 0x) 125 blocknano = nano[,nano]...|all 126 list of EMM-nanos to block (in hex w/o 0x) or all EMM-nanos, only 127 valid for physical readers 127 128 128 129 example: blocknano = 45,93,7a,ff 130 blocknano = all 131 132 savenano = nano[,nano]....|all 133 list of EMM-nanos to save (in hex w/o 0x) or all EMM-nanos, only 134 valid for physical readers 135 136 example: savenano = 45,93,7a,ff 137 savenano = all 138 139 readnano = [path]filename 140 write file (usually a copy of a file saved by savenano) to your 141 smartcard, if no path is specified, the specified file is searched 142 for in the configuration directory, only valid for physical readers 143 144 example: readnano = write.emm 145 readnano = /var/oscam/write.emm 129 146 130 147 EXAMPLES -
trunk/globals.h
r127 r452 370 370 ushort caid[16]; 371 371 uchar b_nano[256]; 372 uchar emmfile[128]; 372 373 char pincode[5]; 373 374 int logemm; -
trunk/module-camd35.c
r70 r452 183 183 memcpy(&mbuf[50+(i*5)], &reader[au].sa[i][0],3); 184 184 } 185 } 185 }/* b_nano old implementation was not working according to documentation, so we changed it 186 186 mbuf[128]=(reader[au].b_nano[0xd0])?0:1; 187 187 mbuf[129]=(reader[au].b_nano[0xd2])?0:1; 188 mbuf[130]=(reader[au].b_nano[0xd3])?0:1; 188 mbuf[130]=(reader[au].b_nano[0xd3])?0:1;*/ 189 mbuf[128]=1; //we think client/server protocols should deliver all information, and only readers should discard EMM 190 mbuf[129]=1; 191 mbuf[130]=1; 189 192 } 190 193 else // disable emm -
trunk/oscam-config.c
r118 r452 973 973 if( !strcmp(token, "pincode") ) 974 974 strncpy(rdr->pincode, value, sizeof(rdr->pincode)-1); 975 if (!strcmp(token, "readnano")) strncpy(rdr->emmfile, value, sizeof(rdr->emmfile)-1); 975 976 /* 976 977 * case insensitive … … 1056 1057 case 2: rdr->logemm=atoi(ptr); break; 1057 1058 } 1059 1058 1060 if (!strcmp(token, "blocknano")) 1059 for (ptr=strtok(value, ","); ptr; ptr=strtok(NULL, ",")) 1060 if ((i=byte_atob(ptr))>=0) 1061 rdr->b_nano[i]=1; 1061 if (!strcmp(value,"all")) //wildcard is used 1062 for (i=0 ; i<256; i++) 1063 rdr->b_nano[i] |= 0x01; //set all lsb's to block all nanos 1064 else 1065 for (ptr=strtok(value, ","); ptr; ptr=strtok(NULL, ",")) 1066 if ((i=byte_atob(ptr))>=0) 1067 rdr->b_nano[i]|= 0x01; //lsb is set when to block nano 1068 1069 if (!strcmp(token, "savenano")) 1070 if (!strcmp(value,"all")) //wildcard is used 1071 for (i=0 ; i<256; i++) 1072 rdr->b_nano[i] |= 0x02; //set all lsb+1 to save all nanos to file 1073 else 1074 for (ptr=strtok(value, ","); ptr; ptr=strtok(NULL, ",")) 1075 if ((i=byte_atob(ptr))>=0) 1076 rdr->b_nano[i]|= 0x02; //lsb+1 is set when to save nano to file 1077 1062 1078 } 1063 1079 -
trunk/oscam-reader.c
r93 r452 320 320 { 321 321 int i, no, rc, ecs; 322 char *rtxt[] ={ "error", "written", "skipped" };322 char *rtxt[] = { "error", "written", "skipped", "blocked" }; 323 323 struct timeb tps, tpe; 324 324 -
trunk/reader-common.c
r94 r452 169 169 } 170 170 171 void do_emm_from_file(void) 172 { 173 //now here check whether we have EMM's on file to load and write to card: 174 if (reader[ridx].emmfile[0]) {//readnano has something filled in 175 176 //handling emmfile 177 char token[256]; 178 FILE *fp; 179 if ((reader[ridx].emmfile[0] == '/')) 180 sprintf (token, "%s", reader[ridx].emmfile); //pathname included 181 else 182 sprintf (token, "%s%s", cs_confdir, reader[ridx].emmfile); //only file specified, look in confdir for this file 183 184 if (!(fp = fopen (token, "rb"))) 185 cs_log ("ERROR: Cannot open EMM file '%s' (errno=%d)\n", token, errno); 186 else { 187 EMM_PACKET *eptmp; 188 eptmp = malloc (sizeof(EMM_PACKET)); 189 fread (eptmp, sizeof (EMM_PACKET), 1, fp); 190 fclose (fp); 191 192 uchar old_b_nano = reader[ridx].b_nano[eptmp->emm[0]]; //save old b_nano value 193 reader[ridx].b_nano[eptmp->emm[0]] &= 0xfc; //clear lsb and lsb+1, so no blocking, and no saving for this nano 194 195 //if (!reader_do_emm (eptmp)) 196 if (!reader_emm (eptmp)) 197 cs_log ("ERROR: EMM read from write.emm NOT processed correctly!"); 198 199 reader[ridx].b_nano[eptmp->emm[0]] = old_b_nano; //restore old block/save settings 200 reader[ridx].emmfile[0] = 0; //clear emmfile, so no reading anymore 201 202 free(eptmp); 203 eptmp = NULL; 204 } 205 } 206 } 207 171 208 void reader_card_info() 172 209 { … … 176 213 client[cs_idx].last=time((time_t)0); 177 214 cs_ri_brk(0); 215 do_emm_from_file(); 178 216 switch(reader[ridx].card_system) 179 217 { … … 206 244 if (!reader[ridx].card_system) cs_ri_log("card system not supported"); 207 245 cs_ri_brk(1); 246 208 247 return(reader[ridx].card_system); 209 248 } … … 326 365 { 327 366 client[cs_idx].last=time((time_t)0); 367 if (reader[ridx].b_nano[ep->emm[0]] & 0x02) //should this nano be saved? 368 { 369 char token[256]; 370 FILE *fp; 371 372 time_t rawtime; 373 time (&rawtime); 374 struct tm *timeinfo; 375 timeinfo = localtime (&rawtime); /* to access LOCAL date/time info */ 376 char buf[80]; 377 strftime (buf, 80, "%Y%m%d_%H_%M_%S", timeinfo); 378 379 sprintf (token, "%swrite_%s_%s.%s", cs_confdir, (ep->emm[0] == 0x82) ? "UNIQ" : "SHARED", buf, "txt"); 380 if (!(fp = fopen (token, "w"))) 381 cs_log ("ERROR: Cannot open EMM.txt file '%s' (errno=%d)\n", token, errno); 382 else { 383 cs_log ("Succesfully written text EMM to %s.", token); 384 int emm_length = ((ep->emm[1] & 0x0f) << 8) | ep->emm[2]; 385 fprintf (fp, "%s", cs_hexdump (0, ep->emm, emm_length + 3)); 386 fclose (fp); 387 } 388 389 //sprintf (token, "%s%s.%s", cs_confdir, buf,"emm"); 390 sprintf (token, "%swrite_%s_%s.%s", cs_confdir, (ep->emm[0] == 0x82) ? "UNIQ" : "SHARED", buf, "emm"); 391 if (!(fp = fopen (token, "wb"))) 392 cs_log ("ERROR: Cannot open EMM.emm file '%s' (errno=%d)\n", token, errno); 393 else { 394 cs_log ("Succesfully written binary EMM to %s.", token); 395 fwrite (ep, sizeof (*ep), 1, fp); 396 fclose (fp); 397 } 398 } 399 400 if (reader[ridx].b_nano[ep->emm[0]] & 0x01) //should this nano be blcoked? 401 return 3; 402 328 403 switch(reader[ridx].card_system) 329 404 { -
trunk/reader-seca.c
r96 r452 1 1 #include "globals.h" 2 2 #include "reader-common.h" 3 #include <stdlib.h> 4 5 //02102009 Dingo35 (=original author of this module): 6 //-added detection of EMM-GA; this kind of EMM has not been documented yet, no update takes place (yet) 7 //-solved bug in validity date 8 //-eliminated unnecessary buffers 9 //-added printing of PBM info 3 10 4 11 extern uchar cta_cmd[], cta_res[]; … … 42 49 ins12[2]=i;//select provider 43 50 read_cmd(ins12, NULL); // show provider properties 44 cs_debug("hexdump:% x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x.",cta_res[0],cta_res[1],cta_res[2],cta_res[3],cta_res[4],cta_res[5],cta_res[6],cta_res[7],cta_res[8],cta_res[9],cta_res[10],cta_res[11],cta_res[12],cta_res[13],cta_res[14],cta_res[15],cta_res[16],cta_res[17],cta_res[18],cta_res[19],cta_res[20],cta_res[21],cta_res[22],cta_res[23],cta_res[24],cta_res[25],cta_res[26]);51 cs_debug("hexdump:%s", cs_hexdump (0, cta_res, 27)); 45 52 46 53 if ((cta_res[25] != 0x90) || (cta_res[26] != 0x00)) return (0); … … 48 55 reader[ridx].prid[i][1]=0;//blanken high byte provider code 49 56 memcpy(&reader[ridx].prid[i][2], cta_res, 2); 50 // sprintf(buf+strlen(buf), ",%06X", b2i(3, &reader[ridx].prid[i][1]));51 57 52 58 year = (cta_res[22]>>1) + 1990; 53 month = ((cta_res[22]&0x1) *256 + (cta_res[23]&0xe0))>>5;59 month = ((cta_res[22]&0x1)<< 3) | (cta_res[23] >>5); 54 60 day = (cta_res[23]&0x1f); 55 61 t=time(NULL); 56 62 lt=localtime(&t); 57 if (lt->tm_year+1900 != year) 58 if (lt->tm_year+1900 < year) 59 valid=1; 60 else 61 valid=0; 62 else 63 if (lt->tm_mon+1 != month) 64 if (lt->tm_mon+1 < month) 65 valid=1; 66 else 67 valid=0; 68 else 69 if (lt->tm_mday != day) 70 if (lt->tm_mday < day) 71 valid=1; 72 else 73 valid=0; 63 if (lt->tm_year + 1900 != year) 64 valid = (lt->tm_year + 1900 < year); 65 else if (lt->tm_mon + 1 != month) 66 valid = (lt->tm_mon + 1 < month); 67 else if (lt->tm_mday != day) 68 valid = (lt->tm_mday < day); 69 74 70 memcpy(l_name+8, cta_res+2, 16); 75 71 l_name[sizeof(l_name)]=0; … … 127 123 for (reader[ridx].nprov=0, i=pmap; i; i>>=1) 128 124 reader[ridx].nprov+=i&1; 129 // i=cta_res[2]*256+cta_res[3];130 // do { n+=i&1; i>>=1; } while(i);131 // reader[ridx].nprov=n;132 125 133 126 for (i=0; i<16; i++) … … 152 145 } 153 146 154 // static int get_prov_index (uchar providhigh, uchar providlow)//returns provider id or -1 if not found155 147 static int get_prov_index(char *provid) //returns provider id or -1 if not found 156 148 { … … 159 151 if (!memcmp(provid, &reader[ridx].prid[prov][2], 2)) 160 152 return(prov); 161 // for (prov=0; prov<reader[ridx].nprov; prov++) //search for provider index162 // if ( (providhigh == reader[ridx].prid[prov][2]) &&163 // (providlow == reader[ridx].prid[prov][3]) )164 // {165 // return(prov);166 // }167 153 return(-1); 168 154 } … … 173 159 static unsigned char ins3c[] = { 0xc1,0x3c,0x00,0x00,0x00 }; // coding cw 174 160 static unsigned char ins3a[] = { 0xc1,0x3a,0x00,0x00,0x10 }; // decoding cw 175 uchar ins3cdata[256];176 161 int i; 177 162 178 // i=get_prov_index(er->ecm[3],er->ecm[4]);179 163 i=get_prov_index((char *) er->ecm+3); 180 164 if ((i == -1) || (reader[ridx].availkeys[i][0] == 0)) //if provider not found or expired … … 182 166 ins3c[2]=i; 183 167 ins3c[3]=er->ecm[7]; //key nr 184 ins3c[4]=(((er->ecm[1]&0x0f) *256)+er->ecm[2])-0x05;168 ins3c[4]=(((er->ecm[1]&0x0f) << 8) | er->ecm[2])-0x05; 185 169 186 memcpy(ins3cdata,er->ecm+8,256-8);187 cs_debug("do_ecm:ins3c=% x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x.",ins3c[0],ins3c[1],ins3c[2],ins3c[3],ins3c[4],ins3cdata[0],ins3cdata[1],ins3cdata[2],ins3cdata[3],ins3cdata[4],ins3cdata[5],ins3cdata[6],ins3cdata[7],ins3cdata[8],ins3cdata[9]);188 write_cmd(ins3c, ins3cdata); //ecm request170 //memcpy(ins3cdata,er->ecm+8,256-8); 171 cs_debug("do_ecm:ins3c=%s", cs_hexdump (0, ins3c, 10)); 172 write_cmd(ins3c, er->ecm+8); //ecm request 189 173 cs_debug("do_ecm_answer:%02x%02x",cta_res[0], cta_res[1]); 190 174 … … 195 179 write_cmd(ins30, ins30data); 196 180 cs_debug("do_ins30_answer:%02x%02x",cta_res[0], cta_res[1]); 197 write_cmd(ins3c, ins3cdata); //ecm request181 write_cmd(ins3c, er->ecm+8); //ecm request 198 182 cs_debug("do_ecm_answer2:%02x%02x",cta_res[0], cta_res[1]); 199 183 } … … 201 185 if ((cta_res[0] != 0x90) || (cta_res[1] != 0x00)) return (0); 202 186 read_cmd(ins3a, NULL); //get cw's 203 cs_debug("cwdump:% x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x.",cta_res[0],cta_res[1],cta_res[2],cta_res[3],cta_res[4],cta_res[5],cta_res[6],cta_res[7],cta_res[8],cta_res[9],cta_res[10],cta_res[11],cta_res[12],cta_res[13],cta_res[14],cta_res[15],cta_res[16],cta_res[17]);187 cs_debug("cwdump:%s", cs_hexdump(0, cta_res,18)); 204 188 if ((cta_res[16] != 0x90) || (cta_res[17] != 0x00)) return (0);//exit if response is not 90 00 //TODO: if response is 9027 ppv mode is possible! 205 189 memcpy(er->cw,cta_res,16); … … 209 193 210 194 int seca_do_emm(EMM_PACKET *ep) 211 { 195 { //return 1; 212 196 static unsigned char ins40[] = { 0xc1,0x40,0x00,0x00,0x00 }; 213 uchar ins40data[256]; 214 int i; 215 cs_debug("EMM:%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x.",ep->emm[0],ep->emm[1],ep->emm[2],ep->emm[3],ep->emm[4],ep->emm[5],ep->emm[6],ep->emm[7],ep->emm[8],ep->emm[9],ep->emm[10],ep->emm[11],ep->emm[12],ep->emm[13],ep->emm[14],ep->emm[15],ep->emm[16],ep->emm[17],ep->emm[18],ep->emm[19],ep->emm[20],ep->emm[21],ep->emm[22],ep->emm[23],ep->emm[24],ep->emm[25],ep->emm[26]); 216 if (ep->emm[0] == 0x84) { //shared EMM 197 //uchar ins40data[256]; 198 int i,ins40data_offset; 199 int emm_length = ((ep->emm[1] & 0x0f) << 8) + ep->emm[2]; 200 201 cs_debug("EMM:%s", cs_hexdump (0, ep->emm, emm_length + 3)); 202 ep->type = ep->emm[0]; 203 switch (ep->type) { 204 case 0x84: //shared EMM 205 { 217 206 //to test if SA matches 218 207 //first find out prov id 219 // i=get_prov_index(ep->emm[3],ep->emm[4]);220 208 i=get_prov_index((char *) ep->emm+3); 221 209 if (i == -1) 222 210 return(0); 223 else //prov id found, now test for SA (only first 3 bytes, custom byte does not count) 224 if ((ep->emm[5] != reader[ridx].sa[i][0]) || 225 (ep->emm[6] != reader[ridx].sa[i][1]) || 226 (ep->emm[7] != reader[ridx].sa[i][2])) { 227 cs_log("EMM: Shared update did not match; EMM SA:%02X%02X%02X, Reader SA:%02X,%02X,%02X.",ep->emm[5],ep->emm[6],ep->emm[7],reader[ridx].sa[i][0],reader[ridx].sa[i][1],reader[ridx].sa[i][2]); 211 //prov id found, now test for SA (only first 3 bytes, custom byte does not count) 212 if (memcmp (ep->emm + 5, reader[ridx].sa[i], 3)) { 213 cs_log("EMM: Shared update did not match; EMM SA:%02X%02X%02X, provider %i, Reader SA:%s.", ep->emm[5], ep->emm[6], ep->emm[7], i + 1, cs_hexdump (0, reader[ridx].sa[i], 3)); 214 return(0); 215 } 216 else { 217 cs_log("EMM: Shared update matched for EMM SA %02X%02X%02X, provider %i.", ep->emm[5], ep->emm[6], ep->emm[7], i + 1); 218 ins40[3]=ep->emm[9]; 219 ins40[4]= emm_length - 0x07; 220 ins40data_offset = 10; 221 //memcpy(ins40data,ep->emm+10,256-10); 222 } 223 break; 224 }//end shared EMM 225 case 0x82: //unique EMM 226 { 227 //first test if UA matches 228 if (memcmp (reader[ridx].hexserial + 2, ep->emm + 3, 6)) { 229 cs_log("EMM: Unique update did not match; EMM Serial:%02X%02X%02X%02X%02X%02X, Reader Serial:%s.", ep->emm[3], ep->emm[4], ep->emm[5], ep->emm[6], ep->emm[7], ep->emm[8], cs_hexdump (0, reader[ridx].hexserial + 2, 6)); 230 return(0); 231 } 232 else { 233 //first find out prov id 234 i=get_prov_index((char *) ep->emm+9); 235 cs_log("EMM: Unique update matched EMM Serial:%02X%02X%02X%02X%02X, provider %i.", ep->emm[3], ep->emm[4], ep->emm[5], ep->emm[6], ep->emm[7], ep->emm[8], i + 1); 236 237 if (i==-1) 228 238 return(0); 229 } 230 else { 231 cs_log("EMM: Shared update matched for EMM SA %02X%02X%02X.",ep->emm[5],ep->emm[6],ep->emm[7]); 232 ins40[3]=ep->emm[9]; 233 ins40[4]=(ep->emm[1]&0x0f)*256+ep->emm[2]-0x07; 234 memcpy(ins40data,ep->emm+10,256-10); 235 } 236 237 }//end shared EMM 238 else 239 if (ep->emm[0] == 0x82) { //unique EMM 240 //first test if UA matches 241 if ((reader[ridx].hexserial[2] != ep->emm[3]) || 242 (reader[ridx].hexserial[3] != ep->emm[4]) || 243 (reader[ridx].hexserial[4] != ep->emm[5]) || 244 (reader[ridx].hexserial[5] != ep->emm[6]) || 245 (reader[ridx].hexserial[6] != ep->emm[7]) || 246 (reader[ridx].hexserial[7] != ep->emm[8])) { 247 cs_log("EMM: Unique update did not match; EMM Serial:%02X%02X%02X%02X%02X%02X, Reader Serial:%02X%02X%02X%02X%02X%02X.", ep->emm[3], ep->emm[4], ep->emm[5], ep->emm[6], ep->emm[7], ep->emm[8], reader[ridx].hexserial[2], reader[ridx].hexserial[3], reader[ridx].hexserial[4], reader[ridx].hexserial[5], reader[ridx].hexserial[6], reader[ridx].hexserial[7]); 248 return(0); 249 } 250 else { 251 cs_log("EMM: Unique update matched EMM Serial:%02X%02X%02X%02X%02X.", ep->emm[3], ep->emm[4], ep->emm[5], ep->emm[6], ep->emm[7], ep->emm[8]); 252 //first find out prov id 253 // i=get_prov_index(ep->emm[9],ep->emm[10]); 254 i=get_prov_index((char *) ep->emm+9); 255 if (i==-1) 256 return(0); 257 ins40[3]=ep->emm[12]; 258 ins40[4]=(ep->emm[1]&0x0f)*256+ep->emm[2]-0x0A; 259 memcpy(ins40data,ep->emm+13,256-13); 260 } 261 } //end unique EMM 262 else 263 return(0); //geen 0x84 en geen 0x82 264 239 ins40[3]=ep->emm[12]; 240 ins40[4]= emm_length - 0x0A; 241 ins40data_offset = 13; 242 //memcpy(ins40data,ep->emm+13,256-13); 243 } 244 break; 245 } //end unique EMM 246 case 0x88: //GA??? 247 case 0x89: //GA??? 248 cs_log("EMM: Congratulations, you have discovered a Global EMM on SECA. This has not been decoded yet, so send this output to authors:"); 249 cs_log("EMM: %s", cs_hexdump (0, ep->emm, emm_length)); 250 return 0; //no update took place 251 break; 252 default: 253 return 0; //unknown 254 } //end of switch 255 265 256 ins40[2]=i; 266 // length = ((er->ecm[1]<<8 || er->ecm[2])&0x0fff); 267 cs_debug("do_emm:ins40=%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x.",ins40[0],ins40[1],ins40[2],ins40[3],ins40[4],ins40data[0],ins40data[1],ins40data[2],ins40data[3],ins40data[4],ins40data[5],ins40data[6],ins40data[7],ins40data[8],ins40data[9]); 268 write_cmd(ins40, ins40data); //emm request 269 cs_debug("emmdump:%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x.",cta_res[0],cta_res[1],cta_res[2],cta_res[3],cta_res[4],cta_res[5],cta_res[6],cta_res[7],cta_res[8],cta_res[9],cta_res[10],cta_res[11],cta_res[12],cta_res[13],cta_res[14],cta_res[15],cta_res[16],cta_res[17]); 257 cs_debug("do_emm:ins40=%02x%02x%02x%02x%02x first 16 bytes of ins40data=%s", ins40[0], ins40[1], ins40[2], ins40[3], ins40[4], cs_hexdump (0, ep->emm + ins40data_offset, 16)); 258 write_cmd(ins40, ep->emm + ins40data_offset); //emm request 259 cs_debug("emmdump:%s", cs_hexdump(0, cta_res, 18)); 270 260 //TODO if ((cta_res[16] != 0x90) || (cta_res[17] != 0x00)) return (0); 271 261 // if ((cta_res[16] != 0x90) || (cta_res[17] != 0x19)) … … 282 272 283 273 } 284 #ifndef LALL 285 int seca_card_info(void) 286 { 287 int i; 288 cs_log("card detected"); 289 cs_ri_log("type: seca, caid: %04X, serial: %llu, card: %s ", 290 reader[ridx].caid[0], serial , card); 291 for (i=0; i<16; i++) 292 if (pmap&(1<<i)) 293 { 294 if (!set_provider_info(i)) 295 return(0); 274 275 int seca_card_info (void) 276 { 277 //Seca Package BitMap records (PBM) can be used to determine whether the channel is part of the package that the seca-card can decrypt. This module reads the PBM 278 //from the SECA card. It cannot be used to check the channel, because this information seems to reside in the CA-descriptor, which seems not to be passed on through servers like camd, newcamd, radegast etc. 279 // 280 //This module is therefore optical only 281 282 static unsigned char ins34[] = { 283 0xc1, 0x34, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 284 }; //data following is provider Package Bitmap Records 285 static unsigned char ins32[] = { 286 0xc1, 0x32, 0x00, 0x00, 0x20 287 }; // get PBM 288 //uchar ins32data[64]; 289 int prov; 290 uchar result[260]; 291 ushort result_size; 292 293 for (prov = 0; prov < reader[ridx].nprov; prov++) { 294 ins32[2] = prov; 295 write_cmd (ins34, ins34 + 5); //prepare card for pbm request 296 read_cmd(ins32, NULL); //pbm request 297 uchar pbm[8]; //TODO should be arrayed per prov 298 switch (cta_res[0]) { 299 case 0x04: 300 cs_log ("No PBM for provider %i", prov + 1); 301 break; 302 case 0x83: 303 cs_debug ("PBM dump for provider%i: %s", prov + 1, cs_hexdump (0, cta_res, 32)); 304 //cs_log ("PBM dump for provider%i: %s", prov + 1, cs_hexdump (0, cta_res, l)); 305 memcpy (pbm, cta_res + 1, 8); 306 cs_log ("PBM for provider %i: %s", prov + 1, cs_hexdump (0, pbm, 8)); 307 break; 308 default: 309 cs_log ("ERROR: PBM returns unknown byte %02x", cta_res[0]); 296 310 } 297 298 reader[ridx].online = 1; 299 300 return 1; 301 } 302 #endif 303 #ifdef LALL 304 int seca_card_info(void) 305 { 306 static uchar ins12[] = { 0xc1, 0x12, 0x00, 0x00, 0x19 }; // get provider info 307 int year, month, day; 308 struct tm *lt; 309 time_t t; 310 int valid=0;//0=false, 1=true 311 char l_name[16+8+1]=", name: "; 312 313 ins12[2]=i;//select provider 314 read_cmd(ins12, NULL); // show provider properties 315 cs_debug("hexdump:%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x.",cta_res[0],cta_res[1],cta_res[2],cta_res[3],cta_res[4],cta_res[5],cta_res[6],cta_res[7],cta_res[8],cta_res[9],cta_res[10],cta_res[11],cta_res[12],cta_res[13],cta_res[14],cta_res[15],cta_res[16],cta_res[17],cta_res[18],cta_res[19],cta_res[20],cta_res[21],cta_res[22],cta_res[23],cta_res[24],cta_res[25],cta_res[26]); 316 317 if ((cta_res[25] != 0x90) || (cta_res[26] != 0x00)) return (0); 318 reader[ridx].prid[i][0]=0; 319 reader[ridx].prid[i][1]=0;//blanken high byte provider code 320 memcpy(&reader[ridx].prid[i][2], cta_res, 2); 321 // sprintf(buf+strlen(buf), ",%06X", b2i(3, &reader[ridx].prid[i][1])); 322 323 year = (cta_res[22]>>1) + 1990; 324 month = ((cta_res[22]&0x1)*256 + (cta_res[23]&0xe0))>>5; 325 day = (cta_res[23]&0x1f); 326 t=time(NULL); 327 lt=localtime(&t); 328 if (lt->tm_year+1900 != year) 329 if (lt->tm_year+1900 < year) 330 valid=1; 331 else 332 valid=0; 333 else 334 if (lt->tm_mon+1 != month) 335 if (lt->tm_mon+1 < month) 336 valid=1; 337 else 338 valid=0; 339 else 340 if (lt->tm_mday != day) 341 if (lt->tm_mday < day) 342 valid=1; 343 else 344 valid=0; 345 memcpy(l_name+8, cta_res+2, 16); 346 l_name[sizeof(l_name)]=0; 347 trim(l_name+8); 348 l_name[0]=(l_name[8]) ? ',' : 0; 349 reader[ridx].availkeys[i][0]=valid; //misusing availkeys to register validity of provider 350 cs_log("provider: %d, valid: %i, expiry date: %i/%i/%i%s",i+1,valid,year,month,day,l_name); 351 memcpy(&reader[ridx].sa[i][0], cta_res+18, 4); 352 if (valid==1) //if not expired 353 cs_log("SA:%02X%02X%02X%02X.",cta_res[18],cta_res[19],cta_res[20],cta_res[21]); 354 355 reader[ridx].online = 1; 356 357 return(1); 358 } 359 #endif 311 } 312 313 reader[ridx].online = 1; // by okmikel 314 return (1); 315 } 316
Note:
See TracChangeset
for help on using the changeset viewer.