Addition of login authentication for telnet debug CLI - currently username and password
are fixed as admin/skysql
This commit is contained in:
61
modules/include/telnetd.h
Normal file
61
modules/include/telnetd.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef _TELNETD_H
|
||||||
|
#define _TELNETD_H
|
||||||
|
/*
|
||||||
|
* This file is distributed as part of the SkySQL Gateway. It is free
|
||||||
|
* software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation,
|
||||||
|
* version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright SkySQL Ab 2013
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file telentd.h The telnetd protocol module header file
|
||||||
|
*
|
||||||
|
* @verbatim
|
||||||
|
* Revision History
|
||||||
|
*
|
||||||
|
* Date Who Description
|
||||||
|
* 17/07/13 Mark Riddoch Initial implementation
|
||||||
|
*
|
||||||
|
* @endverbatim
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct telnetd {
|
||||||
|
int state; /**< The connection state */
|
||||||
|
char *username; /**< The login name of the user */
|
||||||
|
} TELNETD;
|
||||||
|
|
||||||
|
#define TELNETD_STATE_LOGIN 1 /**< Issued login prompt */
|
||||||
|
#define TELNETD_STATE_PASSWD 2 /**< Issued password prompt */
|
||||||
|
#define TELNETD_STATE_DATA 3 /**< User logged in */
|
||||||
|
|
||||||
|
#define TELNET_SE 240
|
||||||
|
#define TELNET_NOP 241
|
||||||
|
#define TELNET_DATA_MARK 242
|
||||||
|
#define TELNET_BRK 243
|
||||||
|
#define TELNET_IP 244
|
||||||
|
#define TELNET_AO 245
|
||||||
|
#define TELNET_AYT 246
|
||||||
|
#define TELNET_EC 247
|
||||||
|
#define TELNET_EL 248
|
||||||
|
#define TELNET_GA 249
|
||||||
|
#define TELNET_SB 250
|
||||||
|
#define TELNET_WILL 251
|
||||||
|
#define TELNET_WONT 252
|
||||||
|
#define TELNET_DO 253
|
||||||
|
#define TELNET_DONT 254
|
||||||
|
#define TELNET_IAC 255
|
||||||
|
#define TELNET_ECHO 1
|
||||||
|
#define TELNET_SUPPRESS_GO_AHEAD 3
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <gw.h>
|
#include <gw.h>
|
||||||
|
#include <telnetd.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file telnetd.c - telnet daemon protocol module
|
* @file telnetd.c - telnet daemon protocol module
|
||||||
@ -48,12 +49,12 @@
|
|||||||
* Revision History
|
* Revision History
|
||||||
* Date Who Description
|
* Date Who Description
|
||||||
* 17/06/2013 Mark Riddoch Initial version
|
* 17/06/2013 Mark Riddoch Initial version
|
||||||
|
* 17/07/2013 Mark Riddoch Addition of login phase
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define TELNET_IAC 255
|
|
||||||
|
|
||||||
static char *version_str = "V1.0.0";
|
static char *version_str = "V1.0.1";
|
||||||
|
|
||||||
static int telnetd_read_event(DCB* dcb);
|
static int telnetd_read_event(DCB* dcb);
|
||||||
static int telnetd_write_event(DCB *dcb);
|
static int telnetd_write_event(DCB *dcb);
|
||||||
@ -81,8 +82,9 @@ static GWPROTOCOL MyObject = {
|
|||||||
NULL /**< Session */
|
NULL /**< Session */
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void telnetd_command(DCB *, unsigned char *cmd);
|
||||||
telnetd_command(DCB *, char *cmd);
|
static void telnetd_echo(DCB *dcb, int enable);
|
||||||
|
static int password_verify(char *, char *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the mandatory version entry point
|
* Implementation of the mandatory version entry point
|
||||||
@ -134,20 +136,52 @@ SESSION *session = dcb->session;
|
|||||||
ROUTER_OBJECT *router = session->service->router;
|
ROUTER_OBJECT *router = session->service->router;
|
||||||
ROUTER *router_instance = session->service->router_instance;
|
ROUTER *router_instance = session->service->router_instance;
|
||||||
void *rsession = session->router_session;
|
void *rsession = session->router_session;
|
||||||
|
TELNETD *telnetd = (TELNETD *)dcb->protocol;
|
||||||
|
char *password;
|
||||||
|
|
||||||
if ((n = dcb_read(dcb, &head)) != -1)
|
if ((n = dcb_read(dcb, &head)) != -1)
|
||||||
{
|
{
|
||||||
dcb->state = DCB_STATE_PROCESSING;
|
dcb->state = DCB_STATE_PROCESSING;
|
||||||
if (head)
|
if (head)
|
||||||
{
|
{
|
||||||
char *ptr = GWBUF_DATA(head);
|
unsigned char *ptr = GWBUF_DATA(head);
|
||||||
ptr = GWBUF_DATA(head);
|
ptr = GWBUF_DATA(head);
|
||||||
if (*ptr == TELNET_IAC)
|
while (*ptr == TELNET_IAC)
|
||||||
{
|
{
|
||||||
telnetd_command(dcb, ptr + 1);
|
telnetd_command(dcb, ptr + 1);
|
||||||
GWBUF_CONSUME(head, 2);
|
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));
|
||||||
|
telnetd->state = TELNETD_STATE_PASSWD;
|
||||||
|
dcb_printf(dcb, "Password: ");
|
||||||
|
telnetd_echo(dcb, 0);
|
||||||
|
break;
|
||||||
|
case TELNETD_STATE_PASSWD:
|
||||||
|
password = strndup(GWBUF_DATA(head), GWBUF_LENGTH(head));
|
||||||
|
if (password_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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TELNETD_STATE_DATA:
|
||||||
|
router->routeQuery(router_instance, rsession, head);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
router->routeQuery(router_instance, rsession, head);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dcb->state = DCB_STATE_POLLING;
|
dcb->state = DCB_STATE_POLLING;
|
||||||
@ -234,6 +268,7 @@ int n_connect = 0;
|
|||||||
client->session = session_alloc(dcb->session->service, client);
|
client->session = session_alloc(dcb->session->service, client);
|
||||||
|
|
||||||
client->state = DCB_STATE_IDLE;
|
client->state = DCB_STATE_IDLE;
|
||||||
|
client->protocol = malloc(sizeof(TELNETD));
|
||||||
|
|
||||||
if (poll_add_dcb(client) == -1)
|
if (poll_add_dcb(client) == -1)
|
||||||
{
|
{
|
||||||
@ -241,7 +276,8 @@ int n_connect = 0;
|
|||||||
}
|
}
|
||||||
n_connect++;
|
n_connect++;
|
||||||
|
|
||||||
dcb_printf(client, "Gateway> ");
|
((TELNETD *)(client->protocol))->state = TELNETD_STATE_LOGIN;
|
||||||
|
dcb_printf(client, "MaxScale login: ");
|
||||||
client->state = DCB_STATE_POLLING;
|
client->state = DCB_STATE_POLLING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,6 +361,51 @@ short pnum;
|
|||||||
* @param cmd The command stream
|
* @param cmd The command stream
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
telnetd_command(DCB *dcb, char *cmd)
|
telnetd_command(DCB *dcb, unsigned char *cmd)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable telnet protocol echo
|
||||||
|
*
|
||||||
|
* @param dcb DCB of the telnet connection
|
||||||
|
* @param enable Enable or disable echo functionality
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
telnetd_echo(DCB *dcb, int enable)
|
||||||
|
{
|
||||||
|
GWBUF *gwbuf;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
if ((gwbuf = gwbuf_alloc(3)) == NULL)
|
||||||
|
return;
|
||||||
|
buf = GWBUF_DATA(gwbuf);
|
||||||
|
buf[0] = TELNET_IAC;
|
||||||
|
buf[1] = enable ? TELNET_WONT : TELNET_WILL;
|
||||||
|
buf[2] = TELNET_ECHO;
|
||||||
|
dcb_write(dcb, gwbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify a username and password
|
||||||
|
*
|
||||||
|
* @param username Username to verify
|
||||||
|
* @param password Password to verify
|
||||||
|
* @return Non-zero if the username/password combination is valid
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
password_verify(char *username, char *password)
|
||||||
|
{
|
||||||
|
char *t;
|
||||||
|
|
||||||
|
/* Strip the cr/lf from the username and password */
|
||||||
|
t = strstr(username, "\r\n");
|
||||||
|
if (t)
|
||||||
|
*t = 0;
|
||||||
|
t = strstr(password, "\r\n");
|
||||||
|
if (t)
|
||||||
|
*t = 0;
|
||||||
|
if (strcmp(username, "admin") == 0 && strcmp(password, "skysql") == 0)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -23,10 +23,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#if defined(SS_DEBUG)
|
|
||||||
#include <skygw_utils.h>
|
#include <skygw_utils.h>
|
||||||
#include <log_manager.h>
|
#include <log_manager.h>
|
||||||
#endif
|
|
||||||
#include <query_classifier.h>
|
#include <query_classifier.h>
|
||||||
#include <dcb.h>
|
#include <dcb.h>
|
||||||
#include <spinlock.h>
|
#include <spinlock.h>
|
||||||
|
|||||||
Reference in New Issue
Block a user