static gboolean handle_join (CockpitRealms *object, GDBusMethodInvocation *invocation, const gchar *arg_name, GVariant *arg_creds, GVariant *arg_options) { if (!auth_check_sender_role (invocation, COCKPIT_ROLE_REALM_ADMIN)) return TRUE; return handle_op (object, invocation, "Join", arg_name, arg_creds, arg_options); }
int server_logic(client_t *c, proto_msg_t *msg) { TRACE_MSG(msg); switch (proto_msg_type(msg)) { case MSG_HELLO: return (handle_hello(c, msg)); case MSG_OP: return (handle_op(c, msg)); case MSG_TEXT: return (handle_text(c, msg)); case MSG_NUM: return (handle_num(c, msg)); default: return (send_text_message(c, "thank you!")); } }
/* * Schedule replacement for rtsem_down(). Only called for threads with * PF_MUTEX_TESTER set. * * This allows us to have finegrained control over the event flow. * */ void schedule_rt_mutex_test(struct rt_mutex *mutex) { int tid, op, dat; struct test_thread_data *td; /* We have to lookup the task */ for (tid = 0; tid < MAX_RT_TEST_THREADS; tid++) { if (threads[tid] == current) break; } BUG_ON(tid == MAX_RT_TEST_THREADS); td = &thread_data[tid]; op = td->opcode; dat = td->opdata; switch (op) { case RTTEST_LOCK: case RTTEST_LOCKINT: case RTTEST_LOCKNOWAIT: case RTTEST_LOCKINTNOWAIT: if (mutex != &mutexes[dat]) break; if (td->mutexes[dat] != 1) break; td->mutexes[dat] = 2; td->event = atomic_add_return(1, &rttest_event); break; case RTTEST_LOCKBKL: default: break; } schedule(); switch (op) { case RTTEST_LOCK: case RTTEST_LOCKINT: if (mutex != &mutexes[dat]) return; if (td->mutexes[dat] != 2) return; td->mutexes[dat] = 3; td->event = atomic_add_return(1, &rttest_event); break; case RTTEST_LOCKNOWAIT: case RTTEST_LOCKINTNOWAIT: if (mutex != &mutexes[dat]) return; if (td->mutexes[dat] != 2) return; td->mutexes[dat] = 1; td->event = atomic_add_return(1, &rttest_event); return; case RTTEST_LOCKBKL: return; default: return; } td->opcode = 0; for (;;) { set_current_state(TASK_INTERRUPTIBLE); if (td->opcode > 0) { int ret; set_current_state(TASK_RUNNING); ret = handle_op(td, 1); set_current_state(TASK_INTERRUPTIBLE); if (td->opcode == RTTEST_LOCKCONT) break; td->opcode = ret; } /* Wait for the next command to be executed */ schedule(); } /* Restore previous command and data */ td->opcode = op; td->opdata = dat; }
STATIC mp_uint_t _webrepl_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) { // We know that os.dupterm always calls with size = 1 assert(size == 1); mp_obj_webrepl_t *self = self_in; const mp_stream_p_t *sock_stream = mp_get_stream_raise(self->sock, MP_STREAM_OP_READ); mp_uint_t out_sz = sock_stream->read(self->sock, buf, size, errcode); //DEBUG_printf("webrepl: Read %d initial bytes from websocket\n", out_sz); if (out_sz == 0 || out_sz == MP_STREAM_ERROR) { return out_sz; } if (self->state == STATE_PASSWD) { char c = *(char*)buf; if (c == '\r' || c == '\n') { self->hdr.fname[self->data_to_recv] = 0; DEBUG_printf("webrepl: entered password: %s\n", self->hdr.fname); if (strcmp(self->hdr.fname, webrepl_passwd) != 0) { write_webrepl_str(self->sock, SSTR(denied_prompt)); return 0; } self->state = STATE_NORMAL; self->data_to_recv = 0; write_webrepl_str(self->sock, SSTR(connected_prompt)); } else if (self->data_to_recv < 10) { self->hdr.fname[self->data_to_recv++] = c; } return -2; } // If last read data belonged to text record (== REPL) int err; if (sock_stream->ioctl(self->sock, MP_STREAM_GET_DATA_OPTS, 0, &err) == 1) { return out_sz; } DEBUG_printf("webrepl: received bin data, hdr_to_recv: %d, data_to_recv=%d\n", self->hdr_to_recv, self->data_to_recv); if (self->hdr_to_recv != 0) { char *p = (char*)&self->hdr + sizeof(self->hdr) - self->hdr_to_recv; *p++ = *(char*)buf; if (--self->hdr_to_recv != 0) { mp_uint_t hdr_sz = sock_stream->read(self->sock, p, self->hdr_to_recv, errcode); if (hdr_sz == MP_STREAM_ERROR) { return hdr_sz; } self->hdr_to_recv -= hdr_sz; if (self->hdr_to_recv != 0) { return -2; } } DEBUG_printf("webrepl: op: %d, file: %s, chunk @%x, sz=%d\n", self->hdr.type, self->hdr.fname, (uint32_t)self->hdr.offset, self->hdr.size); handle_op(self); return -2; } if (self->data_to_recv != 0) { static byte filebuf[512]; filebuf[0] = *(byte*)buf; mp_uint_t buf_sz = 1; if (--self->data_to_recv != 0) { size_t to_read = MIN(sizeof(filebuf) - 1, self->data_to_recv); mp_uint_t sz = sock_stream->read(self->sock, filebuf + 1, to_read, errcode); if (sz == MP_STREAM_ERROR) { return sz; } self->data_to_recv -= sz; buf_sz += sz; } DEBUG_printf("webrepl: Writing %lu bytes to file\n", buf_sz); int err; mp_uint_t res = mp_stream_writeall(self->cur_file, filebuf, buf_sz, &err); if(res == MP_STREAM_ERROR) { assert(0); } if (self->data_to_recv == 0) { close_meth(self->cur_file); self->hdr_to_recv = sizeof(struct webrepl_file); DEBUG_printf("webrepl: Finished writing file\n"); write_webrepl_resp(self->sock, 0); } #ifdef MICROPY_PY_WEBREPL_DELAY // Some platforms may have broken drivers and easily gets // overloaded with modest traffic WebREPL file transfers // generate. The basic workaround is a crude rate control // done in such way. mp_hal_delay_ms(MICROPY_PY_WEBREPL_DELAY); #endif } return -2; }
static int process_worker_packet(void *pool, int cfd, pid_t pid, sec_mod_st * sec, cmd_request_t cmd, uint8_t * buffer, size_t buffer_size) { unsigned i; gnutls_datum_t data, out; int ret; SecOpMsg *op; PROTOBUF_ALLOCATOR(pa, pool); seclog(sec, LOG_DEBUG, "cmd [size=%d] %s\n", (int)buffer_size, cmd_request_to_str(cmd)); data.data = buffer; data.size = buffer_size; switch (cmd) { case CMD_SEC_SIGN: case CMD_SEC_DECRYPT: op = sec_op_msg__unpack(&pa, data.size, data.data); if (op == NULL) { seclog(sec, LOG_INFO, "error unpacking sec op\n"); return -1; } i = op->key_idx; if (op->has_key_idx == 0 || i >= sec->key_size) { seclog(sec, LOG_INFO, "received out-of-bounds key index (%d)", i); return -1; } data.data = op->data.data; data.size = op->data.len; if (cmd == CMD_SEC_DECRYPT) { ret = gnutls_privkey_decrypt_data(sec->key[i], 0, &data, &out); } else { #if GNUTLS_VERSION_NUMBER >= 0x030200 ret = gnutls_privkey_sign_hash(sec->key[i], 0, GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, &data, &out); #else ret = gnutls_privkey_sign_raw_data(sec->key[i], 0, &data, &out); #endif } sec_op_msg__free_unpacked(op, &pa); if (ret < 0) { seclog(sec, LOG_INFO, "error in crypto operation: %s", gnutls_strerror(ret)); return -1; } ret = handle_op(pool, cfd, sec, cmd, out.data, out.size); gnutls_free(out.data); return ret; case CMD_SEC_CLI_STATS:{ CliStatsMsg *tmsg; tmsg = cli_stats_msg__unpack(&pa, data.size, data.data); if (tmsg == NULL) { seclog(sec, LOG_ERR, "error unpacking data"); return -1; } ret = handle_sec_auth_stats_cmd(sec, tmsg, pid); cli_stats_msg__free_unpacked(tmsg, &pa); return ret; } break; case CMD_SEC_AUTH_INIT:{ SecAuthInitMsg *auth_init; auth_init = sec_auth_init_msg__unpack(&pa, data.size, data.data); if (auth_init == NULL) { seclog(sec, LOG_INFO, "error unpacking auth init\n"); return -1; } ret = handle_sec_auth_init(cfd, sec, auth_init, pid); sec_auth_init_msg__free_unpacked(auth_init, &pa); return ret; } case CMD_SEC_AUTH_CONT:{ SecAuthContMsg *auth_cont; auth_cont = sec_auth_cont_msg__unpack(&pa, data.size, data.data); if (auth_cont == NULL) { seclog(sec, LOG_INFO, "error unpacking auth cont\n"); return -1; } ret = handle_sec_auth_cont(cfd, sec, auth_cont); sec_auth_cont_msg__free_unpacked(auth_cont, &pa); return ret; } case RESUME_STORE_REQ:{ SessionResumeStoreReqMsg *smsg; smsg = session_resume_store_req_msg__unpack(&pa, buffer_size, buffer); if (smsg == NULL) { seclog(sec, LOG_ERR, "error unpacking data"); return ERR_BAD_COMMAND; } ret = handle_resume_store_req(sec, smsg); /* zeroize the data */ safe_memset(buffer, 0, buffer_size); safe_memset(smsg->session_data.data, 0, smsg->session_data.len); session_resume_store_req_msg__free_unpacked(smsg, &pa); if (ret < 0) { seclog(sec, LOG_DEBUG, "could not store resumption data"); } } break; case RESUME_DELETE_REQ:{ SessionResumeFetchMsg *fmsg; fmsg = session_resume_fetch_msg__unpack(&pa, buffer_size, buffer); if (fmsg == NULL) { seclog(sec, LOG_ERR, "error unpacking data"); return ERR_BAD_COMMAND; } ret = handle_resume_delete_req(sec, fmsg); session_resume_fetch_msg__free_unpacked(fmsg, &pa); if (ret < 0) { seclog(sec, LOG_DEBUG, "could not delete resumption data."); } } break; case RESUME_FETCH_REQ:{ SessionResumeReplyMsg msg = SESSION_RESUME_REPLY_MSG__INIT; SessionResumeFetchMsg *fmsg; /* FIXME: rate limit that */ fmsg = session_resume_fetch_msg__unpack(&pa, buffer_size, buffer); if (fmsg == NULL) { seclog(sec, LOG_ERR, "error unpacking data"); return ERR_BAD_COMMAND; } ret = handle_resume_fetch_req(sec, fmsg, &msg); session_resume_fetch_msg__free_unpacked(fmsg, &pa); if (ret < 0) { msg.reply = SESSION_RESUME_REPLY_MSG__RESUME__REP__FAILED; seclog(sec, LOG_DEBUG, "could not fetch resumption data."); } else { msg.reply = SESSION_RESUME_REPLY_MSG__RESUME__REP__OK; } ret = send_msg(pool, cfd, RESUME_FETCH_REP, &msg, (pack_size_func) session_resume_reply_msg__get_packed_size, (pack_func) session_resume_reply_msg__pack); if (ret < 0) { seclog(sec, LOG_ERR, "could not send reply cmd %d.", (unsigned)cmd); return ERR_BAD_COMMAND; } } break; default: seclog(sec, LOG_WARNING, "unknown type 0x%.2x", cmd); return -1; } return 0; }