int send_alive_request() { if (login_md5_a.empty()) return -1; if (auth_info.empty()) return -1; U31_LOG_INFO("Send Alive Request." << std::endl); std::vector<uint8_t> pkt_data; pkt_data.push_back(0xFF); // Code pkt_data.insert(pkt_data.end(), login_md5_a.begin(), login_md5_a.end()); pkt_data.insert(pkt_data.end(), 3, 0x00); // Fill 0x00 *3 pkt_data.insert(pkt_data.end(), auth_info.begin(), auth_info.end()); pkt_data.insert(pkt_data.end(), 2, 0x00); // Fill 0x00 *2 for timestamp uint16_t now_time = (uint16_t)(time(NULL) % 86400); U31_LOG_SEND_DUMP auto handler_success = [&](std::vector<uint8_t> recv) -> int { U31_LOG_RECV_DUMP("Send Alive Request"); if (recv[0] != 0x07 && recv[5] != 0x00) // Response for Alive return -1; U31_LOG_INFO("Gateway return: Response for alive." << std::endl); // Captured memcpy(&online_time, &recv[32], 4); memcpy(&total_time, &recv[44], 4); memcpy(&total_flux, &recv[48], 4); memcpy(&balance, &recv[52], 4); #ifdef OPENWRT // network order on openwrt online_time = TO_LITTLE_ENDIAN(online_time); total_time = TO_LITTLE_ENDIAN(total_time); total_flux = TO_LITTLE_ENDIAN(total_flux); balance = TO_LITTLE_ENDIAN(balance); #endif U31_LOG_INFO("Keep Alive succeeded! Timestamp = " << now_time << ", user info:" << std::endl); U31_LOG_INFO("Online Time: " << online_time << " Seconds, Used Time: " << total_time << " Minutes, Used Flux: " << (total_flux & 0x0FFFFFFFF) / 1024.0 << " MB, Balance: " << (balance & 0x0FFFFFFFF) / 10000.0 << " RMB" << std::endl); return 0; }; U31_HANDLE_ERROR("Send Alive Request"); U31_AUTO_RETRY("Send Alive Request"); }
void SHA3_End(SHA3Context *ctx, unsigned char *digest, unsigned int *digestLen, unsigned int maxDigestLen) { if (maxDigestLen < ctx->d) { // TODO how to fail more gracefully? PORT_SetError? return; } // Write domain tag to ctx->todo buffer // This is safe because ctx->todoLen is always less than ctx->r. // Otherwise, we would have processed the block in SHA3_Update. ctx->todo[ctx->todoLength] = ctx->domain; // pad10*1 => Write a 1 after the domain, and at the end ctx->todo[ctx->todoLength] |= (1 << ctx->domainLength); ctx->todo[ctx->r - 1] |= 0x80; // Apply permutation add_block(ctx, ctx->todo); // Return Trunc_d(Z), in the proper byte order // TODO support further squeezing for SHAKE TO_LITTLE_ENDIAN(ctx); memcpy(digest, (uint8_t*) ctx->A, ctx->d); FROM_LITTLE_ENDIAN(ctx); *digestLen = ctx->d; }
// The input buffer is expected to have at least ctx->r bytes. void add_block(SHA3Context *ctx, const unsigned char *input) { // XOR and apply permutation TO_LITTLE_ENDIAN(ctx); uint8_t *state = (uint8_t*) ctx->A; for (int i=0; i<ctx->r; ++i) { state[i] ^= input[i]; } FROM_LITTLE_ENDIAN(ctx); for (int ir=0; ir<24; ++ir) { rnd(ctx, ir); } }
int send_login_auth() { if (challenge.empty()) return -1; U31_LOG_INFO("Send Login Auth." << std::endl); U31_LOG_DBG("username = "******", password = "******"Send Login Auth"); if (recv[0] != 0x04 && recv[0] != 0x05) // Success/Failure return -1; if (recv[0] == 0x05) // Failure { switch (recv[4]) { case 0x01: // Already online U31_LOG_ERR("This account has already been online at IP: " << (int)recv[5] << "." << (int)recv[6] << "." << (int)recv[7] << "." << (int)recv[8] << ", MAC: " << hextostr(&recv[9], 6, ':') << std::endl); break; case 0x03: // Username or password wrong! U31_LOG_ERR("Username or password wrong!" << std::endl); break; case 0x05: // No money U31_LOG_ERR("No money in your account!" << std::endl); break; case 0x0b: // Wrong MAC U31_LOG_ERR("Wrong MAC, should be " << hextostr(&recv[5], 6, ':') << std::endl); break; default: U31_LOG_ERR("Unkown failure: 0x" << std::hex << (int)recv[4] << std::endl); break; } return 1; // Don't retry when failure } U31_LOG_INFO("Gateway return: Success." << std::endl); // Success auth_info.insert(auth_info.end(), recv.begin() + 23, recv.begin() + 23 + 16); // 16 bytes from Success // Captured memcpy(&total_time, &recv[5], 4); memcpy(&total_flux, &recv[9], 4); memcpy(&balance, &recv[13], 4); #ifdef OPENWRT // network order on openwrt total_time = TO_LITTLE_ENDIAN(total_time); total_flux = TO_LITTLE_ENDIAN(total_flux); balance = TO_LITTLE_ENDIAN(balance); #endif U31_LOG_INFO("Login auth succeeded! User info: " << std::endl); U31_LOG_INFO("Used Time: " << total_time << " Minutes, Used Flux: " << (total_flux & 0x0FFFFFFFF) / 1024.0 << " MB, Balance: " << (balance & 0x0FFFFFFFF) / 100.0 << " RMB" << std::endl); return 0; }; U31_HANDLE_ERROR("Send Login Auth"); U31_AUTO_RETRY("Send Login Auth"); }