예제 #1
0
/**
 * Read event for EPOLLIN on the telnetd protocol module.
 *
 * @param dcb	The descriptor control block
 * @return
 */
static int
telnetd_read_event(DCB* dcb)
{
int		n;
GWBUF		*head = NULL;
SESSION		*session = dcb->session;
ROUTER_OBJECT	*router = session->service->router;
ROUTER		*router_instance = session->service->router_instance;
void		*rsession = session->router_session;
TELNETD		*telnetd = (TELNETD *)dcb->protocol;
char		*password, *t;

	if ((n = dcb_read(dcb, &head)) != -1)
	{
		if (head)
		{
			unsigned char *ptr = GWBUF_DATA(head);
			ptr = GWBUF_DATA(head);
			while (GWBUF_LENGTH(head) && *ptr == TELNET_IAC)
			{
				telnetd_command(dcb, ptr + 1);
				GWBUF_CONSUME(head, 3);
				ptr = GWBUF_DATA(head);
			}
			if (GWBUF_LENGTH(head))
			{
				switch (telnetd->state)
				{
				case TELNETD_STATE_LOGIN:
					telnetd->username = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head));
					/* Strip the cr/lf from the username */
				        t = strstr(telnetd->username, "\r\n");
				        if (t)
                				*t = 0;
					telnetd->state = TELNETD_STATE_PASSWD;
					dcb_printf(dcb, "Password: "******"\r\n");
				        if (t)
                				*t = 0;
					if (admin_verify(telnetd->username, password))
					{
						telnetd_echo(dcb, 1);
						telnetd->state = TELNETD_STATE_DATA;
						dcb_printf(dcb, "\n\nMaxScale> ");
					}
					else
					{
						dcb_printf(dcb, "\n\rLogin incorrect\n\rLogin: ");
						telnetd_echo(dcb, 1);
						telnetd->state = TELNETD_STATE_LOGIN;
						free(telnetd->username);
					}
					gwbuf_consume(head, GWBUF_LENGTH(head));
					free(password);
					break;
				case TELNETD_STATE_DATA:
					router->routeQuery(router_instance, rsession, head);
					break;
				}
			}
			else
			{
				// Force the free of the buffer header
				gwbuf_consume(head, 0);
			}
		}
	}
	return n;
}
예제 #2
0
/**
 * Read the backend server MySQL handshake  
 *
 * @param conn	MySQL protocol structure
 * @return 0 on success, 1 on failure
 */
int gw_read_backend_handshake(MySQLProtocol *conn) {
	GWBUF *head = NULL;
	DCB *dcb = conn->owner_dcb;
	int n = -1;
	uint8_t *payload = NULL;
	int h_len = 0;
	int  success = 0;
	int packet_len = 0;

	if ((n = dcb_read(dcb, &head)) != -1) {
		if (head) {
			payload = GWBUF_DATA(head);
			h_len = gwbuf_length(head);

			/*
			 * The mysql packets content starts at byte fifth
			 * just return with less bytes
			 */

			if (h_len <= 4) {
				/* log error this exit point */
				conn->state = MYSQL_AUTH_FAILED;
				return 1;
			}

			//get mysql packet size, 3 bytes
			packet_len = gw_mysql_get_byte3(payload);

			if (h_len < (packet_len + 4)) {
				/*
				 * data in buffer less than expected in the
                                 * packet. Log error this exit point
				 */
				conn->state = MYSQL_AUTH_FAILED;
				return 1;
			}

			// skip the 4 bytes header
			payload += 4;

			//Now decode mysql handshake
			success = gw_decode_mysql_server_handshake(conn,
                                                                   payload);

			if (success < 0) {
				/* MySQL handshake has not been properly decoded
				 * we cannot continue
				 * log error this exit point
				 */
				conn->state = MYSQL_AUTH_FAILED;
				return 1;
			}

			conn->state = MYSQL_AUTH_SENT;

			// consume all the data here
			head = gwbuf_consume(head, GWBUF_LENGTH(head));

			return 0;
		}
	}
	
	// Nothing done here, log error this
	return 1;
}
예제 #3
0
/**
 * Receive the MySQL authentication packet from backend, packet # is 2
 *
 * @param protocol The MySQL protocol structure
 * @return -1 in case of failure, 0 if there was nothing to read, 1 if read
 * was successful.
 */
