/**
 * call the python function to intercept the handshake packet
 *
 * @return PROXY_SEND_QUERY  to send the packet from the client
 *         PROXY_NO_DECISION to pass the server packet unmodified
 */
static network_mysqld_python_stmt_ret
proxy_python_read_handshake(network_mysqld_con *con) {
	network_mysqld_con_python_t *st = con->plugin_con_state;
	network_mysqld_python_stmt_ret ret = PROXY_NO_DECISION;

    if(!CHECK_FUNC(read_handshake))
        return ret;

    PyObject *result = PyObject_CallFunctionObjArgs(
				GET_FUNC(read_handshake), st->proxy, NULL);
	GET_PYTHON_RESULT(read_handshake)

    switch(ret) {
    case PROXY_NO_DECISION:
        break;
    case PROXY_SEND_QUERY:
        g_warning("%s.%d: (read_handshake) return proxy.PROXY_SEND_QUERY is "
					"deprecated, use PROXY_SEND_RESULT instead",
					__FILE__, __LINE__);
        ret = PROXY_SEND_RESULT;
    case PROXY_SEND_RESULT:
        if(network_mysqld_con_python_handle_proxy_response(con, st->proxy))
            network_mysqld_con_send_error(con->client, C("(python) handling "
							"proxy.response failed, check error-log"));
        break;
    default:
        ret = PROXY_NO_DECISION;
        break;
    }
    return ret;
}
Beispiel #2
0
int Get_F (node* tree)
{
	int err_index = 0;
	ASSERT_TREE_OK (tree);

	char tmp_word[TMPLEN] = {};
	strcpy (tmp_word, (*CUR) -> word);
	strupr (tmp_word);
	int func = 0;

	if (0);
	CHECK_FUNC(tmp_word, SIN)
	CHECK_FUNC(tmp_word, COS)
	CHECK_FUNC(tmp_word, TAN)
	CHECK_FUNC(tmp_word, CTAN)
	CHECK_FUNC(tmp_word, LN)
	CHECK_FUNC(tmp_word, LOG)

	if (func == 0) return ERR_WRONG_FUNC;
	CUR++;
	if ((*CUR) -> op != SEP_OPEN_BRACKET) return ERR_FUNC_OPEN_BRACKET;
	CUR++;

	Tree_Add_Left (tree, Node_NEW());
	int ret = Get_E (tree -> left);
	if (ret != HAPPY) if (ret == 0)  return ret;

	if (func == FUNC_LOG)
	{
		if ((*CUR) -> op != SEP_COMMA) return ERR_FUNC_COMMA;
		CUR++;
		ret = Tree_Add_Right (tree, Node_NEW());
		if (ret != HAPPY) if (ret == 0)  return ret;
		ret = Get_E (tree -> right);
		if (ret != HAPPY) if (ret == 0)  return ret;
	}

	if ((*CUR) -> op != SEP_CLOSE_BRACKET) return ERR_FUNC_CLOSE_BRACKET;
	CUR++;

	tree -> type = FUNC;
	tree -> op	 = func;

	ASSERT_TREE_OK (tree);
return HAPPY;
}
static network_mysqld_python_stmt_ret
proxy_python_read_auth(network_mysqld_con *con) {
	network_mysqld_python_stmt_ret ret = PROXY_NO_DECISION;
	network_mysqld_con_python_t *st = con->plugin_con_state;

    if(!CHECK_FUNC(read_auth))
        return ret;

    PyObject *result = PyObject_CallFunctionObjArgs(
				GET_FUNC(read_auth), st->proxy, NULL);
	GET_PYTHON_RESULT(read_auth)

    switch(ret) {
    case PROXY_NO_DECISION:
        break;
    case PROXY_SEND_RESULT:
        /* answer directly */
        if (network_mysqld_con_python_handle_proxy_response(con, st->proxy))
            network_mysqld_con_send_error(con->client, C("(python) handling "
							"proxy.response failed, check error-log"));
        break;
    case PROXY_SEND_QUERY:
        /* something is in the injection queue, pull it from there and replace
		 * the content of original packet
		 */

        if (st->injected.queries->length)
            ret = PROXY_SEND_INJECTION;
        else
            ret = PROXY_NO_DECISION;
        break;
    default:
        ret = PROXY_NO_DECISION;
        break;
    }
	return ret;
}
static network_mysqld_python_stmt_ret
proxy_python_read_query_result(network_mysqld_con *con) {
	network_socket *send_sock = con->client;
	network_socket *recv_sock = con->server;
	injection *inj = NULL;
	network_mysqld_con_python_t *st = con->plugin_con_state;
	network_mysqld_python_stmt_ret ret = PROXY_NO_DECISION;
	GString *packet;

	/**
	 * check if we want to forward the statement to the client
	 * if not, clean the send-queue
	 */
	if (0 == st->injected.queries->length)
		return PROXY_NO_DECISION;

    if(!CHECK_FUNC(read_query_result))
        return ret;

	inj = g_queue_pop_head(st->injected.queries);

	inj->result_queue = con->server->recv_queue->chunks;
	PyObject * injection_obj = Injection_New(inj);
	if(!injection_obj){
		PyErr_Print();
        network_mysqld_con_send_error(con->client,
                    C("PyProxy: Failed to create injection object."));
		con->state = CON_STATE_SEND_ERROR;
        return PROXY_SEND_RESULT;
	}
    PyObject *result = PyObject_CallFunctionObjArgs(
			GET_FUNC(read_query_result), st->proxy, injection_obj, NULL);
	Py_DECREF(injection_obj);
	GET_PYTHON_RESULT(read_query_result)

    if (!con->resultset_is_needed && (PROXY_NO_DECISION != ret)) {
        g_critical("%s: read_query_result() in %s tries to modify the resultset, "
				"but hasn't asked to buffer it in proxy.query.append(..., True). "
				"We ignore the change to the result-set.",
				G_STRLOC, con->config->python_script);
        ret = PROXY_NO_DECISION;
    }

    switch (ret) {
    case PROXY_SEND_RESULT:
		/* we can only replace the result, if we buffer it */
        g_assert_cmpint(con->resultset_is_needed, ==, TRUE);
        while ((packet = g_queue_pop_head(recv_sock->recv_queue->chunks)))
			g_string_free(packet, TRUE);
        if (network_mysqld_con_python_handle_proxy_response(con, st->proxy))
            if (!st->injected.sent_resultset)
                network_mysqld_con_send_error(con->client, C("(python) handling"
								" proxy.response failed, check error-log"));
        /* fall through */
    case PROXY_NO_DECISION:
        if (!st->injected.sent_resultset) {
            // make sure we send only one result-set per client-query
            while ((packet = g_queue_pop_head(recv_sock->recv_queue->chunks)))
                network_mysqld_queue_append_raw(send_sock,
							send_sock->send_queue, packet);
            st->injected.sent_resultset++;
            break;
        }
        g_critical("%s.%d: got asked to send a resultset, but ignoring it as "
					"we already have sent %d resultset(s). injection-id: %d",
					__FILE__, __LINE__, st->injected.sent_resultset, inj->id);
        st->injected.sent_resultset++;

        /* fall through */
    case PROXY_IGNORE_RESULT:
        /* trash the packets for the injection query */

        if (!con->resultset_is_needed) {
            g_critical("%s: we tried to send more than one resultset to the "
						"client, but didn't had them buffered. Now the client "
						"is out of sync may have closed the connection on us. "
						"Please use proxy.queries.append(..., True) to fix this.",
						G_STRLOC);
            break;
        }
        while ((packet = g_queue_pop_head(recv_sock->recv_queue->chunks)))
			g_string_free(packet, TRUE);
        break;
    default:
        /* invalid return code */
        g_message("%s.%d: return-code for read_query_result() was neither "
				"PROXY_SEND_RESULT or PROXY_IGNORE_RESULT, will ignore the result",
                __FILE__, __LINE__);
        while ((packet = g_queue_pop_head(send_sock->send_queue->chunks)))
			g_string_free(packet, TRUE);
        break;
    }
	injection_free(inj);
	return ret;
}