diff options
Diffstat (limited to 'adbbu/twrpback.cpp')
-rw-r--r-- | adbbu/twrpback.cpp | 424 |
1 files changed, 239 insertions, 185 deletions
diff --git a/adbbu/twrpback.cpp b/adbbu/twrpback.cpp index 2c7ea6966..d88a9c9da 100644 --- a/adbbu/twrpback.cpp +++ b/adbbu/twrpback.cpp @@ -36,6 +36,7 @@ #include "twadbstream.h" #include "twrpback.hpp" +#include "libtwadbbu.hpp" #include "../twrpDigest/twrpDigest.hpp" #include "../twrpDigest/twrpMD5.hpp" #include "../twrpAdbBuFifo.hpp" @@ -124,13 +125,13 @@ void twrpback::close_restore_fds() { unlink(TW_ADB_RESTORE); } -int twrpback::backup(std::string command) { +bool twrpback::backup(std::string command) { twrpMD5 digest; bool breakloop = false; int bytes = 0, errctr = 0; - char result[MAX_ADB_READ]; - uint64_t totalbytes = 0, dataChunkBytes = 0; - int64_t count = -1; // Count of how many blocks set + char adbReadStream[MAX_ADB_READ]; + uint64_t totalbytes = 0, dataChunkBytes = 0, fileBytes = 0; + int64_t count = false; // Count of how many blocks set uint64_t md5fnsize = 0; struct AdbBackupControlType endadb; @@ -143,12 +144,12 @@ int twrpback::backup(std::string command) { adbd_fp = fdopen(adbd_fd, "w"); if (adbd_fp == NULL) { adblogwrite("Unable to open adb_fp\n"); - return -1; + return false; } if (mkfifo(TW_ADB_BACKUP, 0666) < 0) { adblogwrite("Unable to create TW_ADB_BACKUP fifo\n"); - return -1; + return false; } adblogwrite("opening TW_ADB_FIFO\n"); @@ -160,7 +161,7 @@ int twrpback::backup(std::string command) { if (errctr > ADB_BU_MAX_ERROR) { adblogwrite("Unable to open TW_ADB_FIFO\n"); close_backup_fds(); - return -1; + return false; } } @@ -168,15 +169,15 @@ int twrpback::backup(std::string command) { if (snprintf(operation, sizeof(operation), "adbbackup %s", command.c_str()) >= sizeof(operation)) { adblogwrite("Operation too big to write to ORS_INPUT_FILE\n"); close_backup_fds(); - return -1; + return false; } if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) { adblogwrite("Unable to write to ORS_INPUT_FILE\n"); close_backup_fds(); - return -1; + return false; } - memset(&result, 0, sizeof(result)); + memset(&adbReadStream, 0, sizeof(adbReadStream)); memset(&cmd, 0, sizeof(cmd)); adblogwrite("opening TW_ADB_BU_CONTROL\n"); @@ -184,7 +185,7 @@ int twrpback::backup(std::string command) { if (adb_control_bu_fd < 0) { adblogwrite("Unable to open TW_ADB_BU_CONTROL for reading.\n"); close_backup_fds(); - return -1; + return false; } adblogwrite("opening TW_ADB_BACKUP\n"); @@ -192,7 +193,7 @@ int twrpback::backup(std::string command) { if (adb_read_fd < 0) { adblogwrite("Unable to open TW_ADB_BACKUP for reading.\n"); close_backup_fds(); - return -1; + return false; } //loop until TWENDADB sent @@ -208,7 +209,7 @@ int twrpback::backup(std::string command) { writedata = false; adblogwrite("Error received. Quitting...\n"); close_backup_fds(); - return -1; + return false; } //we received the end of adb backup stream so we should break the loop else if (cmdtype == TWENDADB) { @@ -223,13 +224,13 @@ int twrpback::backup(std::string command) { //we recieved the TWSTREAMHDR structure metadata to write to adb else if (cmdtype == TWSTREAMHDR) { writedata = false; - adblogwrite("Writing TWSTREAMHDR\n"); + adblogwrite("writing TWSTREAMHDR\n"); if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { std::stringstream str; str << strerror(errno); adblogwrite("Error writing TWSTREAMHDR to adbd" + str.str() + "\n"); close_backup_fds(); - return -1; + return false; } fflush(adbd_fp); } @@ -237,16 +238,17 @@ int twrpback::backup(std::string command) { else if (cmdtype == TWIMG) { struct twfilehdr twimghdr; - adblogwrite("Writing TWIMG\n"); + adblogwrite("writing TWIMG\n"); digest.init(); memset(&twimghdr, 0, sizeof(twimghdr)); memcpy(&twimghdr, cmd, sizeof(cmd)); md5fnsize = twimghdr.size; + compressed = false; - if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { + if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { adblogwrite("Error writing TWIMG to adbd\n"); close_backup_fds(); - return -1; + return false; } fflush(adbd_fp); writedata = true; @@ -255,7 +257,7 @@ int twrpback::backup(std::string command) { else if (cmdtype == TWFN) { struct twfilehdr twfilehdr; - adblogwrite("Writing TWFN\n"); + adblogwrite("writing TWFN\n"); digest.init(); ADBSTRUCT_STATIC_ASSERT(sizeof(twfilehdr) == MAX_ADB_READ); @@ -269,7 +271,7 @@ int twrpback::backup(std::string command) { if (fwrite(cmd, 1, sizeof(cmd), adbd_fp) != sizeof(cmd)) { adblogwrite("Error writing TWFN to adbd\n"); close_backup_fds(); - return -1; + return false; } fflush(adbd_fp); writedata = true; @@ -284,36 +286,43 @@ int twrpback::backup(std::string command) { */ else if (cmdtype == TWEOF) { adblogwrite("received TWEOF\n"); - count = totalbytes / MAX_ADB_READ + 1; - count = count * MAX_ADB_READ; - - while ((bytes = read(adb_read_fd, &result, sizeof(result))) > 0) { + while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream)) != 0)) { totalbytes += bytes; - char *writeresult = new char [bytes]; - memcpy(writeresult, result, bytes); - digest.update((unsigned char *) writeresult, bytes); - if (fwrite(writeresult, 1, bytes, adbd_fp) != bytes) { - adblogwrite("Error writing backup data to adbd\n"); - close_backup_fds(); - return -1; + fileBytes += bytes; + dataChunkBytes += bytes; + + char *writeAdbReadStream = new char [bytes]; + memcpy(writeAdbReadStream, adbReadStream, bytes); + + digest.update((unsigned char *) writeAdbReadStream, bytes); + if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) { + std::stringstream str; + str << strerror(errno); + adblogwrite("Cannot write to adbd stream: " + str.str() + "\n"); } fflush(adbd_fp); - delete [] writeresult; - memset(&result, 0, sizeof(result)); + delete [] writeAdbReadStream; + memset(adbReadStream, 0, sizeof(adbReadStream)); } - if ((totalbytes % MAX_ADB_READ) != 0) { - adblogwrite("writing padding to stream\n"); - char padding[count - totalbytes]; - memset(padding, 0, sizeof(padding)); - if (fwrite(padding, 1, sizeof(padding), adbd_fp) != sizeof(padding)) { + count = fileBytes / DATA_MAX_CHUNK_SIZE + 1; + count = count * DATA_MAX_CHUNK_SIZE; + + if (fileBytes % DATA_MAX_CHUNK_SIZE != 0) { + char padding[count - fileBytes]; + int paddingBytes = sizeof(padding); + std::stringstream paddingStr; + paddingStr << paddingBytes; + memset(padding, 0, paddingBytes); + adblogwrite("writing padding to stream: " + paddingStr.str() + " bytes\n"); + if (fwrite(padding, 1, paddingBytes, adbd_fp) != sizeof(padding)) { adblogwrite("Error writing padding to adbd\n"); close_backup_fds(); - return -1; + return false; } - digest.update((unsigned char *) padding, sizeof(padding)); + totalbytes += paddingBytes; + digest.update((unsigned char *) padding, paddingBytes); fflush(adbd_fp); - totalbytes = 0; } AdbBackupFileTrailer md5trailer; @@ -336,11 +345,12 @@ int twrpback::backup(std::string command) { if (fwrite(&md5trailer, 1, sizeof(md5trailer), adbd_fp) != sizeof(md5trailer)) { adblogwrite("Error writing md5trailer to adbd\n"); close_backup_fds(); - return -1; + return false; } fflush(adbd_fp); writedata = false; firstDataPacket = true; + fileBytes = 0; } memset(&cmd, 0, sizeof(cmd)); } @@ -349,59 +359,76 @@ int twrpback::backup(std::string command) { //to the adb stream. //If the stream is compressed, we need to always write the data. if (writedata || compressed) { - while ((bytes = read(adb_read_fd, &result, sizeof(result))) > 0) { + while ((bytes = read(adb_read_fd, &adbReadStream, sizeof(adbReadStream))) > 0) { if (firstDataPacket) { - struct AdbBackupControlType data_block; - - memset(&data_block, 0, sizeof(data_block)); - strncpy(data_block.start_of_header, TWRP, sizeof(data_block.start_of_header)); - strncpy(data_block.type, TWDATA, sizeof(data_block.type)); - data_block.crc = crc32(0L, Z_NULL, 0); - data_block.crc = crc32(data_block.crc, (const unsigned char*) &data_block, sizeof(data_block)); - if (fwrite(&data_block, 1, sizeof(data_block), adbd_fp) != sizeof(data_block)) { - adblogwrite("Error writing data_block to adbd\n"); + if (!twadbbu::Write_TWDATA(adbd_fp)) { close_backup_fds(); - return -1; + return false; } fflush(adbd_fp); firstDataPacket = false; + dataChunkBytes += sizeof(adbReadStream); } - char *writeresult = new char [bytes]; - memcpy(writeresult, result, bytes); + char *writeAdbReadStream = new char [bytes]; + memcpy(writeAdbReadStream, adbReadStream, bytes); - digest.update((unsigned char *) writeresult, bytes); + digest.update((unsigned char *) writeAdbReadStream, bytes); totalbytes += bytes; + fileBytes += bytes; dataChunkBytes += bytes; - if (fwrite(writeresult, 1, bytes, adbd_fp) != bytes) { + if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) != bytes) { adblogwrite("Error writing backup data to adbd\n"); close_backup_fds(); - return -1; + return false; } fflush(adbd_fp); + delete [] writeAdbReadStream; - delete [] writeresult; - memset(&result, 0, sizeof(result)); - if (dataChunkBytes == DATA_MAX_CHUNK_SIZE - sizeof(result)) { - struct AdbBackupControlType data_block; - - memset(&data_block, 0, sizeof(data_block)); - strncpy(data_block.start_of_header, TWRP, sizeof(data_block.start_of_header)); - strncpy(data_block.type, TWDATA, sizeof(data_block.type)); - data_block.crc = crc32(0L, Z_NULL, 0); - data_block.crc = crc32(data_block.crc, (const unsigned char*) &data_block, sizeof(data_block)); - if (fwrite(&data_block, 1, sizeof(data_block), adbd_fp) != sizeof(data_block)) { - adblogwrite("Error writing data_block to adbd\n"); - close_backup_fds(); - return -1; + memset(&adbReadStream, 0, sizeof(adbReadStream)); + + if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) { + dataChunkBytes = 0; + firstDataPacket = true; + } + else if (dataChunkBytes > (DATA_MAX_CHUNK_SIZE - sizeof(adbReadStream))) { + int bytesLeft = DATA_MAX_CHUNK_SIZE - dataChunkBytes; + char extraData[bytesLeft]; + + memset(&extraData, 0, bytesLeft); + while ((bytes = read(adb_read_fd, &extraData, bytesLeft)) != 0) { + if (bytes > 0) { + totalbytes += bytes; + fileBytes += bytes; + dataChunkBytes += bytes; + + bytesLeft -= bytes; + char *writeAdbReadStream = new char [bytes]; + memcpy(writeAdbReadStream, extraData, bytes); + + digest.update((unsigned char *) writeAdbReadStream, bytes); + if (fwrite(writeAdbReadStream, 1, bytes, adbd_fp) < 0) { + std::stringstream str; + str << strerror(errno); + adblogwrite("Cannot write to adbd stream: " + str.str() + "\n"); + close_restore_fds(); + return false; + } + fflush(adbd_fp); + delete [] writeAdbReadStream; + } + memset(&extraData, 0, bytesLeft); + if (bytesLeft == 0) { + break; + } } + fflush(adbd_fp); dataChunkBytes = 0; + firstDataPacket = true; } - } - compressed = false; } } @@ -409,23 +436,25 @@ int twrpback::backup(std::string command) { if (fwrite(&endadb, 1, sizeof(endadb), adbd_fp) != sizeof(endadb)) { adblogwrite("Error writing endadb to adbd\n"); close_backup_fds(); - return -1; + return false; } fflush(adbd_fp); close_backup_fds(); return 0; } -int twrpback::restore(void) { +bool twrpback::restore(void) { twrpMD5 digest; char cmd[MAX_ADB_READ]; - char result[MAX_ADB_READ]; + char readAdbStream[MAX_ADB_READ]; struct AdbBackupControlType structcmd; - int adb_control_twrp_fd, errctr = 0; + int errctr = 0; uint64_t totalbytes = 0, dataChunkBytes = 0; uint64_t md5fnsize = 0; bool writedata, read_from_adb; bool breakloop, eofsent, md5trsent; + bool compressed; + bool md5TrailerReceived = false; breakloop = false; read_from_adb = true; @@ -436,13 +465,13 @@ int twrpback::restore(void) { if (adbd_fp == NULL) { adblogwrite("Unable to open adb_fp\n"); close_restore_fds(); - return -1; + return false; } if(mkfifo(TW_ADB_RESTORE, 0666)) { adblogwrite("Unable to create TW_ADB_RESTORE fifo\n"); close_restore_fds(); - return -1; + return false; } adblogwrite("opening TW_ADB_FIFO\n"); @@ -454,7 +483,7 @@ int twrpback::restore(void) { if (errctr > ADB_BU_MAX_ERROR) { adblogwrite("Unable to open TW_ADB_FIFO\n"); close_restore_fds(); - return -1; + return false; } } @@ -463,10 +492,10 @@ int twrpback::restore(void) { if (write(write_fd, operation, sizeof(operation)) != sizeof(operation)) { adblogwrite("Unable to write to TW_ADB_FIFO\n"); close_restore_fds(); - return -1; + return false; } - memset(&result, 0, sizeof(result)); + memset(&readAdbStream, 0, sizeof(readAdbStream)); memset(&cmd, 0, sizeof(cmd)); adblogwrite("opening TW_ADB_BU_CONTROL\n"); @@ -476,7 +505,7 @@ int twrpback::restore(void) { str << strerror(errno); adblogwrite("Unable to open TW_ADB_BU_CONTROL for writing. " + str.str() + "\n"); close_restore_fds(); - return -1; + return false; } adblogwrite("opening TW_ADB_TWRP_CONTROL\n"); @@ -492,7 +521,7 @@ int twrpback::restore(void) { if (errctr > ADB_BU_MAX_ERROR) { adblogwrite("Unable to open TW_ADB_TWRP_CONTROL\n"); close_backup_fds(); - return -1; + return false; } } } @@ -511,7 +540,7 @@ int twrpback::restore(void) { struct AdbBackupControlType tweof; memset(&tweof, 0, sizeof(tweof)); - memcpy(&tweof, result, sizeof(result)); + memcpy(&tweof, readAdbStream, sizeof(readAdbStream)); read_from_adb = true; } //Break when TWRP sends TWENDADB @@ -524,15 +553,14 @@ int twrpback::restore(void) { else if (cmdtype == TWERROR) { adblogwrite("Error received. Quitting...\n"); close_restore_fds(); - return -1; + return false; } } //If we should read from the adb stream, write commands and data to TWRP if (read_from_adb) { int readbytes; - if ((readbytes = fread(result, 1, sizeof(result), adbd_fp)) == sizeof(result)) { - totalbytes += readbytes; - memcpy(&structcmd, result, sizeof(result)); + if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) == sizeof(readAdbStream)) { + memcpy(&structcmd, readAdbStream, sizeof(readAdbStream)); std::string cmdtype = structcmd.get_type(); //Tell TWRP we have read the entire adb stream @@ -540,9 +568,8 @@ int twrpback::restore(void) { struct AdbBackupControlType endadb; uint32_t crc, endadbcrc; - totalbytes -= sizeof(result); memset(&endadb, 0, sizeof(endadb)); - memcpy(&endadb, result, sizeof(result)); + memcpy(&endadb, readAdbStream, sizeof(readAdbStream)); endadbcrc = endadb.crc; memset(&endadb.crc, 0, sizeof(endadb.crc)); crc = crc32(0L, Z_NULL, 0); @@ -555,14 +582,14 @@ int twrpback::restore(void) { str << strerror(errno); adblogwrite("Cannot write to ADB_CONTROL_READ_FD: " + str.str() + "\n"); close_restore_fds(); - return -1; + return false; } read_from_adb = false; } else { adblogwrite("ADB TWENDADB crc header doesn't match\n"); close_restore_fds(); - return -1; + return false; } } //Send TWRP partition metadata @@ -571,10 +598,9 @@ int twrpback::restore(void) { uint32_t crc, cnthdrcrc; ADBSTRUCT_STATIC_ASSERT(sizeof(cnthdr) == MAX_ADB_READ); - totalbytes -= sizeof(result); memset(&cnthdr, 0, sizeof(cnthdr)); - memcpy(&cnthdr, result, sizeof(result)); + memcpy(&cnthdr, readAdbStream, sizeof(readAdbStream)); cnthdrcrc = cnthdr.crc; memset(&cnthdr.crc, 0, sizeof(cnthdr.crc)); crc = crc32(0L, Z_NULL, 0); @@ -582,18 +608,18 @@ int twrpback::restore(void) { if (crc == cnthdrcrc) { adblogwrite("Restoring TWSTREAMHDR\n"); - if (write(adb_control_twrp_fd, result, sizeof(result)) < 0) { + if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 0) { std::stringstream str; str << strerror(errno); adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); close_restore_fds(); - return -1; + return false; } } else { adblogwrite("ADB TWSTREAMHDR crc header doesn't match\n"); close_restore_fds(); - return -1; + return false; } } //Tell TWRP we are sending a partition image @@ -602,10 +628,9 @@ int twrpback::restore(void) { uint32_t crc, twimghdrcrc; digest.init(); - totalbytes -= sizeof(result); adblogwrite("Restoring TWIMG\n"); memset(&twimghdr, 0, sizeof(twimghdr)); - memcpy(&twimghdr, result, sizeof(result)); + memcpy(&twimghdr, readAdbStream, sizeof(readAdbStream)); md5fnsize = twimghdr.size; twimghdrcrc = twimghdr.crc; memset(&twimghdr.crc, 0, sizeof(twimghdr.crc)); @@ -613,18 +638,18 @@ int twrpback::restore(void) { crc = crc32(0L, Z_NULL, 0); crc = crc32(crc, (const unsigned char*) &twimghdr, sizeof(twimghdr)); if (crc == twimghdrcrc) { - if (write(adb_control_twrp_fd, result, sizeof(result)) < 1) { + if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) { std::stringstream str; str << strerror(errno); adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); close_restore_fds(); - return -1; + return false; } } else { adblogwrite("ADB TWIMG crc header doesn't match\n"); close_restore_fds(); - return -1; + return false; } adblogwrite("opening TW_ADB_RESTORE\n"); adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY); @@ -633,12 +658,11 @@ int twrpback::restore(void) { else if (cmdtype == TWFN) { struct twfilehdr twfilehdr; uint32_t crc, twfilehdrcrc; - digest.init(); - totalbytes -= sizeof(result); + digest.init(); adblogwrite("Restoring TWFN\n"); memset(&twfilehdr, 0, sizeof(twfilehdr)); - memcpy(&twfilehdr, result, sizeof(result)); + memcpy(&twfilehdr, readAdbStream, sizeof(readAdbStream)); md5fnsize = twfilehdr.size; twfilehdrcrc = twfilehdr.crc; memset(&twfilehdr.crc, 0, sizeof(twfilehdr.crc)); @@ -647,111 +671,82 @@ int twrpback::restore(void) { crc = crc32(crc, (const unsigned char*) &twfilehdr, sizeof(twfilehdr)); if (crc == twfilehdrcrc) { - if (write(adb_control_twrp_fd, result, sizeof(result)) < 1) { + if (write(adb_control_twrp_fd, readAdbStream, sizeof(readAdbStream)) < 1) { std::stringstream str; str << strerror(errno); adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); close_restore_fds(); - return -1; + return false; } } else { adblogwrite("ADB TWFN crc header doesn't match\n"); close_restore_fds(); - return -1; + return false; } adblogwrite("opening TW_ADB_RESTORE\n"); adb_write_fd = open(TW_ADB_RESTORE, O_WRONLY); } + else if (cmdtype == MD5TRAILER) { + read_from_adb = false; //don't read from adb until TWRP sends TWEOF + close(adb_write_fd); + md5TrailerReceived = true; + if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) { + close_restore_fds(); + return false; + } + } //Send the tar or partition image md5 to TWRP else if (cmdtype == TWDATA) { - totalbytes -= sizeof(result); + dataChunkBytes += sizeof(readAdbStream); while (1) { - if ((readbytes = fread(result, 1, sizeof(result), adbd_fp)) != sizeof(result)) { + if ((readbytes = fread(readAdbStream, 1, sizeof(readAdbStream), adbd_fp)) != sizeof(readAdbStream)) { close_restore_fds(); - return -1; + return false; } - totalbytes += readbytes; - memcpy(&structcmd, result, sizeof(result)); - std::string cmdtype = structcmd.get_type(); - if (cmdtype.substr(0, sizeof(MD5TRAILER) - 1) == MD5TRAILER) { - struct AdbBackupFileTrailer md5tr; - uint32_t crc, md5trcrc, md5ident, md5identmatch; - - ADBSTRUCT_STATIC_ASSERT(sizeof(md5tr) == MAX_ADB_READ); - memset(&md5tr, 0, sizeof(md5tr)); - memcpy(&md5tr, result, sizeof(result)); - md5ident = md5tr.ident; - - memset(&md5tr.ident, 0, sizeof(md5tr.ident)); - - md5identmatch = crc32(0L, Z_NULL, 0); - md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5tr, sizeof(md5tr)); - md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5fnsize, sizeof(md5fnsize)); - - if (md5identmatch == md5ident) { - totalbytes -= sizeof(result); - close(adb_write_fd); - adblogwrite("Restoring MD5TRAILER\n"); - md5trcrc = md5tr.crc; - memset(&md5tr.crc, 0, sizeof(md5tr.crc)); - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, (const unsigned char*) &md5tr, sizeof(md5tr)); - if (crc == md5trcrc) { - if (write(adb_control_twrp_fd, result, sizeof(result)) < 1) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); - close_restore_fds(); - return -1; - } - } - else { - adblogwrite("ADB MD5TRAILER crc header doesn't match\n"); - close_restore_fds(); - return -1; - } - - AdbBackupFileTrailer md5; - - memset(&md5, 0, sizeof(md5)); - strncpy(md5.start_of_trailer, TWRP, sizeof(md5.start_of_trailer)); - strncpy(md5.type, TWMD5, sizeof(md5.type)); - std::string md5string = digest.return_digest_string(); - strncpy(md5.md5, md5string.c_str(), sizeof(md5.md5)); - - adblogwrite("Sending MD5Check\n"); - if (write(adb_control_twrp_fd, &md5, sizeof(md5)) < 1) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); - close_restore_fds(); - return -1; - } - read_from_adb = false; //don't read from adb until TWRP sends TWEOF - break; + memcpy(&structcmd, readAdbStream, sizeof(readAdbStream)); + + char *readAdbReadStream = new char [readbytes]; + memcpy(readAdbReadStream, readAdbStream, readbytes); + std::string cmdtype = structcmd.get_type(); + dataChunkBytes += readbytes; + delete [] readAdbReadStream; + totalbytes += readbytes; + digest.update((unsigned char*)readAdbReadStream, readbytes); + + if (cmdtype == MD5TRAILER) { + read_from_adb = false; //don't read from adb until TWRP sends TWEOF + close(adb_write_fd); + if (!checkMD5Trailer(readAdbStream, md5fnsize, &digest)) { + close_restore_fds(); + return false; } + break; } - digest.update((unsigned char*)result, sizeof(result)); - dataChunkBytes += readbytes; - if (write(adb_write_fd, result, sizeof(result)) < 0) { - std::stringstream str; - str << strerror(errno); - adblogwrite("Cannot write to adb_write_fd\n" + str.str() + ". Retrying.\n"); - while(write(adb_write_fd, result, sizeof(result)) < 0) { - adblogwrite("Cannot write to adb_write_fd\n" + str.str() + ". Retrying.\n"); - continue; - } + + if (write(adb_write_fd, readAdbStream, sizeof(readAdbStream)) < 0) { + adblogwrite("end of stream reached.\n"); + break; } - if (dataChunkBytes == ((DATA_MAX_CHUNK_SIZE) - sizeof(result))) { + if (dataChunkBytes == DATA_MAX_CHUNK_SIZE) { dataChunkBytes = 0; break; } - memset(&result, 0, sizeof(result)); + memset(&readAdbStream, 0, sizeof(readAdbStream)); + } + } + else { + if (!md5TrailerReceived) { + char *readAdbReadStream = new char [readbytes]; + memcpy(readAdbReadStream, readAdbStream, readbytes); + digest.update((unsigned char*)readAdbReadStream, readbytes); + totalbytes += readbytes; + delete [] readAdbReadStream; } + } } } @@ -760,7 +755,7 @@ int twrpback::restore(void) { std::stringstream str; str << totalbytes; adblogwrite(str.str() + " bytes restored from adbbackup\n"); - return 0; + return true; } void twrpback::streamFileForTWRP(void) { @@ -785,3 +780,62 @@ void twrpback::threadStream(void) { pthread_create(&thread, NULL, p, this); pthread_join(thread, NULL); } + +bool twrpback::checkMD5Trailer(char readAdbStream[], uint64_t md5fnsize, twrpMD5 *digest) { + struct AdbBackupFileTrailer md5tr; + uint32_t crc, md5trcrc, md5ident, md5identmatch; + + ADBSTRUCT_STATIC_ASSERT(sizeof(md5tr) == MAX_ADB_READ); + memset(&md5tr, 0, sizeof(md5tr)); + memcpy(&md5tr, readAdbStream, MAX_ADB_READ); + md5ident = md5tr.ident; + + memset(&md5tr.ident, 0, sizeof(md5tr.ident)); + + md5identmatch = crc32(0L, Z_NULL, 0); + md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5tr, sizeof(md5tr)); + md5identmatch = crc32(md5identmatch, (const unsigned char*) &md5fnsize, sizeof(md5fnsize)); + + if (md5identmatch == md5ident) { + adblogwrite("checking MD5TRAILER\n"); + md5trcrc = md5tr.crc; + memset(&md5tr.crc, 0, sizeof(md5tr.crc)); + crc = crc32(0L, Z_NULL, 0); + crc = crc32(crc, (const unsigned char*) &md5tr, sizeof(md5tr)); + if (crc == md5trcrc) { + if (write(adb_control_twrp_fd, &md5tr, sizeof(md5tr)) < 1) { + std::stringstream str; + str << strerror(errno); + adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); + close_restore_fds(); + return false; + } + } + else { + adblogwrite("ADB MD5TRAILER crc header doesn't match\n"); + close_restore_fds(); + return false; + } + + AdbBackupFileTrailer md5; + + memset(&md5, 0, sizeof(md5)); + strncpy(md5.start_of_trailer, TWRP, sizeof(md5.start_of_trailer)); + strncpy(md5.type, TWMD5, sizeof(md5.type)); + std::string md5string = digest->return_digest_string(); + strncpy(md5.md5, md5string.c_str(), sizeof(md5.md5)); + + adblogwrite("sending MD5 verification\n"); + std::stringstream dstr; + dstr << adb_control_twrp_fd; + if (write(adb_control_twrp_fd, &md5, sizeof(md5)) < 1) { + std::stringstream str; + str << strerror(errno); + adblogwrite("Cannot write to adb_control_twrp_fd: " + str.str() + "\n"); + close_restore_fds(); + return false; + } + return true; + } + return false; +} |