summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2006-11-28 10:06:24 +0000
committerlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2006-11-28 10:06:24 +0000
commit2da53a43badc7bd578ab5df850648f14807aecd2 (patch)
tree7041dc431c25664d9ba280a02504157407eb774d /utils
parentc972071a03825d8fe595d33f9128b4341b0478bd (diff)
- fix mifare write support
- make mifare auth more reliable - add mifare permission / access bit en/decoding - some more 15693 bits - add new 'mifare-tool' program git-svn-id: https://svn.gnumonks.org/trunk/librfid@1928 e0336214-984f-0b4b-a45f-81c69e1f0ede
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile.am10
-rw-r--r--utils/common.c125
-rw-r--r--utils/librfid-tool.c202
-rw-r--r--utils/librfid-tool.h35
-rw-r--r--utils/mifare-tool.c207
5 files changed, 480 insertions, 99 deletions
diff --git a/utils/Makefile.am b/utils/Makefile.am
index f2b161e..7ad826e 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -1,11 +1,17 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include
-bin_PROGRAMS = librfid-tool send_script
+bin_PROGRAMS = librfid-tool mifare-tool send_script
-librfid_tool_SOURCES = librfid-tool.c
+librfid_tool_SOURCES = librfid-tool.c common.c
librfid_tool_LDADD = ../src/librfid.la
librfid_tool_LDFLAGS = -dynamic
send_script_SOURCES= send_script.c
send_script_LDADD = ../src/librfid.la
send_script_LDFLAGS = -dynamic
+
+mifare_tool_SOURCES = mifare-tool.c common.c
+mifare_tool_LDADD = ../src/librfid.la
+mifare_tool_LDFLAGS = -dynamic
+
+
diff --git a/utils/common.c b/utils/common.c
new file mode 100644
index 0000000..2966ab4
--- /dev/null
+++ b/utils/common.c
@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <libgen.h>
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_scan.h>
+#include <librfid/rfid_reader.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_protocol.h>
+
+#include <librfid/rfid_protocol_mifare_classic.h>
+#include <librfid/rfid_protocol_mifare_ul.h>
+
+#include "librfid-tool.h"
+
+const char *
+hexdump(const void *data, unsigned int len)
+{
+ static char string[1024];
+ unsigned char *d = (unsigned char *) data;
+ unsigned int i, left;
+
+ string[0] = '\0';
+ left = sizeof(string);
+ for (i = 0; len--; i += 3) {
+ if (i >= sizeof(string) -4)
+ break;
+ snprintf(string+i, 4, " %02x", *d++);
+ }
+ return string;
+}
+
+static char parse_hexdigit(const char hexdigit)
+{
+ if (hexdigit <= '9' && hexdigit >= '0')
+ return hexdigit - '0';
+ if (hexdigit <= 'f' && hexdigit >= 'a')
+ return 10 + (hexdigit - 'a');
+
+ return 0;
+}
+
+int
+hexread(unsigned char *result, const unsigned char *in, unsigned int len)
+{
+ const unsigned char *pos;
+ char dig1, dig2;
+ unsigned char *res = result;
+
+ for (pos = in; pos-in <= len-2; pos+=2) {
+ if (*pos == ':') {
+ pos++;
+ continue;
+ }
+ dig1 = *pos;
+ dig2 = *(pos+1);
+
+ *res++ = parse_hexdigit(dig1) << 4 | parse_hexdigit(dig2);
+ }
+
+ return (res - result);
+}
+
+struct rfid_reader_handle *rh;
+struct rfid_layer2_handle *l2h;
+struct rfid_protocol_handle *ph;
+
+int reader_init(void)
+{
+ printf("opening reader handle\n");
+ rh = rfid_reader_open(NULL, RFID_READER_CM5121);
+ if (!rh) {
+ fprintf(stderr, "No Omnikey Cardman 5121 found\n");
+ rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
+ if (!rh) {
+ fprintf(stderr, "No OpenPCD found either\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int l2_init(int layer2)
+{
+ unsigned char buf[0x3f];
+ int rc;
+
+ printf("opening layer2 handle\n");
+ l2h = rfid_layer2_init(rh, layer2);
+ if (!l2h) {
+ fprintf(stderr, "error during iso14443a_init\n");
+ return -1;
+ }
+
+ printf("running layer2 anticol\n");
+ rc = rfid_layer2_open(l2h);
+ if (rc < 0) {
+ fprintf(stderr, "error during layer2_open\n");
+ return rc;
+ }
+
+ return 0;
+}
+
+int l3_init(int protocol)
+{
+ printf("running layer3 (ats)\n");
+ ph = rfid_protocol_init(l2h, protocol);
+ if (!ph) {
+ fprintf(stderr, "error during protocol_init\n");
+ return -1;
+ }
+ if (rfid_protocol_open(ph) < 0) {
+ fprintf(stderr, "error during protocol_open\n");
+ return -1;
+ }
+
+ printf("we now have layer3 up and running\n");
+
+ return 0;
+}
+
diff --git a/utils/librfid-tool.c b/utils/librfid-tool.c
index e1270f1..37efadc 100644
--- a/utils/librfid-tool.c
+++ b/utils/librfid-tool.c
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <libgen.h>
#define _GNU_SOURCE
#include <getopt.h>
@@ -34,84 +35,8 @@
#include <librfid/rfid_protocol_mifare_classic.h>
#include <librfid/rfid_protocol_mifare_ul.h>
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#include "librfid-tool.h"
-static const char *
-hexdump(const void *data, unsigned int len)
-{
- static char string[1024];
- unsigned char *d = (unsigned char *) data;
- unsigned int i, left;
-
- string[0] = '\0';
- left = sizeof(string);
- for (i = 0; len--; i += 3) {
- if (i >= sizeof(string) -4)
- break;
- snprintf(string+i, 4, " %02x", *d++);
- }
- return string;
-}
-
-static struct rfid_reader_handle *rh;
-static struct rfid_layer2_handle *l2h;
-static struct rfid_protocol_handle *ph;
-
-static int reader() {
- printf("opening reader handle\n");
- rh = rfid_reader_open(NULL, RFID_READER_CM5121);
- if (!rh) {
- fprintf(stderr, "No Omnikey Cardman 5121 found\n");
- rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
- if (!rh) {
- fprintf(stderr, "No OpenPCD found either\n");
- return -1;
- }
- }
- return 0;
-}
-static int init(int layer2)
-{
- unsigned char buf[0x3f];
- int rc;
-
-
- printf("opening layer2 handle\n");
- l2h = rfid_layer2_init(rh, layer2);
- if (!l2h) {
- fprintf(stderr, "error during iso14443a_init\n");
- return -1;
- }
-
- //rc632_register_dump(rh->ah, buf);
-
- printf("running layer2 anticol\n");
- rc = rfid_layer2_open(l2h);
- if (rc < 0) {
- fprintf(stderr, "error during layer2_open\n");
- return rc;
- }
-
- return 0;
-}
-
-static int l3(int protocol)
-{
- printf("running layer3 (ats)\n");
- ph = rfid_protocol_init(l2h, protocol);
- if (!ph) {
- fprintf(stderr, "error during protocol_init\n");
- return -1;
- }
- if (rfid_protocol_open(ph) < 0) {
- fprintf(stderr, "error during protocol_open\n");
- return -1;
- }
-
- printf("we now have layer3 up and running\n");
-
- return 0;
-}
static int select_mf(void)
{
@@ -277,15 +202,17 @@ mifare_classic_read_sector(struct rfid_protocol_handle *ph, int sector)
int block;
/* FIXME: make this work for sectors > 31 */
- printf("reading sector %u\n", sector);
+ printf("Reading sector %u\n", sector);
for (block = sector*4; block < sector*4+4; block++) {
- printf("reading block %u\n", block);
+ printf("Reading block %u: ", block);
ret = rfid_protocol_read(ph, block, buf, &len);
if(ret == -ETIMEDOUT)
fprintf(stderr, "TIMEOUT\n");
- if (ret < 0)
+ if (ret < 0) {
+ printf("Error %d reading\n", ret);
return ret;
+ }
printf("Page 0x%x: %s\n", block, hexdump(buf, len));
}
@@ -348,47 +275,126 @@ static void do_scan(void)
}
}
-static void help(void)
-{
- printf( " -s --scan\n"
- " -p --protocol {tcl,mifare-ultralight,mifare-classic}\n"
- " -l --layer2 {iso14443a,iso14443b,iso15693}\n"
- " -h --help\n");
-}
+#define OPTION_OFFSET 256
-static struct option opts[] = {
+static struct option original_opts[] = {
{ "help", 0, 0, 'h' },
{ "layer2", 1, 0, 'l' },
{ "protocol", 1, 0, 'p' },
+ { "scan", 0, 0, 's' },
+ { "scan-loop", 0, 0, 'S' },
{0, 0, 0, 0}
};
+/* module / option merging code */
+static struct option *opts = original_opts;
+static unsigned int global_option_offset = 0;
+
+static char *program_name;
+static char *program_version = LIBRFID_TOOL_VERSION;
+
+static void free_opts(int reset_offset)
+{
+ if (opts != original_opts) {
+ free(opts);
+ opts = original_opts;
+ if (reset_offset)
+ global_option_offset = 0;
+ }
+}
+
+static struct option *
+merge_options(struct option *oldopts, const struct option *newopts,
+ unsigned int *option_offset)
+{
+ unsigned int num_old, num_new, i;
+ struct option *merge;
+
+ for (num_old = 0; oldopts[num_old].name; num_old++);
+ for (num_new = 0; oldopts[num_new].name; num_new++);
+
+ global_option_offset += OPTION_OFFSET;
+ *option_offset = global_option_offset;
+
+ merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
+ memcpy(merge, oldopts, num_old * sizeof(struct option));
+ free_opts(0); /* Release previous options merged if any */
+ for (i = 0; i < num_new; i++) {
+ merge[num_old + i] = newopts[i];
+ merge[num_old + i].val += *option_offset;
+ }
+ memset(merge + num_old + num_new, 0, sizeof(struct option));
+
+ return merge;
+}
+
+struct rfidtool_module *find_module(const char *name)
+{
+ return NULL;
+}
+
+void register_module(struct rfidtool_module *me)
+{
+ struct rfidtool_module *old;
+
+ if (strcmp(me->version, program_version) != 0) {
+ fprintf(stderr, "%s: target `%s' v%s (I'm v%s).\n",
+ program_name, me->name, me->version, program_version);
+ exit(1);
+ }
+
+ old = find_module(me->name);
+ if (old) {
+ fprintf(stderr, "%s: target `%s' already registere.\n",
+ program_name, me->name);
+ exit(1);
+ }
+}
+
+static void help(void)
+{
+ printf( " -s --scan scan until first RFID tag is found\n"
+ " -S --scan-loop endless scanning loop\n"
+ " -p --protocol {tcl,mifare-ultralight,mifare-classic}\n"
+ " -l --layer2 {iso14443a,iso14443b,iso15693}\n"
+ " -h --help\n");
+}
+
int main(int argc, char **argv)
{
int rc;
char buf[0x40];
int i, protocol = -1, layer2 = -1;
+
+ program_name = basename(argv[0]);
- printf("librfid_tool - (C) 2006 by Harald Welte\n"
+ printf("%s - (C) 2006 by Harald Welte\n"
"This program is Free Software and has "
- "ABSOLUTELY NO WARRANTY\n\n");
+ "ABSOLUTELY NO WARRANTY\n\n", program_name);
printf("initializing librfid\n");
rfid_init();
while (1) {
int c, option_index = 0;
- c = getopt_long(argc, argv, "hp:l:s", opts, &option_index);
+ c = getopt_long(argc, argv, "hp:l:sS", opts, &option_index);
if (c == -1)
break;
switch (c) {
case 's':
- if (reader() < 0)
+ if (reader_init() < 0)
exit(1);
do_scan();
exit(0);
break;
+ case 'S':
+ if (reader_init() < 0)
+ exit(1);
+ while (1)
+ do_scan();
+ exit(0);
+ break;
case 'p':
protocol = proto_by_name(optarg);
if (protocol < 0) {
@@ -427,13 +433,13 @@ int main(int argc, char **argv)
exit(2);
}
- if (reader() < 0)
+ if (reader_init() < 0)
exit(1);
- if (init(layer2) < 0)
+ if (l2_init(layer2) < 0)
exit(1);
- if (l3(protocol) < 0)
+ if (l3_init(protocol) < 0)
exit(1);
switch (protocol) {
@@ -506,7 +512,9 @@ int main(int argc, char **argv)
printf("Protocol Mifare Classic\n");
{
int sector;
- for (sector = 1; sector < 31; sector++) {
+ for (sector = 0; sector < 31; sector++) {
+ printf("Authenticating sector %u: ", sector);
+ fflush(stdout);
rc = mfcl_set_key(ph, MIFARE_CL_KEYA_DEFAULT_INFINEON);
if (rc < 0) {
printf("key format error\n");
@@ -517,7 +525,7 @@ int main(int argc, char **argv)
printf("mifare auth error\n");
exit(1);
} else
- printf("mifare authe succeeded!\n");
+ printf("mifare auth succeeded!\n");
mifare_classic_read_sector(ph, sector);
}
diff --git a/utils/librfid-tool.h b/utils/librfid-tool.h
new file mode 100644
index 0000000..5ca49d4
--- /dev/null
+++ b/utils/librfid-tool.h
@@ -0,0 +1,35 @@
+#ifndef _RFIDTOOL_H
+#define _RFIDTOOL_H
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+
+extern const char *
+hexdump(const void *data, unsigned int len);
+
+extern int
+hexread(unsigned char *result, const unsigned char *in, unsigned int len);
+
+extern struct rfid_reader_handle *rh;
+extern struct rfid_layer2_handle *l2h;
+extern struct rfid_protocol_handle *ph;
+
+extern int reader_init(void);
+extern int l2_init(int layer2);
+extern int l3_init(int protocol);
+
+#define LIBRFID_TOOL_VERSION "0.1"
+
+struct rfidtool_module {
+ struct rfidtool_module *next;
+ char *name;
+ char *version;
+ const struct option *extra_opts;
+
+ unsigned int option_offset;
+};
+
+#endif /* _REFIDTOOL_H */
diff --git a/utils/mifare-tool.c b/utils/mifare-tool.c
new file mode 100644
index 0000000..f9a6a49
--- /dev/null
+++ b/utils/mifare-tool.c
@@ -0,0 +1,207 @@
+/* mifare-tool - a small command-line tool for librfid mifare testing
+ *
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <libgen.h>
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_scan.h>
+#include <librfid/rfid_reader.h>
+#include <librfid/rfid_layer2.h>
+#include <librfid/rfid_protocol.h>
+
+#include <librfid/rfid_protocol_mifare_classic.h>
+#include <librfid/rfid_protocol_mifare_ul.h>
+
+#include <librfid/rfid_access_mifare_classic.h>
+
+#include "librfid-tool.h"
+
+static char *program_name;
+
+static void help(void)
+{
+}
+
+static struct option mifare_opts[] = {
+ { "key", 1, 0, 'k' },
+ { "read", 1, 0, 'r' },
+ { "loop-read", 1, 0, 'l' },
+ { "write", 1 ,0, 'w' },
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+static int mifare_cl_auth(unsigned char *key, int page)
+{
+ int rc;
+
+ rc = mfcl_set_key(ph, key);
+ if (rc < 0) {
+ fprintf(stderr, "key format error\n");
+ return rc;
+ }
+ rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, page);
+ if (rc < 0) {
+ fprintf(stderr, "mifare auth error\n");
+ return rc;
+ } else
+ printf("mifare auth succeeded!\n");
+
+ return 0;
+}
+
+static void mifare_l3(void)
+{
+ while (l2_init(RFID_LAYER2_ISO14443A) < 0) ;
+
+ printf("ISO14443-3A anticollision succeeded\n");
+
+ while (l3_init(RFID_PROTOCOL_MIFARE_CLASSIC) < 0) ;
+
+ printf("Mifare card available\n");
+}
+
+int main(int argc, char **argv)
+{
+ int len, rc, c, option_index = 0;
+ unsigned int page;
+ char key[MIFARE_CL_KEY_LEN];
+ char buf[MIFARE_CL_PAGE_SIZE];
+ program_name = basename(argv[0]);
+
+ memcpy(key, MIFARE_CL_KEYA_DEFAULT_INFINEON,
+ sizeof(MIFARE_CL_KEYA_DEFAULT_INFINEON));
+
+ printf("%s - (C) 2006 by Harald Welte\n"
+ "This program is Free Software and has "
+ "ABSOLUTELY NO WARRANTY\n\n", program_name);
+
+ printf("initializing librfid\n");
+ rfid_init();
+
+ if (reader_init() < 0) {
+ fprintf(stderr, "error opening reader\n");
+ exit(1);
+ }
+
+ while (1) {
+ c = getopt_long(argc, argv, "k:r:l:w:", mifare_opts,
+ &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'k':
+ hexread(key, optarg, strlen(optarg));
+ printf("key: %s\n", hexdump(key, MIFARE_CL_KEY_LEN));
+ break;
+ case 'r':
+ page = atoi(optarg);
+ printf("read(key='%s',page=%u):",
+ hexdump(key, MIFARE_CL_KEY_LEN), page);
+ len = MIFARE_CL_PAGE_SIZE;
+ mifare_l3();
+ if (mifare_cl_auth(key, page) < 0)
+ exit(1);
+ rc = rfid_protocol_read(ph, page, buf, &len);
+ if (rc < 0) {
+ printf("\n");
+ fprintf(stderr, "error during read\n");
+ break;
+ }
+ printf("%s\n", hexdump(buf, len));
+
+ if (page & 0x3 == 0x3) {
+ struct mfcl_access_sect s;
+ struct mfcl_access_exp_sect es;
+ int b;
+ u_int8_t recreated[4];
+ mfcl_parse_access(&s, buf+6);
+ printf("access b0:%u b1:%u b2:%u b3:%u\n",
+ s.block[0], s.block[1],
+ s.block[2], s.block[3]);
+ mfcl_access_to_exp(&es, &s);
+ for (b = 0; b < 3; b++)
+ printf("%u: %s\n", b, mfcl_access_exp_stringify(&es.block[b]));
+ printf("3: %s\n", mfcl_access_exp_acc_stringify(&es.acc));
+#if 0
+ mfcl_compile_access(recreated, &s);
+ printf("recreated; %s\n", hexdump(recreated,4));
+#endif
+ }
+ break;
+ case 'l':
+ page = atoi(optarg);
+ printf("read_loop(key='%s',page=%u):\n",
+ hexdump(key, MIFARE_CL_KEY_LEN), page);
+ while (1) {
+ mifare_l3();
+ if (mifare_cl_auth(key, page) < 0)
+ continue;
+ rc = rfid_protocol_read(ph, page, buf, &len);
+ if (rc < 0) {
+ printf("\n");
+ fprintf(stderr, "error during read\n");
+ continue;
+ }
+ printf("%s\n", hexdump(buf, len));
+ }
+ break;
+ case 'w':
+ page = atoi(optarg);
+ len = strlen(argv[optind]);
+ len = hexread(buf, argv[optind], len);
+ printf("write(key='%s',page=%u):",
+ hexdump(key, MIFARE_CL_KEY_LEN), page);
+ printf(" '%s'(%u):", hexdump(buf, len), len);
+ mifare_l3();
+ if (mifare_cl_auth(key, page) < 0)
+ exit(1);
+ rc = rfid_protocol_write(ph, page, buf, len);
+ if (rc < 0) {
+ printf("\n");
+ fprintf(stderr, "error during write\n");
+ break;
+ }
+ printf("success\n");
+ break;
+ case 'h':
+ default:
+ help();
+ }
+ }
+
+#if 0
+ rfid_protocol_close(ph);
+ rfid_protocol_fini(ph);
+
+ rfid_layer2_close(l2h);
+ rfid_layer2_fini(l2h);
+#endif
+ rfid_reader_close(rh);
+ exit(0);
+}
+
personal git repositories of Harald Welte. Your mileage may vary