diff --git a/IO.cpp b/IO.cpp
index 854dc0c..b6d3b52 100644
--- a/IO.cpp
+++ b/IO.cpp
@@ -23,25 +23,35 @@ along with this program. If not, see .
#include
#include
#include
-#include
+#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
#include "u2f.hpp"
#include "Macro.hpp"
#include "U2FDevice.hpp"
-#include
using namespace std;
-bool bytesAvailable(const size_t count);
+bool bytesAvailable(size_t count);
vector& getBuffer();
+string binaryDirectory{};
+string cacheDirectory{ DEBUG_STREAMS };
+
+// Thanks to https://stackoverflow.com/a/478960
+vector execOutput(const string &cmd);
+void execInput(const string &cmd, const vector &stdinData);
+
vector readNonBlock(const size_t count)
{
if (!bytesAvailable(count))
- {
return vector{};
- }
auto &buffer = getBuffer();
auto buffStart = buffer.begin(), buffEnd = buffer.begin() + count;
@@ -53,33 +63,20 @@ vector readNonBlock(const size_t count)
return bytes;
}
-void write(const uint8_t* bytes, const size_t count)
+void write(const vector &bytes)
{
- size_t totalBytes = 0;
- auto hostDescriptor = *getHostDescriptor();
-
- while (totalBytes < count)
- {
- auto writtenBytes = write(hostDescriptor, bytes + totalBytes, count - totalBytes);
-
- if (writtenBytes > 0)
- totalBytes += writtenBytes;
- else if (errno != 0 && errno != EAGAIN && errno != EWOULDBLOCK) //Expect file blocking behaviour
- ERR();
- }
-
- errno = 0;
+ __android_log_print(ANDROID_LOG_DEBUG, "U2FAndroid", "Writing %zu bytes", bytes.size());
+ execInput("su -c \"" + binaryDirectory + "/U2FAndroid_Write\"", bytes);
}
bool bytesAvailable(const size_t count)
{
auto startTime = std::chrono::high_resolution_clock::now();
- const timespec iterDelay{ 0, 1000 };
+ const timespec iterDelay{ 0, 10000000 };
chrono::duration delay{ 0 };
- while (delay.count() < U2FHID_TRANS_TIMEOUT && contProc)
+ while (delay.count() < U2FHID_TRANS_TIMEOUT)
{
- delay = chrono::high_resolution_clock::now() - startTime;
if (getBuffer().size() >= count) {
#ifdef DEBUG_MSGS
clog << "Requested " << count << " bytes" << endl;
@@ -87,6 +84,7 @@ bool bytesAvailable(const size_t count)
return true;
}
nanosleep(&iterDelay, nullptr);
+ delay = chrono::high_resolution_clock::now() - startTime;
}
#ifdef DEBUG_MSGS
@@ -105,44 +103,45 @@ vector& bufferVar()
vector& getBuffer()
{
auto &buff = bufferVar();
- array bytes{};
- auto hostDescriptor = *getHostDescriptor();
+ vector bytes = execOutput("su -c \"" + binaryDirectory + "/U2FAndroid_Read\"");
- while (true)
+ if (!bytes.empty())
{
- auto readByteCount = read(hostDescriptor, bytes.data(), HID_RPT_SIZE);
-
- if (readByteCount > 0 && readByteCount != HID_RPT_SIZE)
- {
- //Failed to copy an entire packet in, so log this packet
-#ifdef DEBUG_MSGS
- cerr << "Only retrieved " << readByteCount << " bytes from expected full packet." << endl;
-#endif
- }
-
- if (readByteCount > 0)
- {
- copy(bytes.begin(), bytes.begin() + readByteCount, back_inserter(buff));
+ __android_log_print(ANDROID_LOG_DEBUG, "U2FAndroid", "Reading bytes: got %zu", bytes.size());
+ buff.insert(buff.end(), bytes.begin(), bytes.end());
#ifdef DEBUG_STREAMS
- fwrite(bytes.data(), 1, readByteCount, getComHostStream().get());
+ fwrite(bytes.data(), 1, bytes.size(), getComHostStream().get());
#endif
-
- }
- else if (errno != EAGAIN && errno != EWOULDBLOCK) //Expect read would block
- {
- ERR();
-#ifdef DEBUG_MSGS
- cerr << "Unknown stream error: " << errno << endl;
-#endif
- break;
- }
- else
- {
- errno = 0;
- break; //Escape loop if blocking would occur
- }
}
return buff;
}
+
+vector execOutput(const string &cmd)
+{
+ // NOLINT(hicpp-member-init)
+ array buffer;
+ vector result{};
+ unique_ptr pipe{ popen(cmd.c_str(), "rb"), pclose };
+
+ if (!pipe)
+ throw std::runtime_error("popen() failed!");
+ while (size_t readBytes = fread(buffer.data(), 1, buffer.size(), pipe.get()))
+ copy(buffer.begin(), buffer.begin() + readBytes, back_inserter(result));
+
+ return result;
+}
+
+void execInput(const string &cmd, const vector &stdinData)
+{
+ assert(stdinData.size() % HID_RPT_SIZE == 0);
+
+ size_t writtenBytes = 0;
+ unique_ptr pipe{ popen(cmd.c_str(), "wb"), pclose };
+
+ if (!pipe)
+ throw std::runtime_error("popen() failed!");
+ while (writtenBytes < stdinData.size())
+ writtenBytes += fwrite(stdinData.data(), 1, HID_RPT_SIZE, pipe.get());
+}
diff --git a/IO.hpp b/IO.hpp
index 57fadcc..2e25d7c 100644
--- a/IO.hpp
+++ b/IO.hpp
@@ -21,9 +21,12 @@ along with this program. If not, see .
#include
#include
+extern std::string binaryDirectory;
+extern std::string cacheDirectory;
+
//Returns either the number of bytes specified,
//or returns empty vector without discarding bytes from HID stream
std::vector readNonBlock(const size_t count);
//Blocking write to HID stream - shouldn't block for too long
-void write(const uint8_t* bytes, const size_t count);
+void write(const std::vector& data);
diff --git a/Packet.cpp b/Packet.cpp
index 1f0e983..ef412ca 100644
--- a/Packet.cpp
+++ b/Packet.cpp
@@ -243,7 +243,7 @@ void InitPacket::writePacket()
memcpy(this->buf + 5, &bcnth, 1);
memcpy(this->buf + 6, &bcntl, 1);
memcpy(this->buf + 7, data.data(), data.size());
- write(this->buf, sizeof(this->buf));
+ write(vector{ this->buf, this->buf + sizeof(this->buf) });
#ifdef DEBUG_STREAMS
fwrite(this->buf, 1, sizeof(this->buf), devStream);
@@ -288,7 +288,7 @@ void ContPacket::writePacket()
memcpy(this->buf + 4, &seq, 1);
memcpy(this->buf + 5, data.data(), data.size());
- write(this->buf, HID_RPT_SIZE);
+ write(vector{this->buf, this->buf + HID_RPT_SIZE });
#ifdef DEBUG_STREAMS
fwrite(this->buf, HID_RPT_SIZE, 1, devStream);
diff --git a/Streams.cpp b/Streams.cpp
index 4f51ec3..35afadd 100644
--- a/Streams.cpp
+++ b/Streams.cpp
@@ -17,6 +17,7 @@ along with this program. If not, see .
*/
#include "Streams.hpp"
+#include "IO.hpp"
#include
#include
#include
@@ -49,7 +50,7 @@ shared_ptr getHostDescriptor()
#ifdef DEBUG_STREAMS
shared_ptr getComHostStream()
{
- static shared_ptr stream{ fopen(DEBUG_STREAMS "comhost.txt", "wb"), [](FILE *f){
+ static shared_ptr stream{ fopen((cacheDirectory + "comhost.txt").c_str(), "wb"), [](FILE *f){
clog << "Closing comhost stream" << endl;
fclose(f);
} };
@@ -62,7 +63,7 @@ shared_ptr getComHostStream()
shared_ptr getHostPacketStream()
{
- static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostpackets.html", "wb"), "Host Packets"), [](FILE *f){
+ static shared_ptr stream{ initHTML(fopen((cacheDirectory + "hostpackets.html").c_str(), "wb"), "Host Packets"), [](FILE *f){
clog << "Closing hostPackets stream" << endl;
closeHTML(f);
} };
@@ -75,7 +76,7 @@ shared_ptr getHostPacketStream()
shared_ptr getHostAPDUStream()
{
- static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "hostAPDU.html", "wb"), "Host APDU"), [](FILE *f){
+ static shared_ptr stream{ initHTML(fopen((cacheDirectory + "hostAPDU.html").c_str(), "wb"), "Host APDU"), [](FILE *f){
clog << "Closing host APDU stream" << endl;
closeHTML(f);
} };
@@ -88,7 +89,7 @@ shared_ptr getHostAPDUStream()
shared_ptr getComDevStream()
{
- static shared_ptr stream{ fopen(DEBUG_STREAMS "comdev.txt", "wb"), [](FILE *f){
+ static shared_ptr stream{ fopen((cacheDirectory + "comdev.txt").c_str(), "wb"), [](FILE *f){
clog << "Closing comdev stream" << endl;
fclose(f);
} };
@@ -101,7 +102,7 @@ shared_ptr getComDevStream()
shared_ptr getDevPacketStream()
{
- static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devpackets.html", "wb"), "Dev Packets"), [](FILE *f){
+ static shared_ptr stream{ initHTML(fopen((cacheDirectory + "devpackets.html").c_str(), "wb"), "Dev Packets"), [](FILE *f){
clog << "Closing devPackets stream" << endl;
closeHTML(f);
} };
@@ -114,7 +115,7 @@ shared_ptr getDevPacketStream()
shared_ptr getDevAPDUStream()
{
- static shared_ptr stream{ initHTML(fopen(DEBUG_STREAMS "devAPDU.html", "wb"), "Dev APDU"), [](FILE *f){
+ static shared_ptr stream{ initHTML(fopen((cacheDirectory + "devAPDU.html").c_str(), "wb"), "Dev APDU"), [](FILE *f){
clog << "Closing dev APDU stream" << endl;
closeHTML(f);
} };
diff --git a/U2FDevice.cpp b/U2FDevice.cpp
index fb34cd2..a8ecf8d 100644
--- a/U2FDevice.cpp
+++ b/U2FDevice.cpp
@@ -21,7 +21,7 @@ along with this program. If not, see .
#include "Storage.hpp"
#include "Controller.hpp"
#include "LED.hpp"
-#include
+#include
#include
using namespace std;
@@ -40,9 +40,6 @@ bool initialiseLights(const string& prog) {
{
cerr << e.what() << endl;
- if (getuid() != 0)
- cerr << "Try running as root, using \'sudo " << prog << "\'" << endl;
-
return false;
}
@@ -65,9 +62,6 @@ int handleTransactions(const string& prog, const string& privKeyDir)
{
cerr << e.what() << endl;
- if (getuid() != 0)
- cerr << "Try running as root, using \'sudo " << prog << "\'" << endl;
-
raise(SIGINT);
return EXIT_FAILURE;
}
@@ -88,9 +82,6 @@ bool deinitialiseLights(const string& prog) {
{
cerr << e.what() << endl;
- if (getuid() != 0)
- cerr << "Try running as root, using \'sudo " << prog << "\'" << endl;
-
return false;
}