|
@@ -13,6 +13,13 @@
|
13
|
13
|
#include "CommandLineParser.h"
|
14
|
14
|
#include "MainClass.h"
|
15
|
15
|
|
|
16
|
+#define EX_KEY_ERROR 1
|
|
17
|
+#define EX_LIB_NFC_ERROR 2
|
|
18
|
+#define EX_NFC_DEVICE_NOT_FOUND 3
|
|
19
|
+#define EX_NFC_TAG_NOT_FOUND 4
|
|
20
|
+#define EX_MAP_KEYS_ERROR 5
|
|
21
|
+#define EX_DUMP_ERROR 6
|
|
22
|
+
|
16
|
23
|
MainClass::MainClass(int argc, char *argv[])
|
17
|
24
|
: _argc(argc)
|
18
|
25
|
, _argv(argv)
|
|
@@ -25,30 +32,36 @@ int MainClass::main()
|
25
|
32
|
CommandLineOption optionVersion(&parser, "version", 'v', "Show libnfc and mifare-tools versions");
|
26
|
33
|
CommandLineOption optionHelp(&parser, "help", 'h', "Show this help");
|
27
|
34
|
|
28
|
|
- CommandLineOption optionDevice(&parser, "device", 'd', "Use the device DEVICE", "DEVICE");
|
29
|
|
- CommandLineOption optionUid(&parser, "uid", 'u', "Use the UID tag", "UID");
|
|
35
|
+ CommandLineOption optionMap(&parser, "map", 'm', "Map keys for the tag");
|
|
36
|
+ CommandLineOption optionDump(&parser, "dump", 'd', "Dump the tag");
|
|
37
|
+ CommandLineOption optionDevices(&parser, "devices", 'l', "List NFC devices");
|
|
38
|
+ CommandLineOption optionTags(&parser, "tags", 't', "List NFC tags");
|
|
39
|
+
|
|
40
|
+ CommandLineOption optionDevice(&parser, "device", 'e', "Use the device DEVICE", "DEVICE");
|
|
41
|
+ CommandLineOption optionTag(&parser, "tag", 'u', "Use the UID tag", "UID");
|
30
|
42
|
|
31
|
43
|
CommandLineOption optionKeyFile(&parser, "key-file", 'f', "Path to a file containing keys", "FILE");
|
|
44
|
+ CommandLineOption optionKey(&parser, "key", 'k', "Key to use to authenticate", "KEY");
|
32
|
45
|
|
33
|
46
|
if (!parser.parse()) {
|
34
|
47
|
return parser.showHelp(EX_USAGE);
|
35
|
48
|
}
|
36
|
49
|
if (optionVersion.isSet()) {
|
37
|
50
|
printVersion();
|
38
|
|
- return 0;
|
|
51
|
+ return EX_OK;
|
39
|
52
|
}
|
40
|
53
|
if (optionHelp.isSet()) {
|
41
|
|
- return parser.showHelp(0, false);
|
|
54
|
+ return parser.showHelp(EX_OK, false);
|
42
|
55
|
}
|
43
|
56
|
|
44
|
57
|
std::string deviceName = "";
|
45
|
|
- if (!optionDevice.isSet()) {
|
|
58
|
+ if (optionDevice.isSet()) {
|
46
|
59
|
deviceName = optionDevice.getValue();
|
47
|
60
|
}
|
48
|
61
|
|
49
|
62
|
std::string tagUid = "";
|
50
|
|
- if (!optionUid.isSet()) {
|
51
|
|
- tagUid = optionUid.getValue();
|
|
63
|
+ if (optionTag.isSet()) {
|
|
64
|
+ tagUid = optionTag.getValue();
|
52
|
65
|
}
|
53
|
66
|
|
54
|
67
|
std::vector<std::string> keys;
|
|
@@ -57,65 +70,107 @@ int MainClass::main()
|
57
|
70
|
auto keysResult = readFile(filePath);
|
58
|
71
|
if (!keysResult) {
|
59
|
72
|
keysResult.print();
|
60
|
|
- return 1;
|
|
73
|
+ return EX_KEY_ERROR;
|
61
|
74
|
}
|
62
|
75
|
auto fileKeys = keysResult.getData();
|
63
|
76
|
keys.insert(keys.end(), fileKeys.begin(), fileKeys.end());
|
64
|
77
|
}
|
65
|
78
|
}
|
|
79
|
+ if (optionKey.isSet()) {
|
|
80
|
+ for (auto key : optionKey.getValues()) {
|
|
81
|
+ auto keyResult = StringUtils::humanToRaw(key);
|
|
82
|
+ key = keyResult.getData();
|
|
83
|
+ if (!keyResult || key.length() != 6) {
|
|
84
|
+ std::cerr << "Invalid key" << std::endl;
|
|
85
|
+ return EX_KEY_ERROR;
|
|
86
|
+ }
|
|
87
|
+ keys.push_back(key);
|
|
88
|
+ }
|
|
89
|
+ }
|
66
|
90
|
|
|
91
|
+ int res = EX_OK;
|
67
|
92
|
LibNfcBusiness libNfc;
|
68
|
93
|
auto init = libNfc.init();
|
69
|
94
|
if (!init) {
|
70
|
95
|
init.print();
|
71
|
|
- return 1;
|
72
|
|
- }
|
73
|
|
-
|
74
|
|
- auto devicesResult = libNfc.getDevices();
|
75
|
|
- if (!devicesResult) {
|
76
|
|
- devicesResult.print();
|
77
|
|
- return 2;
|
78
|
|
- }
|
79
|
|
- auto devices = devicesResult.getData();
|
80
|
|
- std::shared_ptr<NfcDeviceBusiness> device = getDevice(deviceName, devices);
|
81
|
|
- if (device == 0) {
|
82
|
|
- std::cerr << "NFC device not found" << std::endl;
|
83
|
|
- return 3;
|
84
|
|
- }
|
85
|
|
- auto open = device->open();
|
86
|
|
- if (!open) {
|
87
|
|
- open.print();
|
88
|
|
- return 4;
|
89
|
|
- }
|
90
|
|
-
|
91
|
|
- FreeFareDeviceBusiness freeFareDevice(device);
|
92
|
|
- auto tagsResult = freeFareDevice.getTags();
|
93
|
|
- if (!tagsResult) {
|
94
|
|
- tagsResult.print();
|
95
|
|
- return 5;
|
96
|
|
- }
|
97
|
|
-
|
98
|
|
- auto tags = tagsResult.getData();
|
99
|
|
- if (tags.size() == 0) {
|
100
|
|
- std::cerr << "No tag found" << std::endl;
|
101
|
|
- return 6;
|
|
96
|
+ res = EX_LIB_NFC_ERROR;
|
102
|
97
|
}
|
103
|
|
-
|
104
|
|
- auto tag = getTag(tagUid, tags);
|
105
|
|
- if (tag == 0) {
|
106
|
|
- std::cerr << "Tag not found" << std::endl;
|
107
|
|
- return 6;
|
|
98
|
+ else
|
|
99
|
+ {
|
|
100
|
+ auto devicesResult = libNfc.getDevices();
|
|
101
|
+ if (!devicesResult)
|
|
102
|
+ {
|
|
103
|
+ devicesResult.print();
|
|
104
|
+ res = EX_LIB_NFC_ERROR;
|
|
105
|
+ }
|
|
106
|
+ else
|
|
107
|
+ {
|
|
108
|
+ auto devices = devicesResult.getData();
|
|
109
|
+
|
|
110
|
+ if (optionDevices.isSet())
|
|
111
|
+ {
|
|
112
|
+ for (auto device : devices) {
|
|
113
|
+ std::cout << device->getConnStr() << std::endl;
|
|
114
|
+ }
|
|
115
|
+ }
|
|
116
|
+ else
|
|
117
|
+ {
|
|
118
|
+ auto device = getDevice(deviceName, devices);
|
|
119
|
+ if (device == 0)
|
|
120
|
+ {
|
|
121
|
+ std::cerr << "NFC device not found" << std::endl;
|
|
122
|
+ res = EX_NFC_DEVICE_NOT_FOUND;
|
|
123
|
+ }
|
|
124
|
+ else {
|
|
125
|
+ auto open = device->open();
|
|
126
|
+ if (!open) {
|
|
127
|
+ open.print();
|
|
128
|
+ res = EX_LIB_NFC_ERROR;
|
|
129
|
+ }
|
|
130
|
+ else {
|
|
131
|
+
|
|
132
|
+ FreeFareDeviceBusiness freeFareDevice(device);
|
|
133
|
+ auto tagsResult = freeFareDevice.getTags();
|
|
134
|
+ if (!tagsResult)
|
|
135
|
+ {
|
|
136
|
+ tagsResult.print();
|
|
137
|
+ res = EX_LIB_NFC_ERROR;
|
|
138
|
+ }
|
|
139
|
+
|
|
140
|
+ auto tags = tagsResult.getData();
|
|
141
|
+
|
|
142
|
+ if (optionTags.isSet()) {
|
|
143
|
+ for (auto tag : tags)
|
|
144
|
+ {
|
|
145
|
+ std::cout << "UID=" << tag->getUid() << " \tType=" << tag->getType() << std::endl;
|
|
146
|
+ }
|
|
147
|
+ }
|
|
148
|
+ else {
|
|
149
|
+ auto tag = getTag(tagUid, tags);
|
|
150
|
+ if (tag == 0) {
|
|
151
|
+ std::cerr << "Tag not found" << std::endl;
|
|
152
|
+ res = EX_NFC_TAG_NOT_FOUND;
|
|
153
|
+ }
|
|
154
|
+ else {
|
|
155
|
+ if (optionDump.isSet()) {
|
|
156
|
+ res = dump(tag, keys);
|
|
157
|
+ }
|
|
158
|
+ else if (optionMap.isSet()) {
|
|
159
|
+ res = mapKeys(tag, keys);
|
|
160
|
+ }
|
|
161
|
+ else {
|
|
162
|
+ std::cerr << "Must select an action (dump|map|devices|tags)" << std::endl;
|
|
163
|
+ res = EX_USAGE;
|
|
164
|
+ }
|
|
165
|
+ }
|
|
166
|
+ }
|
|
167
|
+ }
|
|
168
|
+ }
|
|
169
|
+ device->close();
|
|
170
|
+ }
|
|
171
|
+ }
|
108
|
172
|
}
|
109
|
173
|
|
110
|
|
-// std::vector<std::string> keys;
|
111
|
|
-// keys.push_back(StringUtils::humanToRaw("8829da9daf76").getData());
|
112
|
|
-// keys.push_back(StringUtils::humanToRaw("ffffffffffff").getData());
|
113
|
|
- keys.push_back(StringUtils::humanToRaw("484558414354").getData());
|
114
|
|
-
|
115
|
|
- int res = dump(tag, keys);
|
116
|
|
-// int res = mapKeys(tag, keys);
|
117
|
|
-
|
118
|
|
- device->close();
|
119
|
174
|
libNfc.clean();
|
120
|
175
|
|
121
|
176
|
return res;
|
|
@@ -129,6 +184,7 @@ int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std
|
129
|
184
|
}
|
130
|
185
|
if (!mappedKeysResult) {
|
131
|
186
|
mappedKeysResult.print();
|
|
187
|
+ return EX_MAP_KEYS_ERROR;
|
132
|
188
|
}
|
133
|
189
|
else {
|
134
|
190
|
auto mappedKeys = mappedKeysResult.getData();
|
|
@@ -137,12 +193,12 @@ int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std
|
137
|
193
|
std::cout << "+Sector: " << s << std::endl;
|
138
|
194
|
for (int b = 0; b < 4; ++b) {
|
139
|
195
|
std::cout << "+Block: " << b << std::endl;
|
140
|
|
- std::cout << "Key A: " << StringUtils::rawToHuman(sectorKey.first) << std::endl;
|
141
|
|
- std::cout << "Key B: " << StringUtils::rawToHuman(sectorKey.second) << std::endl;
|
|
196
|
+ std::cout << "Key A: " << (!sectorKey.first.empty() ? StringUtils::rawToHuman(sectorKey.first) : std::string(12, '-')) << std::endl;
|
|
197
|
+ std::cout << "Key B: " << (!sectorKey.second.empty() ? StringUtils::rawToHuman(sectorKey.second) : std::string(12, '-')) << std::endl;
|
142
|
198
|
}
|
143
|
199
|
}
|
144
|
200
|
}
|
145
|
|
- return 0;
|
|
201
|
+ return EX_OK;
|
146
|
202
|
}
|
147
|
203
|
|
148
|
204
|
int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys)
|
|
@@ -153,7 +209,7 @@ int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::s
|
153
|
209
|
}
|
154
|
210
|
if (!dumpResult) {
|
155
|
211
|
dumpResult.print();
|
156
|
|
- return 7;
|
|
212
|
+ return EX_DUMP_ERROR;
|
157
|
213
|
}
|
158
|
214
|
auto dump = dumpResult.getData();
|
159
|
215
|
for(int s = 0; s < 16; ++s) {
|
|
@@ -178,7 +234,7 @@ int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::s
|
178
|
234
|
std::cout << "+Block: 4 ";
|
179
|
235
|
printTrailerAccessBits(accessBitsDbo);
|
180
|
236
|
}
|
181
|
|
- return 0;
|
|
237
|
+ return EX_OK;
|
182
|
238
|
}
|
183
|
239
|
|
184
|
240
|
void MainClass::printBlockAccessBits(const AccessBitsDbo &accessBits, int block)
|