diff options
Diffstat (limited to 'ncpd/socketchan.cc')
-rw-r--r-- | ncpd/socketchan.cc | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/ncpd/socketchan.cc b/ncpd/socketchan.cc index d78d3b6..a7d612e 100644 --- a/ncpd/socketchan.cc +++ b/ncpd/socketchan.cc @@ -39,6 +39,7 @@ iow(_iow) { skt = _skt; connectName = 0; + connectTry = 0; iow.addIO(skt->socket()); connected = false; } @@ -61,12 +62,63 @@ ncpDataCallback(bufferStore & a) cerr << "socketchan: Connect without name!!!\n"; } -const char *socketChan:: +char *socketChan:: getNcpConnectName() { return connectName; } +// NCP Command processing +bool socketChan:: +ncpCommand(bufferStore & a) +{ +cerr << "socketChan:: received NCP command (" << a << ")" << endl; + // str is guaranteed to begin with NCP$, and all NCP commands are + // greater than or equal to 8 characters in length. + const char *str = a.getString(); + // unsigned long len = a.getLen(); + bool ok = false; + + if (!strncmp(str+4, "INFO", 4)) { + // Send information discovered during the receipt of the + // NCON_MSG_NCP_INFO message. + a.init(); + switch (ncpProtocolVersion()) { + case PV_SERIES_3: + a.addStringT("Series 3"); + break; + case PV_SERIES_5: + a.addStringT("Series 5"); + break; + default: + cerr << "ncpd: protocol version not known" << endl; + a.addStringT("Unknown!"); + break; + } + skt->sendBufferStore(a); + ok = true; + } else if (!strncmp(str+4, "CONN", 4)) { + // Connect to a channel that was placed in 'pending' mode, by + // checking the channel table against the ID... + // DO ME LATER + ok = true; + } else if (!strncmp(str+4, "CHAL", 4)) { + // Challenge + // The idea is that the channel stays in 'secure' mode until a + // valid RESP is received + // DO ME LATER + ok = true; + } else if (!strncmp(str+4, "RESP", 4)) { + // Reponse - here is the plaintext as sent in the CHAL - the + // channel will only open up if this matches what ncpd has for + // the encrypted plaintext. + // DO ME LATER + ok = true; + } + return ok; +} + + void socketChan:: ncpConnectAck() { @@ -74,24 +126,77 @@ ncpConnectAck() a.addStringT("Ok"); skt->sendBufferStore(a); connected = true; + connectTry = 3; } void socketChan:: ncpConnectTerminate() { bufferStore a; + connectTry = 0; a.addStringT("Close"); skt->sendBufferStore(a); terminateWhenAsked(); } void socketChan:: +ncpRegisterAck() +{ + connectTry++; + ncpConnect(); +} + +void socketChan:: +ncpConnectNak() +{ + if (!connectName || (connectTry > 1)) + ncpConnectTerminate(); + else { + connectTry++; + ncpRegister(); + } +} + +void socketChan:: socketPoll() { if (connectName == 0) { bufferStore a; if (skt->getBufferStore(a, false) == 1) { + // A client has connected, and is announcing who it + // is... e.g. "SYS$RFSV.*" + // + // An NCP Channel can be in 'Control' or 'Data' mode. + // Initially, it is in 'Control' mode, and can accept + // certain commands. + // + // When a command is received that ncpd does not + // understand, this is assumed to be a request to + // connect to the remote service of that name, and enter + // 'data' mode. + // + // Later, there might be an explicit command to enter + // 'data' mode, and also a challenge-response protocol + // before any connection can be made. + // + // All commands begin with "NCP$". + + // There is a magic process name called "NCP$INFO.*" + // which is announced by the rfsvfactory. This causes a + // response to be issued containing the NCP version + // number. The rfsvfactory will create the correct type + // of RFSV protocol handler, which will then announce + // itself. So, first time in here, we might get the + // NCP$INFO.* + if (a.getLen() > 8 && !strncmp(a.getString(), "NCP$", 4)) { + if (!ncpCommand(a)) + cerr << "ncpd: command " << a << " unrecognised." << endl; + return; + } + + // This isn't a command, it's a remote process. Connect. connectName = strdup(a.getString()); + connectTry++; ncpConnect(); } } else if (connected) { |