Example #1
0
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;
}
Example #2
0
/*
 * 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);
}