Skip to content
Snippets Groups Projects
Commit 4952d09a authored by John Hodge's avatar John Hodge
Browse files

Usermode/telnetd - Option negotation framework, indexed PTY

parent d1e3e105
Branches
Tags
No related merge requests found
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <acess/devices/pty.h> #include <acess/devices/pty.h>
#include <stdbool.h>
// === TYPES === // === TYPES ===
enum eTelnetMode enum eTelnetMode
...@@ -22,7 +23,10 @@ enum eTelnetMode ...@@ -22,7 +23,10 @@ enum eTelnetMode
MODE_WILL, MODE_WILL,
MODE_WONT, MODE_WONT,
MODE_DO, MODE_DO,
MODE_DONT MODE_DONT,
MODE_SUBNEG_OPTION,
MODE_SUBNEG_DATA,
MODE_SUBNEG_IAC,
}; };
typedef struct sClient typedef struct sClient
...@@ -37,6 +41,7 @@ void EventLoop(void); ...@@ -37,6 +41,7 @@ void EventLoop(void);
void Server_NewClient(int FD); void Server_NewClient(int FD);
void HandleServerBoundData(tClient *Client); void HandleServerBoundData(tClient *Client);
void HandleClientBoundData(tClient *Client); void HandleClientBoundData(tClient *Client);
void HandleOptionRequest(tClient *Client, int Option, bool Value, bool IsRequest);
// === GLOBALS === // === GLOBALS ===
// --- Configuration --- // --- Configuration ---
...@@ -94,7 +99,8 @@ void EventLoop(void) ...@@ -94,7 +99,8 @@ void EventLoop(void)
} }
// Select! // Select!
_SysSelect( maxfd+1, &fds, NULL, NULL, NULL, 0 ); int rv = _SysSelect( maxfd+1, &fds, NULL, NULL, NULL, 0 );
_SysDebug("Select return %i", rv);
// Check events // Check events
if( FD_ISSET(giServerFD, &fds) ) if( FD_ISSET(giServerFD, &fds) )
...@@ -154,7 +160,7 @@ void Server_NewClient(int FD) ...@@ -154,7 +160,7 @@ void Server_NewClient(int FD)
} }
// - Initialise // - Initialise
{ {
_SysIOCtl(clt->pty, PTY_IOCTL_SETID, "telnetd0"); _SysIOCtl(clt->pty, PTY_IOCTL_SETID, "telnetd#");
struct ptymode mode = {.InputMode = 0, .OutputMode=0}; struct ptymode mode = {.InputMode = 0, .OutputMode=0};
struct ptydims dims = {.W = 80, .H = 25}; struct ptydims dims = {.W = 80, .H = 25};
_SysIOCtl(clt->pty, PTY_IOCTL_SETMODE, &mode); _SysIOCtl(clt->pty, PTY_IOCTL_SETMODE, &mode);
...@@ -163,7 +169,9 @@ void Server_NewClient(int FD) ...@@ -163,7 +169,9 @@ void Server_NewClient(int FD)
// TODO: Arguments and envp // TODO: Arguments and envp
{ {
int clientfd = _SysOpen("/Devices/pts/telnetd0", OPENFLAG_READ|OPENFLAG_WRITE); char pty_path[] = "/Devices/pts/telnetd000";
_SysIOCtl(clt->pty, PTY_IOCTL_GETID, pty_path+13);
int clientfd = _SysOpen(pty_path, OPENFLAG_READ|OPENFLAG_WRITE);
if(clientfd < 0) { if(clientfd < 0) {
perror("Unable to open login PTY"); perror("Unable to open login PTY");
_SysClose(clt->Socket); _SysClose(clt->Socket);
...@@ -171,9 +179,11 @@ void Server_NewClient(int FD) ...@@ -171,9 +179,11 @@ void Server_NewClient(int FD)
clt->Socket = 0; clt->Socket = 0;
return ; return ;
} }
_SysDebug("Using client PTY %s", pty_path);
int fds[3] = {clientfd, clientfd, clientfd}; int fds[3] = {clientfd, clientfd, clientfd};
const char *argv[] = {"login", NULL}; const char *argv[] = {"login", NULL};
_SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL); _SysSpawn("/Acess/SBin/login", argv, argv, 3, fds, NULL);
_SysClose(clientfd);
} }
} }
...@@ -181,14 +191,16 @@ void HandleServerBoundData(tClient *Client) ...@@ -181,14 +191,16 @@ void HandleServerBoundData(tClient *Client)
{ {
uint8_t buf[BUFSIZ]; uint8_t buf[BUFSIZ];
size_t len; size_t len;
_SysDebug("Client %p", Client);
len = _SysRead(Client->Socket, buf, BUFSIZ); len = _SysRead(Client->Socket, buf, BUFSIZ);
_SysDebug("%i bytes for %p", len, Client);
if( len == 0 ) return ; if( len == 0 ) return ;
if( len == -1 ) { if( len == -1 ) {
return ; return ;
} }
// handle options // handle options
int last_flush = 0; // int last_flush = 0;
for( int i = 0; i < len; i ++ ) for( int i = 0; i < len; i ++ )
{ {
switch(Client->Mode) switch(Client->Mode)
...@@ -215,6 +227,8 @@ void HandleServerBoundData(tClient *Client) ...@@ -215,6 +227,8 @@ void HandleServerBoundData(tClient *Client)
break; break;
case 250: // Subnegotation case 250: // Subnegotation
_SysDebug("Subnegotiation"); _SysDebug("Subnegotiation");
// TODO: Get option ID, and then cache until 'END SB' (240)
Client->Mode = MODE_SUBNEG_OPTION;
break; break;
case 251: // WILL case 251: // WILL
Client->Mode = MODE_WILL; Client->Mode = MODE_WILL;
...@@ -229,27 +243,57 @@ void HandleServerBoundData(tClient *Client) ...@@ -229,27 +243,57 @@ void HandleServerBoundData(tClient *Client)
Client->Mode = MODE_DONT; Client->Mode = MODE_DONT;
break; break;
case 255: // Literal 255 case 255: // Literal 255
Client->Mode = MODE_DATA; _SysWrite(Client->pty, buf+i, 1);
i --; // hacky!
break; break;
} }
break; break;
case MODE_WILL: case MODE_WILL:
_SysDebug("Option %i WILL", buf[i]); _SysDebug("Option %i WILL", buf[i]);
HandleOptionRequest(Client, buf[i], true, false);
Client->Mode = MODE_DATA; Client->Mode = MODE_DATA;
break; break;
case MODE_WONT: case MODE_WONT:
_SysDebug("Option %i WONT", buf[i]); _SysDebug("Option %i WONT", buf[i]);
HandleOptionRequest(Client, buf[i], false, false);
Client->Mode = MODE_DATA; Client->Mode = MODE_DATA;
break; break;
case MODE_DO: case MODE_DO:
_SysDebug("Option %i DO", buf[i]); _SysDebug("Option %i DO", buf[i]);
HandleOptionRequest(Client, buf[i], true, true);
Client->Mode = MODE_DATA; Client->Mode = MODE_DATA;
break; break;
case MODE_DONT: case MODE_DONT:
_SysDebug("Option %i DONT", buf[i]); _SysDebug("Option %i DONT", buf[i]);
HandleOptionRequest(Client, buf[i], false, true);
Client->Mode = MODE_DATA; Client->Mode = MODE_DATA;
break; break;
case MODE_SUBNEG_OPTION:
_SysDebug("Option %i subnegotation", buf[i]);
Client->Mode = MODE_SUBNEG_DATA;
break;
case MODE_SUBNEG_IAC:
switch(buf[i])
{
case 240: // End subnegotation
// TODO: Handle subnegotation data
Client->Mode = MODE_DATA;
break;
case 255:
// TODO: Literal 255
Client->Mode = MODE_SUBNEG_DATA;
break;
default:
_SysDebug("Unexpected %i in SUBNEG IAC", buf[i]);
Client->Mode = MODE_SUBNEG_DATA;
break;
}
case MODE_SUBNEG_DATA:
if( buf[i] == 255 )
Client->Mode = MODE_SUBNEG_IAC;
else
;//_SysWrite(Client->pty, buf+i, 1);
break;
case MODE_DATA: case MODE_DATA:
if( buf[i] == 255 ) if( buf[i] == 255 )
Client->Mode = MODE_IAC; Client->Mode = MODE_IAC;
...@@ -270,3 +314,13 @@ void HandleClientBoundData(tClient *Client) ...@@ -270,3 +314,13 @@ void HandleClientBoundData(tClient *Client)
_SysWrite(Client->Socket, buf, len); _SysWrite(Client->Socket, buf, len);
} }
void HandleOptionRequest(tClient *Client, int Option, bool Value, bool IsRequest)
{
switch(Option)
{
default:
_SysDebug("Unknown option %i", Option);
break;
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment