bool server_process_request(twopence_transaction_t *trans, twopence_buf_t *payload) { twopence_file_xfer_t xfer; twopence_command_t cmd; switch (trans->type) { case TWOPENCE_PROTO_TYPE_INJECT: twopence_file_xfer_init(&xfer); if (!twopence_protocol_dissect_inject_packet(payload, &xfer)) goto bad_packet; server_inject_file(trans, &xfer); twopence_file_xfer_destroy(&xfer); break; case TWOPENCE_PROTO_TYPE_EXTRACT: twopence_file_xfer_init(&xfer); if (!twopence_protocol_dissect_extract_packet(payload, &xfer)) goto bad_packet; server_extract_file(trans, &xfer); twopence_file_xfer_destroy(&xfer); break; case TWOPENCE_PROTO_TYPE_COMMAND: memset(&cmd, 0, sizeof(cmd)); if (!twopence_protocol_dissect_command_packet(payload, &cmd) || cmd.command[0] == '\0') goto bad_packet; server_run_command(trans, &cmd); twopence_command_destroy(&cmd); break; case TWOPENCE_PROTO_TYPE_QUIT: server_request_quit(); /* we should not get here */ trans->done = true; break; default: twopence_log_error("Unknown command code '%c' in global context\n", trans->type); return false; } return true; bad_packet: twopence_log_error("unable to parse %s packet", twopence_protocol_packet_type_to_string(trans->type)); return false; }
/* * Takes the client struct and the server configuration and handles a client * request. Reads a command from the client, checks the ACL, runs the command * if appropriate, and sends any output back to the client. */ void server_v1_handle_messages(struct client *client, struct config *config) { gss_buffer_desc token; OM_uint32 major, minor; struct iovec **argv = NULL; int status, flags; /* Receive the message. */ status = token_recv_priv(client->fd, client->context, &flags, &token, TOKEN_MAX_LENGTH, TIMEOUT, &major, &minor); if (status != TOKEN_OK) { warn_token("receiving command token", status, major, minor); if (status == TOKEN_FAIL_LARGE) server_send_error(client, ERROR_TOOMUCH_DATA, "Too much data"); else if (status != TOKEN_FAIL_EOF) server_send_error(client, ERROR_BAD_TOKEN, "Invalid token"); return; } /* Check the data size. */ if (token.length > TOKEN_MAX_DATA) { warn("command data length %lu exceeds 64KB", (unsigned long) token.length); server_send_error(client, ERROR_TOOMUCH_DATA, "Too much data"); gss_release_buffer(&minor, &token); return; } /* * Do the shared parsing of the message. This code is identical to the * code for v2 (v2 just pulls more data off the front of the token first). */ argv = server_parse_command(client, token.value, token.length); gss_release_buffer(&minor, &token); if (argv == NULL) return; /* * Check the ACL and existence of the command, run the command if * possible, and accumulate the output in the client struct. */ server_run_command(client, config, argv); server_free_command(argv); }