int NFC_Mifare_Classic(int argc, const char *argv[]) //! Lecture - Écriture d'une carte MIFARE Classic { action_t atAction = ACTION_USAGE; uint8_t *pbtUID; int unlock = 0; if (argc < 2) { sprintf(message_erreur,"Syntaxe incorrecte !"); return EXIT_FAILURE; //! Échec ! } const char *command = argv[1]; if (strcmp(command, "r") == 0 || strcmp(command, "R") == 0) { if (argc < 4) { sprintf(message_erreur,"Syntaxe incorrecte !"); return EXIT_FAILURE; //! Échec ! } atAction = ACTION_READ; if (strcmp(command, "R") == 0) { unlock = 1; } bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a'; bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2])); bUseKeyFile = (argc > 4); bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0)); } else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0) { if (argc < 4) { sprintf(message_erreur,"Syntaxe incorrecte !"); return EXIT_FAILURE; //! Échec ! } atAction = ACTION_WRITE; if (strcmp(command, "W") == 0) { unlock = 1; } bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a'; bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2])); bUseKeyFile = (argc > 4); bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0)); } if (atAction == ACTION_USAGE) { sprintf(message_erreur,"Syntaxe incorrecte !"); return EXIT_FAILURE; //! Échec ! } //! We don't know yet the card size so let's read only the UID from the keyfile for the moment if (bUseKeyFile) { FILE *pfKeys = fopen(argv[4], "rb"); if (pfKeys == NULL) { sprintf(message_erreur,"Could not open keys file: %s\n", argv[4]); return EXIT_FAILURE; //! Échec ! } if (fread(&mtKeys, 1, 4, pfKeys) != 4) { sprintf(message_erreur,"Could not read UID from key file: %s !", argv[4]); fclose(pfKeys); return EXIT_FAILURE; //! Échec ! } fclose(pfKeys); } nfc_init(&context); if (context == NULL) { sprintf(message_erreur,"Unable to init libnfc (malloc) !"); return EXIT_FAILURE; //! Échec ! } //! Try to open the NFC reader pnd = nfc_open(context, NULL); if (pnd == NULL) { sprintf(message_erreur,"Error opening NFC reader !"); nfc_exit(context); return EXIT_FAILURE; //! Échec ! } if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); nfc_strerror_r(pnd, message_erreur, TAILLE_MESSAGE_ERREUR); nfc_close(pnd); nfc_exit(context); return EXIT_FAILURE; //! Échec ! }; //! Let the reader only try once to find a tag if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_strerror_r(pnd, message_erreur, TAILLE_MESSAGE_ERREUR); nfc_close(pnd); nfc_exit(context); return EXIT_FAILURE; //! Échec ! } //! Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance. nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false); #ifdef DEBUG_PRINTF fprintf(stderr,"NFC reader: %s opened\n", nfc_device_get_name(pnd)); #endif //! Try to find a MIFARE Classic tag if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) { sprintf(message_erreur,"Error: no tag was found !"); nfc_close(pnd); nfc_exit(context); return EXIT_FAILURE; //! Échec ! } //! Test if we are dealing with a MIFARE compatible tag if ((nt.nti.nai.btSak & 0x08) == 0) { #ifdef DEBUG_PRINTF fprintf(stderr,"Warning: tag is probably not a MFC !"); #endif } //! Get the info from the current tag pbtUID = nt.nti.nai.abtUid; if (bUseKeyFile) { uint8_t fileUid[4]; memcpy(fileUid, mtKeys.amb[0].mbm.abtUID, 4); //! Compare if key dump UID is the same as the current tag UID, at least for the first 4 bytes if (memcmp(pbtUID, fileUid, 4) != 0) { #ifdef DEBUG_PRINTF fprintf(stderr,"Expected MIFARE Classic card with UID starting as: %02x%02x%02x%02x\n", fileUid[0], fileUid[1], fileUid[2], fileUid[3]); fprintf(stderr,"Got card with UID starting as: %02x%02x%02x%02x\n", pbtUID[0], pbtUID[1], pbtUID[2], pbtUID[3]); #endif if (! bForceKeyFile) { sprintf(message_erreur,"Aborting !"); nfc_close(pnd); nfc_exit(context); return EXIT_FAILURE; //! Échec ! } } } #ifdef DEBUG_PRINTF fprintf(stderr,"Found MIFARE Classic card:\n"); #endif print_nfc_target(&nt, false); //! Guessing size if ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x02) //! 4K uiBlocks = 0xff; else if ((nt.nti.nai.btSak & 0x01) == 0x01) //! 320b uiBlocks = 0x13; else //! 1K/2K, checked through RATS uiBlocks = 0x3f; //! Testing RATS int res; if ((res = get_rats()) > 0) { if ((res >= 10) && (abtRx[5] == 0xc1) && (abtRx[6] == 0x05) && (abtRx[7] == 0x2f) && (abtRx[8] == 0x2f) && ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x00)) { //! MIFARE Plus 2K uiBlocks = 0x7f; } //! Chinese magic emulation card, ATS=0978009102:dabc1910 if ((res == 9) && (abtRx[5] == 0xda) && (abtRx[6] == 0xbc) && (abtRx[7] == 0x19) && (abtRx[8] == 0x10)) { magic2 = true; } } #ifdef DEBUG_PRINTF fprintf(stderr,"Guessing size: seems to be a %i-byte card\n", (uiBlocks + 1) * 16); #endif if (bUseKeyFile) { FILE *pfKeys = fopen(argv[4], "rb"); if (pfKeys == NULL) { sprintf(message_erreur,"Could not open keys file: %s !", argv[4]); return EXIT_FAILURE; //! Échec ! } if (fread(&mtKeys, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfKeys) != (uiBlocks + 1) * sizeof(mifare_classic_block)) { sprintf(message_erreur,"Could not read keys file: %s !", argv[4]); fclose(pfKeys); return EXIT_FAILURE; //! Échec ! } fclose(pfKeys); } if (atAction == ACTION_READ) { memset(&mtDump, 0x00, sizeof(mtDump)); } else { FILE *pfDump = fopen(argv[3], "rb"); if (pfDump == NULL) { sprintf(message_erreur,"Could not open dump file: %s !", argv[3]); return EXIT_FAILURE; //! Échec ! } if (fread(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != (uiBlocks + 1) * sizeof(mifare_classic_block)) { sprintf(message_erreur,"Could not read dump file: %s !", argv[3]); fclose(pfDump); return EXIT_FAILURE; //! Échec ! } fclose(pfDump); } if (atAction == ACTION_READ) { if (read_card(unlock)) { #ifdef DEBUG_PRINTF fprintf(stderr,"Writing data to file: %s ...", argv[3]); #endif fflush(stdout); FILE *pfDump = fopen(argv[3], "wb"); if (pfDump == NULL) { sprintf(message_erreur,"Could not open dump file: %s !", argv[3]); nfc_close(pnd); nfc_exit(context); return EXIT_FAILURE; //! Échec ! } if (fwrite(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != ((uiBlocks + 1) * sizeof(mifare_classic_block))) { sprintf(message_erreur,"\nCould not write to file: %s !", argv[3]); fclose(pfDump); nfc_close(pnd); nfc_exit(context); return EXIT_FAILURE; //! Échec ! } #ifdef DEBUG_PRINTF fprintf(stderr,"Done.\n"); #endif fclose(pfDump); } else { nfc_close(pnd); nfc_exit(context); return EXIT_FAILURE; } } else if (atAction == ACTION_WRITE) { write_card(unlock); } nfc_close(pnd); nfc_exit(context); return EXIT_SUCCESS; //! Succès ! }
/* *********************************************************** * Function: fus_write_trailer() * * Description: write batch, totals, and file trailer records * * Input: fd FILE POINTER * tot_tran total detail records in file * tot_debit_amt total debit amount in pennies * tot_credit_amt total credit amount in pennies * * Output: None * * Returns: 1 if SUCCESS, 0 if Error **************************************************************** */ static int fus_write_trailer(FILE *fd, int tot_tran, Arb_numeric *tot_debit_amt, Arb_numeric *tot_credit_amt) { char card[512]; Arb_numeric result = ARB_NUMERIC_ZERO; char iamount[ARB_NUMERIC_LEN]; char idebit[ARB_NUMERIC_LEN]; char icredit[ARB_NUMERIC_LEN]; arb_num_arith(&result, tot_debit_amt, ARB_NUM_ADD, tot_credit_amt); arb_numeric_to_string(&result, iamount); arb_numeric_to_string(tot_debit_amt, idebit); arb_numeric_to_string(tot_credit_amt, icredit); if(!VerifyNumberString(iamount, FUS_FILE_AMOUNT_MAX_LENGTH) || !VerifyNumberString(idebit, FUS_FILE_AMOUNT_MAX_LENGTH) || !VerifyNumberString(icredit, FUS_FILE_AMOUNT_MAX_LENGTH)) { fprintf(RptFileFD,"\nERROR - Problem with total Amount!\n"); emit(FILE_LINE, CPM_WRITE_CARD, gFile_id); return (0); } /* Batch Totals record */ sprintf(card, "B #RECS=%.6d #ORDS=%.6d $TOT=%09.9s $SALES=%09.9s $REFUNDS=%09.9s ", ((tot_tran * 2) + 1), tot_tran, iamount, idebit, icredit); if (write_card(fd, card) != 1) { emit(FILE_LINE, CPM_WRITE_CARD, gFile_id); return(0); } /* File Totals record */ sprintf(card, "T #RECS=%.6d #ORDS=%.6d $TOT=%09.9s $SALES=%09.9s $REFUNDS=%09.9s ", ((tot_tran * 2) + 2), tot_tran, iamount, idebit, icredit); if (write_card(fd, card) != 1) { emit(FILE_LINE, CPM_WRITE_CARD, gFile_id); return(0); } /* File Trailer record */ sprintf(card,"PID=%-6.6s %-8.8s SID=%-6.6s %-8.8s END %-6.6s%-28.28s", gCH_curr.fus_pres_id, gCH_curr.fus_pres_pass, gCH_curr.fus_sub_id, gCH_curr.fus_sub_pass, &gFile_date_time[2], /* YYMMDD */ ""); if (write_card(fd, card) != 1) { emit(FILE_LINE, CPM_WRITE_CARD, gFile_id); return(0); } return(1); }
/* *********************************************************** * Function: knn_write_trailer() * * Description: write file trailer * * Input: fd FILE POINTER tot_tran total records in file tot_amt total amount * * Output: None * * Returns: 1 if SUCCESS, 0 if Error **************************************************************** */ static int knn_write_trailer(FILE *fd, int tot_tran, Arb_numeric *tot_amt) { char card[512]; char buff[ARB_NUMERIC_LEN]; arb_numeric_to_string(tot_amt, buff); if(!VerifyNumberString(buff, KNN_FILE_AMOUNT_MAX_LENGTH)) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); fprintf(RptFileFD,"\nERROR - Problem with total Amount length!\n"); return (0); } /* Add 2 to total record count (header and trailer */ sprintf(card, "TR%.8d%018.18s%-70.70s", tot_tran+2, buff, ""); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
/* *********************************************************** * Function: fus_write_detail_record() * * Description: write record to the out put file * * Input: fd FILE POINTER * data transaction data record * * Output: * * Returns: 1 if SUCCESS, 0 if Error **************************************************************** */ static int fus_write_detail_record(FILE *fd, TRANS *trec) { char card[512]; char unique_id[16]; char eft_trans_type; char acct_type; char iamount[ARB_NUMERIC_LEN]; /* A unique id per record */ /* Combine 2-digit tracking_id_serv, 10-digit tracking_id, 3 digit counter */ sprintf(unique_id, "%.2d%.10d%.3d", trec->tracking_id_serv, trec->tracking_id, trec->counter); if (trec->eft_trans_type == EFT_DEBIT_CHECK) { eft_trans_type = FUS_DEBIT_CHECKING; acct_type = FUS_ACCT_TYPE_CHECKING; } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_CHECK) { eft_trans_type = FUS_DEBIT_PRENOTE_CHECKING; acct_type = FUS_ACCT_TYPE_CHECKING; } else if (trec->eft_trans_type == EFT_DEBIT_SAVINGS) { eft_trans_type = FUS_DEBIT_SAVINGS; acct_type = FUS_ACCT_TYPE_SAVINGS; } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_SAVINGS) { eft_trans_type = FUS_DEBIT_PRENOTE_SAVINGS; acct_type = FUS_ACCT_TYPE_SAVINGS; } else if (trec->eft_trans_type == EFT_CREDIT_CHECK) { eft_trans_type = FUS_CREDIT_CHECKING; acct_type = FUS_ACCT_TYPE_CHECKING; } else if (trec->eft_trans_type == EFT_CREDIT_SAVINGS) { eft_trans_type = FUS_CREDIT_SAVINGS; acct_type = FUS_ACCT_TYPE_SAVINGS; } arb_numeric_to_string(&trec->amount, iamount); if(!VerifyNumberString(iamount, FUS_AMOUNT_MAX_LENGTH)) return (0); sprintf(card, "S%-6.6s%-16.16sO%cK%-9.9s%-17.17s %c B %07.7s%-16.16s", gCH_curr.fus_merchant_id, unique_id, eft_trans_type, trec->cust_bank_sort_code, trec->cust_bank_acc_num, acct_type, iamount, " "); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
/* *********************************************************** * Function: frn_write_trailer() * * Description: write file trailer * * Input: fd FILE POINTER * debit_amt debit amount * credit_amt credit amount * * Output: None * * Returns: 1 if SUCCESS, 0 if Error **************************************************************** */ static int frn_write_trailer(FILE *fd, Arb_numeric *debit_amt, Arb_numeric *credit_amt) { char card[512]; char *op_id; char debit_amount[ARB_NUMERIC_LEN]; /* CAMqa86327 */ char credit_amount[ARB_NUMERIC_LEN]; /* CAMqa86327 */ if (gCH_curr.frn_fast_mode) op_id = gCH_curr.frn_fast_op_id; else op_id = gCH_curr.frn_norm_op_id; /************************************************/ /* CAMqa86327 - Trailer record now has debit */ /* amount and credit amount separtely instead */ /* total amount. */ /************************************************/ arb_numeric_to_string(debit_amt, debit_amount); if(!VerifyNumberString(debit_amount, FRN_BATCH_AMOUNT_MAX_LENGTH)) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); fprintf(RptFileFD,"\nERROR - Problem with total Amount length!\n"); return (0); } arb_numeric_to_string(credit_amt, credit_amount); if(!VerifyNumberString(credit_amount, FRN_BATCH_AMOUNT_MAX_LENGTH)) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); fprintf(RptFileFD,"\nERROR - Problem with total Amount length!\n"); return (0); } /* BUG: Not handling 16 byte trailer amount well */ sprintf(card, "08%-2.2s%-8.8s%-6.6s%-84.84s%016.16s%016.16s%-26.26s", op_id, "", gCH_curr.frn_national_num, "", debit_amount, credit_amount, ""); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
/* *********************************************************** * Function: knn_write_detail_record() * * Description: write record to the out put file * * Input: fd FILE POINTER * data transaction data record * * Output: * * Returns: 1 if SUCCESS, 0 if Error **************************************************************** */ static int knn_write_detail_record(FILE *fd, TRANS *trec) { char card[512]; char unique_id[16]; int eft_trans_type; char buff[ARB_NUMERIC_LEN]; char scust_bank_acc_name[PAYMENT_PROFILE_ownr_lname_SZ-1]; /* A unique id per record */ /* Combine 2-digit tracking_id_serv, 10-digit tracking_id, 3 digit counter */ sprintf(unique_id, "%.2d%.10d%.3d", trec->tracking_id_serv, trec->tracking_id, trec->counter); if (trec->eft_trans_type == EFT_DEBIT_CHECK) { eft_trans_type = KNN_DEBIT_CHECKING; } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_CHECK) { eft_trans_type = KNN_DEBIT_PRENOTE_CHECKING; } else if (trec->eft_trans_type == EFT_DEBIT_SAVINGS) { eft_trans_type = KNN_DEBIT_SAVINGS; } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_SAVINGS) { eft_trans_type = KNN_DEBIT_PRENOTE_SAVINGS; } else if (trec->eft_trans_type == EFT_CREDIT_CHECK) { eft_trans_type = KNN_CREDIT_CHECKING; } else if (trec->eft_trans_type == EFT_CREDIT_SAVINGS) { eft_trans_type = KNN_CREDIT_SAVINGS; } arb_numeric_to_string(&trec->amount, buff); if(!VerifyNumberString(buff, KNN_AMOUNT_MAX_LENGTH)) return (0); arb_safe_strncpy(scust_bank_acc_name, trec->cust_bank_acc_name, 23); sprintf(card, "DT%c%-9.9s%-20.20s%018.18s%-22.22s%-6.6s%-15.15s0000 ", eft_trans_type, trec->cust_bank_sort_code, trec->cust_bank_acc_num, buff, scust_bank_acc_name, &gFile_date_time[2], unique_id); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
/* *********************************************************** * Function: knn_write_header() * * Description: write the header record for the send file * * Input: fd FILE Descripter * * Output: none * Return: 1 if SUCCESS, 0 if FAILURE **************************************************************** */ static int knn_write_header(FILE *fd) { char card[512]; sprintf(card,"HD%-12.12s%-4.4sCOMVERSE %-6.6s%-6.6s%.8d%-50.50s", gCH_curr.knn_merchant_acct, gCH_curr.knn_merchant_id, &gFile_date_time[2], /* Date time is YYYYMMDDhhmmss, we need YYMMDD */ &gFile_date_time[8], /* Date time is YYYYMMDDhhmmss, we need hhmmss */ gCycle_id, " "); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
/*********************************************************** * Function: fus_write_addr_record() * * Description: write record to the out put file * * Input: fd FILE POINTER * data transaction data record * * Output: * * Returns: 1 if SUCCESS, 0 if Error ***********************************************************/ static int fus_write_addr_record(FILE *fd, TRANS *trec) { char card[512]; char scust_bank_acc_name[PAYMENT_PROFILE_ownr_lname_SZ-1]; arb_safe_strncpy(scust_bank_acc_name, trec->cust_bank_acc_name, 31); sprintf(card, "AM%-30.30s%-48.48s", scust_bank_acc_name, ""); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
/* *********************************************************** * Function: fus_write_header() * * Description: write the header record for the send file * * Input: fd FILE Descripter * * Output: none * Return: 1 if SUCCESS, 0 if FAILURE **************************************************************** */ static int fus_write_header(FILE *fd) { char card[512]; sprintf(card,"PID=%-6.6s %-8.8s SID=%-6.6s %-8.8s START %-6.6s%-6.6s%.8d%-14.14s", gCH_curr.fus_pres_id, gCH_curr.fus_pres_pass, gCH_curr.fus_sub_id, gCH_curr.fus_sub_pass, &gFile_date_time[2], /* YYMMDD */ &gFile_date_time[8], /* hhmmss */ gCycle_id, " "); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
/* *********************************************************** * Function: frn_write_header() * * Description: write the header record for the send file * * Input: fd FILE Descripter * * Output: none * Return: 1 if SUCCESS, 0 if FAILURE **************************************************************** */ static int frn_write_header(FILE *fd, CURRENCY_STRUCT *currency_struct) { char card[512]; char *op_id; char ppdd_date[7]; char *currency_format = (char*)" "; if (gLanguage_code > 0) strcpy(currency_format, currency_struct->currency_format); /* need DDMMY value, not yyyymmdd */ sprintf(ppdd_date, "%-2.2s%-2.2s%-1.1s", &gPpdd_day[6], &gPpdd_day[4], &gPpdd_day[3]); if (gCH_curr.frn_fast_mode) op_id = gCH_curr.frn_fast_op_id; else op_id = gCH_curr.frn_norm_op_id; sprintf(card,"03%-2.2s %-6.6s %-5.5s%-24.24s%.7d%-19.19s%1.1s%-5.5s%-5.5s%-11.11s%-47.47s%-5.5s ", op_id, gCH_curr.frn_national_num, ppdd_date, /* DDMMY, ppdd_date/posting date */ gCH_curr.frn_company_name, gCycle_id, " ", currency_format, /* Added for CAMqa54502 */ " ", gCH_curr.frn_agency_code, gCH_curr.frn_account_num, " ", gCH_curr.frn_bank_code); if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
bool psxcard_device::transfer(uint8_t to, uint8_t *from) { bool ret=true; switch (state) { case state_illegal: if (is_loaded()) { // printf("CARD: begin\n"); state = state_command; *from = 0x00; } else { ret = false; } break; case state_command: cmd=to; *from=0x5a; state=state_cmdack; break; case state_cmdack: *from=0x5d; state=state_wait; break; case state_wait: *from=0x00; state=state_addr_hi; break; case state_addr_hi: addr=(to<<8); // printf("addr_hi: %02x, addr = %x\n", to, addr); *from=to; state=state_addr_lo; break; case state_addr_lo: addr|=(to&0xff); // printf("addr_lo: %02x, addr = %x, cmd = %x\n", to, addr, cmd); switch (cmd) { case 'R': // 0x52 { pkt[0]=*from=0x5c; pkt[1]=0x5d; pkt[2]=(addr>>8); pkt[3]=(addr&0xff); read_card(addr,&pkt[4]); pkt[4+128]=checksum_data(&pkt[2],128+2); pkt[5+128]=0x47; pkt_sz=6+128; pkt_ptr=1; state=state_read; break; } case 'W': // 0x57 { pkt[0]=addr>>8; pkt[1]=addr&0xff; pkt_sz=129+2; pkt_ptr=2; state=state_write; *from=to; break; } default: state=state_illegal; break; } break; case state_read: //assert(to==0); // printf("state_read: pkt_ptr = %d, pkt_sz = %d\n", pkt_ptr, pkt_sz); *from=pkt[pkt_ptr++]; if (pkt_ptr==pkt_sz) { #ifdef debug_card printf("card: read finished\n"); #endif state=state_end; } break; case state_write: *from=to; pkt[pkt_ptr++]=to; if (pkt_ptr==pkt_sz) { *from=0x5c; state=state_writeack_2; } break; case state_writeack_2: *from=0x5d; state=state_writechk; break; case state_writechk: { unsigned char chk=checksum_data(pkt,128+2); if (chk==pkt[128+2]) { #ifdef debug_card printf("card: write ok\n"); #endif write_card(addr,pkt+2); *from='G'; } else { #ifdef debug_card printf("card: write fail\n"); #endif *from='N'; } state=state_end; break; } case state_end: ret = false; state = state_illegal; break; default: /*assert(0);*/ ret=false; break; } #ifdef debug_card // printf("card: transfer to=%02x from=%02x ret=%c\n",to,*from,ret ? 'T' : 'F'); #endif return ret; }
/* *********************************************************** * Function: frn_write_detail_record() * * Description: write record to the output file * * Input: fd FILE POINTER * data transaction data record * tran_ind credit/debit indicator * * Output: * * Returns: 1 if SUCCESS, 0 if Error **************************************************************** */ static int frn_write_detail_record(FILE *fd, TRANS *trec, char *currency_format) { char card[512]; char unique_id[16]; char *op_id; int iamount = 0; char scust_bank_acc_name[PAYMENT_PROFILE_ownr_lname_SZ-1]; char trans_type; /* CAMqa86327 */ char str_amount[ARB_NUMERIC_LEN]; /* DENqa05053 */ /* A unique id per record */ /* Combine 2-digit tracking_id_serv, 10-digit tracking_id, 3 digit counter */ sprintf(unique_id, "%.2d%.10d%.3d", trec->tracking_id_serv, trec->tracking_id, trec->counter); if (gCH_curr.frn_fast_mode) op_id = gCH_curr.frn_fast_op_id; else op_id = gCH_curr.frn_norm_op_id; /*****************************************************/ /* DENqa05053 */ /* Leaving iamount for FT specific record layout */ /* Adding string like what is used in trailer to */ /* handle amount up to 16 byte length */ /*****************************************************/ arb_numeric_to_int(&trec->amount, &iamount); arb_numeric_to_string(&trec->amount, str_amount); if(!VerifyNumberString(str_amount, FRN_AMOUNT_MAX_LENGTH)) return (0); arb_safe_strncpy(scust_bank_acc_name, trec->cust_bank_acc_name, 25); /*************************************************************/ /* CAMqa86327 - set transaction type to either C (credit) or */ /* D (debit) depending on the eft_trans_type. */ /*************************************************************/ if (trec->eft_trans_type == EFT_DEBIT_CHECK || trec->eft_trans_type == EFT_DEBIT_SAVINGS || trec->eft_trans_type == EFT_DEBIT_PRENOTE_CHECK || trec->eft_trans_type == EFT_DEBIT_PRENOTE_SAVINGS) { trans_type = 'D'; /* debit */ } else { trans_type = 'C'; /* credit */ } /* FT Specific compile option for alternative FT specific record layout */ #ifdef FT sprintf(card, "06%-2.2s%-8.8s%-6.6s%.12d%-24.24s%-24.24s%-2.2s%1.1s%-5.5s%-5.5s%-11.11s%.16d*%-15.15s%.9d %-5.5s%c%-5.5s", op_id, "", gCH_curr.frn_national_num, trec->bill_ref_no, scust_bank_acc_name, trec->bank_agency_name, "", currency_format, /* Added for CAMqa54502 */ "", trec->bank_agency_code, trec->cust_bank_acc_num, iamount, unique_id, trec->bill_ref_no, trec->cust_bank_sort_code, trans_type, ""); #else /* BUG: we are not handling the full 16 byte amount well. */ sprintf(card, "06%-2.2s%-8.8s%-6.6s%.12d%-24.24s%-24.24s%-8.8s%-5.5s%-11.11s%016.16s%-15.15s%.16d%-5.5s%c%-5.5s", op_id, "", gCH_curr.frn_national_num, trec->bill_ref_no, scust_bank_acc_name, trec->bank_agency_name, "", trec->bank_agency_code, trec->cust_bank_acc_num, str_amount, unique_id, trec->bill_ref_no, trec->cust_bank_sort_code, trans_type, ""); #endif if (write_card(fd, card) != 1) { emit(FILE_LINE, EFT_WRITE_CARD, gFile_id); return(0); } return(1); }
int main (int argc, const char *argv[]) { bool bReadAction; FILE *pfDump; if (argc < 3) { printf ("\n"); printf ("%s r|w <dump.mfd>\n", argv[0]); printf ("\n"); printf ("r|w - Perform read from or write to card\n"); printf ("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n"); printf ("\n"); return 1; } DBG ("\nChecking arguments and settings\n"); bReadAction = tolower ((int) ((unsigned char) *(argv[1])) == 'r'); if (bReadAction) { memset (&mtDump, 0x00, sizeof (mtDump)); } else { pfDump = fopen (argv[2], "rb"); if (pfDump == NULL) { ERR ("Could not open dump file: %s\n", argv[2]); return 1; } if (fread (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) { ERR ("Could not read from dump file: %s\n", argv[2]); fclose (pfDump); return 1; } fclose (pfDump); } DBG ("Successfully opened the dump file\n"); // Try to open the NFC device pnd = nfc_connect (NULL); if (pnd == NULL) { ERR ("Error connecting NFC device\n"); return 1; } nfc_initiator_init (pnd); // Drop the field for a while if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) { nfc_perror (pnd, "nfc_configure"); exit (EXIT_FAILURE); } // Let the device only try once to find a tag if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) { nfc_perror (pnd, "nfc_configure"); exit (EXIT_FAILURE); } if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) { nfc_perror (pnd, "nfc_configure"); exit (EXIT_FAILURE); } if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) { nfc_perror (pnd, "nfc_configure"); exit (EXIT_FAILURE); } // Enable field so more power consuming cards can power themselves up if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) { nfc_perror (pnd, "nfc_configure"); exit (EXIT_FAILURE); } printf ("Connected to NFC device: %s\n", pnd->acName); // Try to find a MIFARE Ultralight tag if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) { ERR ("no tag was found\n"); nfc_disconnect (pnd); return 1; } // Test if we are dealing with a MIFARE compatible tag if (nt.nti.nai.abtAtqa[1] != 0x44) { ERR ("tag is not a MIFARE Ultralight card\n"); nfc_disconnect (pnd); return EXIT_FAILURE; } // Get the info from the current tag printf ("Found MIFARE Ultralight card with UID: "); size_t szPos; for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) { printf ("%02x", nt.nti.nai.abtUid[szPos]); } printf("\n"); if (bReadAction) { if (read_card ()) { printf ("Writing data to file: %s ... ", argv[2]); fflush (stdout); pfDump = fopen (argv[2], "wb"); if (pfDump == NULL) { printf ("Could not open file: %s\n", argv[2]); return EXIT_FAILURE; } if (fwrite (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) { printf ("Could not write to file: %s\n", argv[2]); return EXIT_FAILURE; } fclose (pfDump); printf ("Done.\n"); } } else { write_card (); } nfc_disconnect (pnd); return EXIT_SUCCESS; }
int main(int argc, const char *argv[]) { bool bReadAction; FILE *pfDump; if (argc < 3) { printf("\n"); printf("%s r|w <dump.mfd>\n", argv[0]); printf("\n"); printf("r|w - Perform read from or write to card\n"); printf("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n"); printf("\n"); exit(EXIT_FAILURE); } DBG("\nChecking arguments and settings\n"); bReadAction = tolower((int)((unsigned char) * (argv[1])) == 'r'); if (bReadAction) { memset(&mtDump, 0x00, sizeof(mtDump)); } else { pfDump = fopen(argv[2], "rb"); if (pfDump == NULL) { ERR("Could not open dump file: %s\n", argv[2]); exit(EXIT_FAILURE); } if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { ERR("Could not read from dump file: %s\n", argv[2]); fclose(pfDump); exit(EXIT_FAILURE); } fclose(pfDump); } DBG("Successfully opened the dump file\n"); nfc_context *context; nfc_init(&context); if (context == NULL) { ERR("Unable to init libnfc (malloc)"); exit(EXIT_FAILURE); } // Try to open the NFC device pnd = nfc_open(context, NULL); if (pnd == NULL) { ERR("Error opening NFC device"); nfc_exit(context); exit(EXIT_FAILURE); } if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Let the device only try once to find a tag if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); // Try to find a MIFARE Ultralight tag if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) { ERR("no tag was found\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Test if we are dealing with a MIFARE compatible tag if (nt.nti.nai.abtAtqa[1] != 0x44) { ERR("tag is not a MIFARE Ultralight card\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Get the info from the current tag printf("Found MIFARE Ultralight card with UID: "); size_t szPos; for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) { printf("%02x", nt.nti.nai.abtUid[szPos]); } printf("\n"); if (bReadAction) { if (read_card()) { printf("Writing data to file: %s ... ", argv[2]); fflush(stdout); pfDump = fopen(argv[2], "wb"); if (pfDump == NULL) { printf("Could not open file: %s\n", argv[2]); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { printf("Could not write to file: %s\n", argv[2]); fclose(pfDump); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } fclose(pfDump); printf("Done.\n"); } } else { write_card(); } nfc_close(pnd); nfc_exit(context); exit(EXIT_SUCCESS); }
int main(int argc, const char *argv[]) { int iAction = 0; uint8_t iUID[MAX_UID_LEN] = { 0x0 }; size_t szUID = 0; bool bOTP = false; bool bLock = false; bool bUID = false; FILE *pfDump; if (argc < 2) { print_usage(argv); exit(EXIT_FAILURE); } DBG("\nChecking arguments and settings\n"); // Get commandline options for (int arg = 1; arg < argc; arg++) { if (0 == strcmp(argv[arg], "r")) { iAction = 1; } else if (0 == strcmp(argv[arg], "w")) { iAction = 2; } else if (0 == strcmp(argv[arg], "--with-uid")) { if (argc < 5) { ERR("Please supply a UID of 4, 7 or 10 bytes long. Ex: a1:b2:c3:d4"); exit(EXIT_FAILURE); } szUID = str_to_uid(argv[4], iUID); } else if (0 == strcmp(argv[arg], "--full")) { bOTP = true; bLock = true; bUID = true; } else if (0 == strcmp(argv[arg], "--otp")) { bOTP = true; } else if (0 == strcmp(argv[arg], "--lock")) { bLock = true; } else if (0 == strcmp(argv[arg], "--uid")) { bUID = true; } else if (0 == strcmp(argv[arg], "--check-magic")) { iAction = 3; } else { //Skip validation of the filename if ((arg != 2) && (arg != 4)) { ERR("%s is not supported option.", argv[arg]); print_usage(argv); exit(EXIT_FAILURE); } } } if (iAction == 1) { memset(&mtDump, 0x00, sizeof(mtDump)); } else if (iAction == 2) { pfDump = fopen(argv[2], "rb"); if (pfDump == NULL) { ERR("Could not open dump file: %s\n", argv[2]); exit(EXIT_FAILURE); } if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { ERR("Could not read from dump file: %s\n", argv[2]); fclose(pfDump); exit(EXIT_FAILURE); } fclose(pfDump); DBG("Successfully opened the dump file\n"); } else if (iAction == 3) { DBG("Switching to Check Magic Mode\n"); } else { ERR("Unable to determine operating mode"); exit(EXIT_FAILURE); } nfc_context *context; nfc_init(&context); if (context == NULL) { ERR("Unable to init libnfc (malloc)"); exit(EXIT_FAILURE); } // Try to open the NFC device pnd = nfc_open(context, NULL); if (pnd == NULL) { ERR("Error opening NFC device"); nfc_exit(context); exit(EXIT_FAILURE); } printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); if (list_passive_targets(pnd)) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Let the device only try once to find a tag if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Try to find a MIFARE Ultralight tag if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) { ERR("no tag was found\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Test if we are dealing with a MIFARE compatible tag if (nt.nti.nai.abtAtqa[1] != 0x44) { ERR("tag is not a MIFARE Ultralight card\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Get the info from the current tag printf("Using MIFARE Ultralight card with UID: "); size_t szPos; for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) { printf("%02x", nt.nti.nai.abtUid[szPos]); } printf("\n"); if (iAction == 1) { if (read_card()) { printf("Writing data to file: %s ... ", argv[2]); fflush(stdout); pfDump = fopen(argv[2], "wb"); if (pfDump == NULL) { printf("Could not open file: %s\n", argv[2]); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { printf("Could not write to file: %s\n", argv[2]); fclose(pfDump); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } fclose(pfDump); printf("Done.\n"); } } else if (iAction == 2) { write_card(bOTP, bLock, bUID); } else if (iAction == 3) { if (!check_magic()) { printf("Card is not magic\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } else { printf("Card is magic\n"); } } nfc_close(pnd); nfc_exit(context); exit(EXIT_SUCCESS); }
int main(int argc, const char *argv[]) { int iAction = 0; uint8_t iDumpSize = sizeof(mifareul_tag); uint8_t iUID[MAX_UID_LEN] = { 0x0 }; size_t szUID = 0; bool bOTP = false; bool bLock = false; bool bUID = false; bool bPWD = false; bool bPart = false; bool bFilename = false; FILE *pfDump; if (argc < 3) { print_usage(argv); exit(EXIT_FAILURE); } DBG("\nChecking arguments and settings\n"); // Get commandline options for (int arg = 1; arg < argc; arg++) { if (0 == strcmp(argv[arg], "r")) { iAction = 1; } else if (0 == strcmp(argv[arg], "w")) { iAction = 2; } else if (0 == strcmp(argv[arg], "--with-uid")) { if (arg + 1 == argc) { ERR("Please supply a UID of 4, 7 or 10 bytes long. Ex: a1:b2:c3:d4"); exit(EXIT_FAILURE); } szUID = str_to_uid(argv[++arg], iUID); } else if (0 == strcmp(argv[arg], "--full")) { bOTP = true; bLock = true; bUID = true; } else if (0 == strcmp(argv[arg], "--otp")) { bOTP = true; } else if (0 == strcmp(argv[arg], "--lock")) { bLock = true; } else if (0 == strcmp(argv[arg], "--uid")) { bUID = true; } else if (0 == strcmp(argv[arg], "--check-magic")) { iAction = 3; } else if (0 == strcmp(argv[arg], "--partial")) { bPart = true; } else if (0 == strcmp(argv[arg], "--pw")) { bPWD = true; if (arg + 1 == argc || strlen(argv[++arg]) != 8 || ! ev1_load_pwd(iPWD, argv[arg])) { ERR("Please supply a PASSWORD of 8 HEX digits"); exit(EXIT_FAILURE); } } else { //Skip validation of the filename if (arg != 2) { ERR("%s is not a supported option.", argv[arg]); print_usage(argv); exit(EXIT_FAILURE); } else { bFilename = true; } } } if (! bFilename) { ERR("Please supply a Mifare Dump filename"); exit(EXIT_FAILURE); } nfc_context *context; nfc_init(&context); if (context == NULL) { ERR("Unable to init libnfc (malloc)"); exit(EXIT_FAILURE); } // Try to open the NFC device pnd = nfc_open(context, NULL); if (pnd == NULL) { ERR("Error opening NFC device"); nfc_exit(context); exit(EXIT_FAILURE); } printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); if (list_passive_targets(pnd)) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Let the device only try once to find a tag if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Try to find a MIFARE Ultralight tag if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) { ERR("no tag was found\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Test if we are dealing with a MIFARE compatible tag if (nt.nti.nai.abtAtqa[1] != 0x44) { ERR("tag is not a MIFARE Ultralight card\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Get the info from the current tag printf("Using MIFARE Ultralight card with UID: "); size_t szPos; for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) { printf("%02x", nt.nti.nai.abtUid[szPos]); } printf("\n"); // test if tag is EV1 if (get_ev1_version()) { if (!bPWD) printf("Tag is EV1 - PASSWORD may be required\n"); printf("EV1 storage size: "); if (abtRx[6] == 0x0b) { printf("48 bytes\n"); uiBlocks = 0x14; iEV1Type = EV1_UL11; iDumpSize = sizeof(mifareul_ev1_mf0ul11_tag); } else if (abtRx[6] == 0x0e) { printf("128 bytes\n"); uiBlocks = 0x29; iEV1Type = EV1_UL21; iDumpSize = sizeof(mifareul_ev1_mf0ul21_tag); } else printf("unknown!\n"); } else { // re-init non EV1 tag if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) { ERR("no tag was found\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } } // EV1 login required if (bPWD) { printf("Authing with PWD: %02x%02x%02x%02x ", iPWD[0], iPWD[1], iPWD[2], iPWD[3]); if (!ev1_pwd_auth(iPWD)) { printf("\n"); ERR("AUTH failed!\n"); exit(EXIT_FAILURE); } else { printf("Success - PACK: %02x%02x\n", abtRx[0], abtRx[1]); memcpy(iPACK, abtRx, 2); } } if (iAction == 1) { memset(&mtDump, 0x00, sizeof(mtDump)); } else if (iAction == 2) { pfDump = fopen(argv[2], "rb"); if (pfDump == NULL) { ERR("Could not open dump file: %s\n", argv[2]); exit(EXIT_FAILURE); } size_t szDump; if (((szDump = fread(&mtDump, 1, sizeof(mtDump), pfDump)) != iDumpSize && !bPart) || szDump <= 0) { ERR("Could not read from dump file or size mismatch: %s\n", argv[2]); fclose(pfDump); exit(EXIT_FAILURE); } if (szDump != iDumpSize) printf("Performing partial write\n"); fclose(pfDump); DBG("Successfully opened the dump file\n"); } else if (iAction == 3) { DBG("Switching to Check Magic Mode\n"); } else { ERR("Unable to determine operating mode"); exit(EXIT_FAILURE); } if (iAction == 1) { bool bRF = read_card(); printf("Writing data to file: %s ... ", argv[2]); fflush(stdout); pfDump = fopen(argv[2], "wb"); if (pfDump == NULL) { printf("Could not open file: %s\n", argv[2]); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (fwrite(&mtDump, 1, uiReadPages * 4, pfDump) != uiReadPages * 4) { printf("Could not write to file: %s\n", argv[2]); fclose(pfDump); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } fclose(pfDump); printf("Done.\n"); if (!bRF) printf("Warning! Read failed - partial data written to file!\n"); } else if (iAction == 2) { write_card(bOTP, bLock, bUID); } else if (iAction == 3) { if (!check_magic()) { printf("Card is not magic\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } else { printf("Card is magic\n"); } } nfc_close(pnd); nfc_exit(context); exit(EXIT_SUCCESS); }