/* Copyright 2018 bigbiff/Dees_Troy TeamWin This file is part of TWRP/TeamWin Recovery Project. TWRP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. TWRP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TWRP. If not, see . */ /* The keystore refuses to allow the root user to supply auth tokens, so * we write the auth token to a file in TWRP and run a separate service * (this) that runs as the system user to add the auth token. TWRP waits * for /auth_token to be deleted and also looks for /auth_error to check * for errors. TWRP will error out after a while if /auth_token does not * get deleted. */ #include #include #include #include #include #include #include #define LOG_TAG "keystore_auth" using namespace android; void create_error_file() { FILE* error_file = fopen("/auth_error", "wb"); if (error_file == NULL) { printf("Failed to open /auth_error\n"); ALOGE("Failed to open /auth_error\n"); return; } fwrite("1", 1, 1, error_file); fclose(error_file); unlink("/auth_token"); } int main(int argc, char *argv[]) { unlink("/auth_error"); FILE* auth_file = fopen("/auth_token", "rb"); if (auth_file == NULL) { printf("Failed to open /auth_token\n"); ALOGE("Failed to open /auth_token\n"); create_error_file(); return -1; } // Get the file size fseek(auth_file, 0, SEEK_END); int size = ftell(auth_file); fseek(auth_file, 0, SEEK_SET); uint8_t auth_token[size]; fread(auth_token , sizeof(uint8_t), size, auth_file); fclose(auth_file); // First get the keystore service sp sm = defaultServiceManager(); sp binder = sm->getService(String16("android.security.keystore")); sp service = interface_cast(binder); if (service == NULL) { printf("error: could not connect to keystore service\n"); ALOGE("error: could not connect to keystore service\n"); create_error_file(); return -2; } ::keystore::KeyStoreServiceReturnCode auth_result = service->addAuthToken(auth_token, size); if (!auth_result.isOk()) { // The keystore checks the uid of the calling process and will return a permission denied on this operation for user 0 printf("keystore error adding auth token\n"); ALOGE("keystore error adding auth token\n"); create_error_file(); return -3; } printf("successfully added auth token to keystore\n"); ALOGD("successfully added auth token to keystore\n"); unlink("/auth_token"); return 0; }