int gw_receive_backend_auth(
        MySQLProtocol *protocol)
{
	int n = -1;
	GWBUF   *head = NULL;
	DCB     *dcb = protocol->owner_dcb;
	uint8_t *ptr = NULL;
        int      rc = 0;

        n = dcb_read(dcb, &head);

        /*<
         * Read didn't fail and there is enough data for mysql packet.
         */
        if (n != -1 &&
            head != NULL &&
            GWBUF_LENGTH(head) >= 5)
        {
                ptr = GWBUF_DATA(head);
                /*<
                 * 5th byte is 0x0 if successful.
                 */
                if (ptr[4] == '\x00') {
                        rc = 1;
                } else {
                        uint8_t* tmpbuf =
                                (uint8_t *)calloc(1, GWBUF_LENGTH(head)+1);
                        memcpy(tmpbuf, ptr, GWBUF_LENGTH(head));
                        LOGIF(LD, (skygw_log_write(
                                LOGFILE_DEBUG,
                                "%lu [gw_receive_backend_auth] Invalid "
                                "authentication message from backend dcb %p "
                                "fd %d, ptr[4] = %p, msg %s.",
                                pthread_self(),
                                dcb,
                                dcb->fd,
                                tmpbuf[4],
                                tmpbuf)));
                        
                                free(tmpbuf);
                                rc = -1;
                }
                /*<
                 * Remove data from buffer.
                 */
                head = gwbuf_consume(head, GWBUF_LENGTH(head));
        }
        else if (n == 0)
        {
                /*<
                 * This is considered as success because call didn't fail,
                 * although no bytes was read.
                 */
                rc = 0;
                LOGIF(LD, (skygw_log_write(
                        LOGFILE_DEBUG,
                        "%lu [gw_receive_backend_auth] Read zero bytes from "
                        "backend dcb %p fd %d in state %s. n %d, head %p, len %d",
                        pthread_self(),
                        dcb,
                        dcb->fd,
                        STRDCBSTATE(dcb->state),
                        n,
                        head,
                        (head == NULL) ? 0 : GWBUF_LENGTH(head))));
        }
        else
        {
                ss_dassert(n < 0 && head == NULL);
                rc = -1;
                LOGIF(LD, (skygw_log_write_flush(
                        LOGFILE_DEBUG,
                        "%lu [gw_receive_backend_auth] Reading from backend dcb %p "
                        "fd %d in state %s failed. n %d, head %p, len %d",
                        pthread_self(),
                        dcb,
                        dcb->fd,
                        STRDCBSTATE(dcb->state),
                        n,
                        head,
                        (head == NULL) ? 0 : GWBUF_LENGTH(head))));
        }
        
        return rc;
}
예제 #4
0
파일: httpd.c 프로젝트: markus456/MaxScale
/**
 * Read event for EPOLLIN on the httpd protocol module.
 *
 * @param dcb	The descriptor control block
 * @return
 */
static int
httpd_read_event(DCB *dcb)
{
SESSION		*session = dcb->session;
GWBUF		*buf = NULL;
char		*ptr, *sol;
HTTPD_session	*client_data = NULL;
int 		n;

	// Read all the available data
	if ((n = dcb_read(dcb, &buf)) != -1)
	{
		client_data = dcb->data;

		if (client_data->saved)
		{
			buf = gwbuf_append(client_data->saved, buf);
			client_data->saved = NULL;
		}
		buf = gwbuf_make_contiguous(buf);

		ptr = GWBUF_DATA(buf);

		if (strncasecmp(ptr, "POST", 4))
		{
			client_data->method = METHOD_POST;
			gwbuf_add_property(buf, "Method", "POST");
			ptr = ptr + 4;
		}
		else if (strncasecmp(ptr, "PUT", 3))
		{
			client_data->method = METHOD_PUT;
			gwbuf_add_property(buf, "Method", "PUT");
			ptr = ptr + 3;
		}
		else if (strncasecmp(ptr, "GET", 3))
		{
			client_data->method = METHOD_GET;
			gwbuf_add_property(buf, "Method", "GET");
			ptr = ptr + 3;
		}
		else if (strncasecmp(ptr, "HEAD", 4))
		{
			client_data->method = METHOD_HEAD;
			gwbuf_add_property(buf, "Method", "HEAD");
			ptr = ptr + 4;
		}
		while (ptr < (char *)(buf->end) && isspace(*ptr))
			ptr++;
		sol = ptr;
		while (ptr < (char *)(buf->end) && isspace(*ptr) == 0)
			ptr++;
		client_data->url = strndup(sol, ptr - sol);
		gwbuf_add_property(buf, "URL", client_data->url);
		while ((sol = httpd_nextline(buf, ptr)) != NULL && 
				*sol != '\n' && *sol != '\r')
		{
			httpd_process_header(buf, sol, client_data);
			ptr = sol;
		}

		/*
		 * We have read all the headers, or run out of data to 
		 * examine.
		 */
		if (sol == NULL)
		{
			client_data->saved = buf;
			return 0;
		}
		else
		{
			if (((char *)(buf->end) - sol)
					< client_data->request_len)
			{
				client_data->saved = buf;
			}
			else
			{
				LOGIF(LT, (skygw_log_write(
		                           LOGFILE_TRACE,
               		            "HTTPD: request %s.\n", client_data->url)));
				SESSION_ROUTE_QUERY(session, buf);
				if (client_data->url)
				{
					free(client_data->url);
					client_data->url = NULL;
				}
			}
		}



	}
	return 0;
}