|
@@ -4,9 +4,10 @@
|
4
|
4
|
|
5
|
5
|
#include <iostream>
|
6
|
6
|
#include <sysexits.h>
|
|
7
|
+#include <iomanip>
|
|
8
|
+#include <fstream>
|
7
|
9
|
#include <DBO/StringUtils.h>
|
8
|
10
|
#include <Business/FreeFareDeviceBusiness.h>
|
9
|
|
-#include <iomanip>
|
10
|
11
|
#include "DBO/Result.h"
|
11
|
12
|
#include "Business/LibNfcBusiness.h"
|
12
|
13
|
#include "CommandLineParser.h"
|
|
@@ -18,9 +19,61 @@ MainClass::MainClass(int argc, char *argv[])
|
18
|
19
|
{
|
19
|
20
|
}
|
20
|
21
|
|
|
22
|
+#define Q(x) #x
|
|
23
|
+#define QUOTE(x) Q(x)
|
|
24
|
+
|
|
25
|
+#ifndef GIT_SHA1
|
|
26
|
+#define GIT_SHA1 "unknown"
|
|
27
|
+#endif
|
|
28
|
+
|
|
29
|
+#ifndef GIT_REF_NAME
|
|
30
|
+#define GIT_REF_NAME "unknown"
|
|
31
|
+#endif
|
|
32
|
+
|
21
|
33
|
int MainClass::main()
|
22
|
34
|
{
|
23
|
|
- std::cout << "LibNfc version: " << LibNfcBusiness::getVersion() << std::endl;
|
|
35
|
+ CommandLineParser parser(_argc, _argv);
|
|
36
|
+ CommandLineOption optionVersion(&parser, "version", 'v', "Show libnfc and mifare-tools versions");
|
|
37
|
+ CommandLineOption optionHelp(&parser, "help", 'h', "Show this help");
|
|
38
|
+
|
|
39
|
+ CommandLineOption optionDevice(&parser, "device", 'd', "Use the device DEVICE", "DEVICE");
|
|
40
|
+ CommandLineOption optionUid(&parser, "uid", 'u', "Use the UID tag", "UID");
|
|
41
|
+
|
|
42
|
+ CommandLineOption optionKeyFile(&parser, "key-file", 'f', "Path to a file containing keys", "FILE");
|
|
43
|
+
|
|
44
|
+ if (!parser.parse()) {
|
|
45
|
+ return parser.showHelp(EX_USAGE);
|
|
46
|
+ }
|
|
47
|
+ if (optionVersion.isSet()) {
|
|
48
|
+ printVersion();
|
|
49
|
+ return 0;
|
|
50
|
+ }
|
|
51
|
+ if (optionHelp.isSet()) {
|
|
52
|
+ return parser.showHelp(0, false);
|
|
53
|
+ }
|
|
54
|
+
|
|
55
|
+ std::string deviceName = "";
|
|
56
|
+ if (!optionDevice.isSet()) {
|
|
57
|
+ deviceName = optionDevice.getValue();
|
|
58
|
+ }
|
|
59
|
+
|
|
60
|
+ std::string tagUid = "";
|
|
61
|
+ if (!optionUid.isSet()) {
|
|
62
|
+ tagUid = optionUid.getValue();
|
|
63
|
+ }
|
|
64
|
+
|
|
65
|
+ std::vector<std::string> keys;
|
|
66
|
+ if (optionKeyFile.isSet()) {
|
|
67
|
+ for (auto filePath : optionKeyFile.getValues()) {
|
|
68
|
+ auto keysResult = readFile(filePath);
|
|
69
|
+ if (!keysResult) {
|
|
70
|
+ keysResult.print();
|
|
71
|
+ return 1;
|
|
72
|
+ }
|
|
73
|
+ auto fileKeys = keysResult.getData();
|
|
74
|
+ keys.insert(keys.end(), fileKeys.begin(), fileKeys.end());
|
|
75
|
+ }
|
|
76
|
+ }
|
24
|
77
|
|
25
|
78
|
LibNfcBusiness libNfc;
|
26
|
79
|
auto init = libNfc.init();
|
|
@@ -35,18 +88,11 @@ int MainClass::main()
|
35
|
88
|
return 2;
|
36
|
89
|
}
|
37
|
90
|
auto devices = devicesResult.getData();
|
38
|
|
- if (devices.size() == 0) {
|
39
|
|
- std::cerr << "No NFC device found" << std::endl;
|
|
91
|
+ std::shared_ptr<NfcDeviceBusiness> device = getDevice(deviceName, devices);
|
|
92
|
+ if (device == 0) {
|
|
93
|
+ std::cerr << "NFC device not found" << std::endl;
|
40
|
94
|
return 3;
|
41
|
95
|
}
|
42
|
|
-
|
43
|
|
- std::cout << "Found " << devices.size() << " devices: " << std::endl;
|
44
|
|
- for (size_t i = 0; i < devices.size(); ++i) {
|
45
|
|
- std::cout << devices[i]->getConnStr() << std::endl;
|
46
|
|
- }
|
47
|
|
- std::cout << "Using first device" << std::endl;
|
48
|
|
-
|
49
|
|
- auto device = devices[0];
|
50
|
96
|
auto open = device->open();
|
51
|
97
|
if (!open) {
|
52
|
98
|
open.print();
|
|
@@ -66,20 +112,16 @@ int MainClass::main()
|
66
|
112
|
return 6;
|
67
|
113
|
}
|
68
|
114
|
|
69
|
|
- std::cout << "Found " << tagsResult.getData().size() << " tags:" << std::endl;
|
70
|
|
- for (size_t i = 0; i < tagsResult.getData().size(); ++i) {
|
71
|
|
- auto tag = tagsResult.getData()[i];
|
72
|
|
- std::cout << "UID: " << tag->getUid() << std::endl;
|
73
|
|
- std::cout << "Type: " << tag->getType() << std::endl;
|
|
115
|
+ auto tag = getTag(tagUid, tags);
|
|
116
|
+ if (tag == 0) {
|
|
117
|
+ std::cerr << "Tag not found" << std::endl;
|
|
118
|
+ return 6;
|
74
|
119
|
}
|
75
|
|
- std::cout << "Using first tag" << std::endl;
|
76
|
120
|
|
77
|
|
- auto tag = tags[0];
|
78
|
|
-
|
79
|
|
- std::vector<std::string> keys;
|
|
121
|
+// std::vector<std::string> keys;
|
80
|
122
|
// keys.push_back(StringUtils::humanToRaw("8829da9daf76").getData());
|
81
|
123
|
// keys.push_back(StringUtils::humanToRaw("ffffffffffff").getData());
|
82
|
|
- keys.push_back(StringUtils::humanToRaw("484558414354").getData());
|
|
124
|
+// keys.push_back(StringUtils::humanToRaw("484558414354").getData());
|
83
|
125
|
|
84
|
126
|
int res = dump(tag, keys);
|
85
|
127
|
// int res = mapKeys(tag, keys);
|
|
@@ -169,5 +211,71 @@ void MainClass::printTrailerAccessBits(const AccessBitsDbo &accessBits)
|
169
|
211
|
|
170
|
212
|
void MainClass::printPercent(int done, int total)
|
171
|
213
|
{
|
172
|
|
- std::cout << "\r" << std::fixed << std::setprecision(1) << ((float)done / (float)total * 100.0) << "%" << std::flush;
|
|
214
|
+ std::cout << "\r\033[2K" << std::fixed << std::setprecision(1) << ((float)done / (float)total * 100.0) << "%" << std::flush;
|
|
215
|
+}
|
|
216
|
+
|
|
217
|
+void MainClass::printVersion() const
|
|
218
|
+{
|
|
219
|
+ std::cout << "LibNfc version: " << LibNfcBusiness::getVersion() << std::endl;
|
|
220
|
+ std::cout << "Mifare-tools version: " << QUOTE(GIT_REF_NAME) << "-" << QUOTE(GIT_SHA1) << std::endl;
|
|
221
|
+}
|
|
222
|
+
|
|
223
|
+std::shared_ptr<NfcDeviceBusiness> MainClass::getDevice(const std::string &deviceName, std::vector<std::shared_ptr<NfcDeviceBusiness>> devices)
|
|
224
|
+{
|
|
225
|
+ if (deviceName.empty()) {
|
|
226
|
+ if (devices.size() > 0) {
|
|
227
|
+ return devices[0];
|
|
228
|
+ }
|
|
229
|
+ }
|
|
230
|
+ else {
|
|
231
|
+ for (auto d : devices) {
|
|
232
|
+ if (d->getConnStr() == deviceName) {
|
|
233
|
+ return d;
|
|
234
|
+ }
|
|
235
|
+ }
|
|
236
|
+ }
|
|
237
|
+ return 0;
|
|
238
|
+}
|
|
239
|
+
|
|
240
|
+std::shared_ptr<FreeFareTagBusiness> MainClass::getTag(const std::string &tagUid,
|
|
241
|
+ std::vector<std::shared_ptr<FreeFareTagBusiness>> tags)
|
|
242
|
+{
|
|
243
|
+ if (tagUid.empty()) {
|
|
244
|
+ if (tags.size() > 0) {
|
|
245
|
+ return tags[0];
|
|
246
|
+ }
|
|
247
|
+ }
|
|
248
|
+ else {
|
|
249
|
+ for (auto t : tags) {
|
|
250
|
+ if (t->getUid() == tagUid) {
|
|
251
|
+ return t;
|
|
252
|
+ }
|
|
253
|
+ }
|
|
254
|
+ }
|
|
255
|
+ return 0;
|
|
256
|
+}
|
|
257
|
+
|
|
258
|
+Result<std::vector<std::string>> MainClass::readFile(const std::string &filePath)
|
|
259
|
+{
|
|
260
|
+ std::vector<std::string> lines;
|
|
261
|
+ std::ifstream fileInput(filePath);
|
|
262
|
+ if (fileInput) {
|
|
263
|
+ while (!fileInput.eof()) {
|
|
264
|
+ std::string line;
|
|
265
|
+ std::getline(fileInput, line);
|
|
266
|
+ line = StringUtils::removeSpaces(line);
|
|
267
|
+ if (line.compare(0, 1, "#") != 0 && line.compare(0, 1, "+") != 0) {
|
|
268
|
+ auto keyResult = StringUtils::humanToRaw(line);
|
|
269
|
+ if (!keyResult) {
|
|
270
|
+ return Result<std::vector<std::string>>::error("Invalid file data");
|
|
271
|
+ }
|
|
272
|
+ line = keyResult.getData();
|
|
273
|
+ lines.push_back(line);
|
|
274
|
+ }
|
|
275
|
+ }
|
|
276
|
+ }
|
|
277
|
+ else {
|
|
278
|
+ return Result<std::vector<std::string>>::error("Failed to open file: " + std::string(strerror(errno)));
|
|
279
|
+ }
|
|
280
|
+ return Result<std::vector<std::string>>::ok(lines);
|
173
|
281
|
}
|