|
@@ -44,24 +44,25 @@ int MainClass::main()
|
44
|
44
|
CommandLineOption optionKeyFile(&parser, "key-file", 'f', "Path to a file containing keys", "FILE");
|
45
|
45
|
CommandLineOption optionKey(&parser, "key", 'k', "Key to use to authenticate", "KEY");
|
46
|
46
|
|
47
|
|
- CommandLineOption optionOutput(&parser, "output", 'o', "Redirect output to FILE. '-' to use stdout", "FILE");
|
|
47
|
+ CommandLineOption optionOutput(&parser, "output", 'o', "Redirect output to FILE. '-' to use stdout", "FILE", "-");
|
48
|
48
|
|
49
|
49
|
if (!parser.parse()) {
|
50
|
50
|
return parser.showHelp(EX_USAGE);
|
51
|
51
|
}
|
52
|
|
- std::string outputFile = "-";
|
|
52
|
+ std::string outputFile = optionOutput.getDefaultValue();
|
53
|
53
|
if (optionOutput.isSet()) {
|
54
|
54
|
outputFile = optionOutput.getValue();
|
55
|
55
|
}
|
56
|
|
- std::streambuf* oldCoutStreamBuf = std::cout.rdbuf();
|
57
|
|
- std::ofstream fileCout;
|
|
56
|
+
|
|
57
|
+ std::shared_ptr<std::ofstream> fileCout = 0;
|
58
|
58
|
if (outputFile != "-" && !outputFile.empty()) {
|
59
|
|
- fileCout.open(outputFile);
|
60
|
|
- if (!fileCout) {
|
|
59
|
+ fileCout = std::make_shared<std::ofstream>();
|
|
60
|
+ fileCout->open(outputFile);
|
|
61
|
+ if (!*fileCout) {
|
61
|
62
|
std::cerr << "Failed to redirect output: " << strerror(errno) << std::endl;
|
62
|
63
|
return EX_REDIRECT_ERROR;
|
63
|
64
|
}
|
64
|
|
- std::cout.rdbuf(fileCout.rdbuf());
|
|
65
|
+ _outputStream = fileCout;
|
65
|
66
|
}
|
66
|
67
|
|
67
|
68
|
if (optionVersion.isSet()) {
|
|
@@ -72,12 +73,12 @@ int MainClass::main()
|
72
|
73
|
return parser.showHelp(EX_OK, false);
|
73
|
74
|
}
|
74
|
75
|
|
75
|
|
- std::string deviceName = "";
|
|
76
|
+ std::string deviceName = optionDevice.getDefaultValue();
|
76
|
77
|
if (optionDevice.isSet()) {
|
77
|
78
|
deviceName = optionDevice.getValue();
|
78
|
79
|
}
|
79
|
80
|
|
80
|
|
- std::string tagUid = "";
|
|
81
|
+ std::string tagUid = optionTag.getDefaultValue();
|
81
|
82
|
if (optionTag.isSet()) {
|
82
|
83
|
tagUid = optionTag.getValue();
|
83
|
84
|
}
|
|
@@ -128,7 +129,7 @@ int MainClass::main()
|
128
|
129
|
if (optionDevices.isSet())
|
129
|
130
|
{
|
130
|
131
|
for (auto device : devices) {
|
131
|
|
- std::cout << device->getConnStr() << std::endl;
|
|
132
|
+ cout() << device->getConnStr() << std::endl;
|
132
|
133
|
}
|
133
|
134
|
}
|
134
|
135
|
else
|
|
@@ -160,7 +161,7 @@ int MainClass::main()
|
160
|
161
|
if (optionTags.isSet()) {
|
161
|
162
|
for (auto tag : tags)
|
162
|
163
|
{
|
163
|
|
- std::cout << "UID=" << tag->getUid() << " \tType=" << tag->getType() << std::endl;
|
|
164
|
+ cout() << "UID=" << tag->getUid() << " \tType=" << tag->getType() << std::endl;
|
164
|
165
|
}
|
165
|
166
|
}
|
166
|
167
|
else {
|
|
@@ -187,22 +188,15 @@ int MainClass::main()
|
187
|
188
|
}
|
188
|
189
|
}
|
189
|
190
|
}
|
|
191
|
+ libNfc.clean();
|
190
|
192
|
}
|
191
|
193
|
|
192
|
|
- libNfc.clean();
|
193
|
|
- std::cout.rdbuf(oldCoutStreamBuf);
|
194
|
|
- if (fileCout) {
|
195
|
|
- fileCout.close();
|
196
|
|
- }
|
197
|
194
|
return res;
|
198
|
195
|
}
|
199
|
196
|
|
200
|
197
|
int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys)
|
201
|
198
|
{
|
202
|
199
|
auto mappedKeysResult = tag->mapKeys(keys, printPercentMapKeys);
|
203
|
|
- if (isatty(1)) {
|
204
|
|
- std::cout << "\r";
|
205
|
|
- }
|
206
|
200
|
if (!mappedKeysResult) {
|
207
|
201
|
mappedKeysResult.print();
|
208
|
202
|
return EX_MAP_KEYS_ERROR;
|
|
@@ -211,11 +205,11 @@ int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std
|
211
|
205
|
auto mappedKeys = mappedKeysResult.getData();
|
212
|
206
|
for (int s = 0; s < mappedKeys.size(); ++s) {
|
213
|
207
|
auto sectorKey = mappedKeys[s];
|
214
|
|
- std::cout << "+Sector: " << s << std::endl;
|
|
208
|
+ cout() << "+Sector: " << s << std::endl;
|
215
|
209
|
for (int b = 0; b < 4; ++b) {
|
216
|
|
- std::cout << "+Block: " << b << std::endl;
|
217
|
|
- std::cout << "Key A: " << (!sectorKey.first.empty() ? StringUtils::rawToHuman(sectorKey.first) : std::string(12, '-')) << std::endl;
|
218
|
|
- std::cout << "Key B: " << (!sectorKey.second.empty() ? StringUtils::rawToHuman(sectorKey.second) : std::string(12, '-')) << std::endl;
|
|
210
|
+ cout() << "+Block: " << b << std::endl;
|
|
211
|
+ cout() << "+Key: A" << std::endl << (!sectorKey.first.empty() ? StringUtils::rawToHuman(sectorKey.first) : std::string(12, '-')) << std::endl;
|
|
212
|
+ cout() << "+Key: B" << std::endl << (!sectorKey.second.empty() ? StringUtils::rawToHuman(sectorKey.second) : std::string(12, '-')) << std::endl;
|
219
|
213
|
}
|
220
|
214
|
}
|
221
|
215
|
}
|
|
@@ -225,34 +219,31 @@ int MainClass::mapKeys(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std
|
225
|
219
|
int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::string> keys)
|
226
|
220
|
{
|
227
|
221
|
auto dumpResult = tag->dump(keys, printPercentMapKeys, printPercentDump);
|
228
|
|
- if (isatty(1)) {
|
229
|
|
- std::cout << "\r";
|
230
|
|
- }
|
231
|
222
|
if (!dumpResult) {
|
232
|
223
|
dumpResult.print();
|
233
|
224
|
return EX_DUMP_ERROR;
|
234
|
225
|
}
|
235
|
226
|
auto dump = dumpResult.getData();
|
236
|
227
|
for(int s = 0; s < 16; ++s) {
|
237
|
|
- std::cout << "+Sector: " << s << std::endl;
|
|
228
|
+ cout() << "+Sector: " << s << std::endl;
|
238
|
229
|
auto sector = dump[s];
|
239
|
230
|
for (int b = 0; b < 3; ++b) {
|
240
|
|
- std::cout << (sector.hasBlock(b) ? StringUtils::rawToHuman(sector.getBlock(b)) : std::string(32, '-')) << std::endl;
|
|
231
|
+ cout() << (sector.hasBlock(b) ? StringUtils::rawToHuman(sector.getBlock(b)) : std::string(32, '-')) << std::endl;
|
241
|
232
|
}
|
242
|
|
- std::cout << "" << (sector.hasKeyA() ? StringUtils::rawToHuman(sector.getKeyA()) : std::string(12, '-'))
|
|
233
|
+ cout() << (sector.hasKeyA() ? StringUtils::rawToHuman(sector.getKeyA()) : std::string(12, '-'))
|
243
|
234
|
<< (sector.hasAccessBits() ? StringUtils::rawToHuman(sector.getAccessBits()) : std::string(8, '-'))
|
244
|
235
|
<< (sector.hasKeyB() ? StringUtils::rawToHuman(sector.getKeyB()) : std::string(12, '-')) << std::endl;
|
245
|
236
|
|
246
|
237
|
|
247
|
|
- std::cout << "+Trailer key A: " << (sector.hasKeyA() ? StringUtils::rawToHuman(sector.getKeyA()) : std::string(12, '-'))
|
|
238
|
+ cout() << "+Trailer key A: " << (sector.hasKeyA() ? StringUtils::rawToHuman(sector.getKeyA()) : std::string(12, '-'))
|
248
|
239
|
<< "\t AC bits: " << (sector.hasAccessBits() ? StringUtils::rawToHuman(sector.getAccessBits()) : std::string(8, '-'))
|
249
|
240
|
<< "\t key B: " << (sector.hasKeyB() ? StringUtils::rawToHuman(sector.getKeyB()) : std::string(12, '-')) << std::endl;
|
250
|
241
|
AccessBitsDbo accessBitsDbo = sector.getAccessBitsDbo();
|
251
|
242
|
for (int b = 0; b < 3; ++b) {
|
252
|
|
- std::cout << "+Block: " << b << " ";
|
|
243
|
+ cout() << "+Block: " << b << " ";
|
253
|
244
|
printBlockAccessBits(accessBitsDbo, b);
|
254
|
245
|
}
|
255
|
|
- std::cout << "+Block: 4 ";
|
|
246
|
+ cout() << "+Block: 3 ";
|
256
|
247
|
printTrailerAccessBits(accessBitsDbo);
|
257
|
248
|
}
|
258
|
249
|
return EX_OK;
|
|
@@ -260,31 +251,33 @@ int MainClass::dump(std::shared_ptr<FreeFareTagBusiness> tag, std::vector<std::s
|
260
|
251
|
|
261
|
252
|
void MainClass::printBlockAccessBits(const AccessBitsDbo &accessBits, int block)
|
262
|
253
|
{
|
263
|
|
- std::cout << "read: " << (accessBits.canKeyAReadBlock(block) ? "A" : " ") << (accessBits.canKeyBReadBlock(block) ? "B" : " ");
|
264
|
|
- std::cout << "\t write: " << (accessBits.canKeyAWriteBlock(block) ? "A" : " ") << (accessBits.canKeyBWriteBlock(block) ? "B" : " ");
|
265
|
|
- std::cout << "\t increment: " << (accessBits.canKeyAIncrementBlock(block) ? "A" : " ") << (accessBits.canKeyBIncrementBlock(block) ? "B" : " ");
|
266
|
|
- std::cout << "\t decrement: " << (accessBits.canKeyADecrementBlock(block) ? "A" : " ") << (accessBits.canKeyBDecrementBlock(block) ? "B" : " ") << std::endl;
|
|
254
|
+ cout() << "read: " << (accessBits.canKeyAReadBlock(block) ? "A" : " ") << (accessBits.canKeyBReadBlock(block) ? "B" : " ");
|
|
255
|
+ cout() << "\t write: " << (accessBits.canKeyAWriteBlock(block) ? "A" : " ") << (accessBits.canKeyBWriteBlock(block) ? "B" : " ");
|
|
256
|
+ cout() << "\t increment: " << (accessBits.canKeyAIncrementBlock(block) ? "A" : " ") << (accessBits.canKeyBIncrementBlock(block) ? "B" : " ");
|
|
257
|
+ cout() << "\t decrement: " << (accessBits.canKeyADecrementBlock(block) ? "A" : " ") << (accessBits.canKeyBDecrementBlock(block) ? "B" : " ") << std::endl;
|
267
|
258
|
}
|
268
|
259
|
|
269
|
260
|
void MainClass::printTrailerAccessBits(const AccessBitsDbo &accessBits)
|
270
|
261
|
{
|
271
|
|
- std::cout << "key A read: " << (accessBits.canKeyAReadKeyATrailer() ? "A" : " ") << (accessBits.canKeyBReadKeyATrailer() ? "B" : " ");
|
272
|
|
- std::cout << "\t key A write: " << (accessBits.canKeyAWriteKeyATrailer() ? "A" : " ") << (accessBits.canKeyBWriteKeyATrailer() ? "B" : " ");
|
|
262
|
+ cout() << "key A read: " << (accessBits.canKeyAReadKeyATrailer() ? "A" : " ") << (accessBits.canKeyBReadKeyATrailer() ? "B" : " ");
|
|
263
|
+ cout() << "\t key A write: " << (accessBits.canKeyAWriteKeyATrailer() ? "A" : " ") << (accessBits.canKeyBWriteKeyATrailer() ? "B" : " ");
|
273
|
264
|
|
274
|
|
- std::cout << "\t AC bits read: " << (accessBits.canKeyAReadAccessBitsTrailer() ? "A" : " ") << (accessBits.canKeyBReadAccessBitsTrailer() ? "B" : " ");
|
275
|
|
- std::cout << "\t AC bits write: " << (accessBits.canKeyAWriteAccessBitsTrailer() ? "A" : " ") << (accessBits.canKeyBWriteAccessBitsTrailer() ? "B" : " ");
|
|
265
|
+ cout() << "\t AC bits read: " << (accessBits.canKeyAReadAccessBitsTrailer() ? "A" : " ") << (accessBits.canKeyBReadAccessBitsTrailer() ? "B" : " ");
|
|
266
|
+ cout() << "\t AC bits write: " << (accessBits.canKeyAWriteAccessBitsTrailer() ? "A" : " ") << (accessBits.canKeyBWriteAccessBitsTrailer() ? "B" : " ");
|
276
|
267
|
|
277
|
|
- std::cout << "\t key B read: " << (accessBits.canKeyAReadKeyBTrailer() ? "A" : " ") << (accessBits.canKeyBReadKeyBTrailer() ? "B" : " ");
|
278
|
|
- std::cout << "\t key B write: " << (accessBits.canKeyAWriteKeyBTrailer() ? "A" : " ") << (accessBits.canKeyBWriteKeyBTrailer() ? "B" : " ") << std::endl;;
|
|
268
|
+ cout() << "\t key B read: " << (accessBits.canKeyAReadKeyBTrailer() ? "A" : " ") << (accessBits.canKeyBReadKeyBTrailer() ? "B" : " ");
|
|
269
|
+ cout() << "\t key B write: " << (accessBits.canKeyAWriteKeyBTrailer() ? "A" : " ") << (accessBits.canKeyBWriteKeyBTrailer() ? "B" : " ") << std::endl;;
|
279
|
270
|
}
|
280
|
271
|
|
281
|
272
|
void MainClass::printPercent(int done, int total, const std::string& header)
|
282
|
273
|
{
|
283
|
|
- if (isatty(1)) {
|
|
274
|
+ if (isatty(fileno(stdout))) {
|
284
|
275
|
std::cout << "\r\033[2K" << header << ": " << std::fixed << std::setprecision(1)
|
285
|
276
|
<< ((float) done / (float) total * 100.0) << "%" << std::flush;
|
|
277
|
+ if (done == total) {
|
|
278
|
+ std::cout << std::endl;
|
|
279
|
+ }
|
286
|
280
|
}
|
287
|
|
-
|
288
|
281
|
}
|
289
|
282
|
|
290
|
283
|
void MainClass::printPercentMapKeys(int done, int total)
|
|
@@ -297,10 +290,10 @@ void MainClass::printPercentDump(int done, int total)
|
297
|
290
|
printPercent(done, total, "Dumping");
|
298
|
291
|
}
|
299
|
292
|
|
300
|
|
-void MainClass::printVersion() const
|
|
293
|
+void MainClass::printVersion()
|
301
|
294
|
{
|
302
|
|
- std::cout << "LibNfc version: " << LibNfcBusiness::getLibNfcVersion() << std::endl;
|
303
|
|
- std::cout << "Mifare-tools version: " << LibNfcBusiness::getMifareToolsVersion() << std::endl;
|
|
295
|
+ cout() << "LibNfc version: " << LibNfcBusiness::getLibNfcVersion() << std::endl;
|
|
296
|
+ cout() << "Mifare-tools version: " << LibNfcBusiness::getMifareToolsVersion() << std::endl;
|
304
|
297
|
}
|
305
|
298
|
|
306
|
299
|
std::shared_ptr<NfcDeviceBusiness> MainClass::getDevice(const std::string &deviceName, std::vector<std::shared_ptr<NfcDeviceBusiness>> devices)
|
|
@@ -362,3 +355,8 @@ Result<std::vector<std::string>> MainClass::readFile(const std::string &filePath
|
362
|
355
|
}
|
363
|
356
|
return Result<std::vector<std::string>>::ok(lines);
|
364
|
357
|
}
|
|
358
|
+
|
|
359
|
+std::ostream &MainClass::cout()
|
|
360
|
+{
|
|
361
|
+ return _outputStream == 0 ? std::cout : *_outputStream;
|
|
362
|
+}
|