bool lua_msg_handler(lua_State *state, SockMsg* msg) { int functionIndex = -3; Worker *worker = &g_workers[msg->sock->epoll_idx]; lua_getglobal(worker->state, worker->msg_handler); lua_pushinteger(state, (int)msg->sock->fd); #if ENABLE_XXTEA_ZLIB uLong buf_len = MAX_LUA_MSG_LEN; uncompress((Bytef*)msg_buf, &buf_len, (Bytef*)MSG_MSG(msg), MSG_LEN(msg)); xxtea_long xxlen = 0; char* xxresult = (char*)xxtea_decrypt((unsigned char*)msg_buf, buf_len, (unsigned char*)xxtea_key, strlen(xxtea_key), &xxlen); lua_pushlstring(state, xxresult, xxlen); free(xxresult); #else //printf("lua_msg_handler: %d %s\n", MSG_MSG(msg), MSG_LEN(msg)); lua_pushlstring(state, MSG_MSG(msg), MSG_LEN(msg)); #endif int traceback = 0; lua_getglobal(worker->state, worker->trace_handler); if (!lua_isfunction(worker->state, -1)) { lua_pop(worker->state, 1); /* L: ... func arg1 arg2 ... */ } else { lua_insert(worker->state, functionIndex - 1); /* L: ... G func arg1 arg2 ... */ traceback = functionIndex - 1; } bool ret = lua_pcall(worker->state, 2, 0, traceback); if(ret != 0) { Log(); printf("lua_pcall failed: %s\n", lua_tostring(worker->state, -1)); lua_pop(worker->state, 2); lua_settop(worker->state, 0); return false; } ret = lua_toboolean(state, -1); lua_pop(worker->state, 3); lua_settop(worker->state, 0); return ret; }
void u2fhid_init_cmd(const U2FHID_FRAME *f) { reader->seq = 0; reader->buf_ptr = reader->buf; reader->len = MSG_LEN(*f); reader->cmd = f->type; memcpy(reader->buf_ptr, f->init.data, sizeof(f->init.data)); reader->buf_ptr += sizeof(f->init.data); cid = f->cid; }
void u2fhid_read_start(const U2FHID_FRAME *f) { U2F_ReadBuffer readbuffer; memzero(&readbuffer, sizeof(readbuffer)); if (!(f->type & TYPE_INIT)) { return; } // Broadcast is reserved for init if (f->cid == CID_BROADCAST || f->cid == 0) { send_u2fhid_error(f->cid, ERR_INVALID_CID); return; } if ((unsigned)MSG_LEN(*f) > sizeof(reader->buf)) { send_u2fhid_error(f->cid, ERR_INVALID_LEN); return; } reader = &readbuffer; u2fhid_init_cmd(f); usbTiny(1); for(;;) { // Do we need to wait for more data while ((reader->buf_ptr - reader->buf) < (signed)reader->len) { uint8_t lastseq = reader->seq; uint8_t lastcmd = reader->cmd; int counter = U2F_TIMEOUT; while (reader->seq == lastseq && reader->cmd == lastcmd) { if (counter-- == 0) { // timeout send_u2fhid_error(cid, ERR_MSG_TIMEOUT); cid = 0; reader = 0; usbTiny(0); layoutHome(); return; } usbPoll(); } } // We have all the data switch (reader->cmd) { case 0: // message was aborted by init break; case U2FHID_PING: u2fhid_ping(reader->buf, reader->len); break; case U2FHID_MSG: u2fhid_msg((APDU *)reader->buf, reader->len); break; case U2FHID_WINK: u2fhid_wink(reader->buf, reader->len); break; default: send_u2fhid_error(cid, ERR_INVALID_CMD); break; } // wait for next commmand/ button press reader->cmd = 0; reader->seq = 255; while (dialog_timeout > 0 && reader->cmd == 0) { dialog_timeout--; usbPoll(); // may trigger new request //buttonUpdate(); if (keepkey_button_down() && (last_req_state == AUTH || last_req_state == REG)) { last_req_state++; // standard requires to remember button press for 10 seconds. dialog_timeout = 10 * U2F_TIMEOUT; } } if (reader->cmd == 0) { last_req_state = INIT; cid = 0; reader = 0; usbTiny(0); layoutHome(); return; } } }