Skip to content

Instantly share code, notes, and snippets.

@CanadianJeff
Created November 25, 2020 03:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CanadianJeff/9ca85aca75b768c3f7e2fed60f7d62e8 to your computer and use it in GitHub Desktop.
Save CanadianJeff/9ca85aca75b768c3f7e2fed60f7d62e8 to your computer and use it in GitHub Desktop.
/* the (*) in C code is a pointer */
/* the 2nd time you reference a pointer leave out the (*) */
/* to stop code at a location put raise(SIGINT); */
/* https://www.programiz.com/c-programming/c-pointers */
// getLine("] ", user_server_data, strlen(user_server_data));
#include <sys/types.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <inttypes.h>
#include <ctype.h> /* needed for isprint() function */
#include <time.h> /* needed for gettickrate() function */
#include <stdbool.h>
// #include <conio.h>
#ifndef WIN32
#include <netdb.h>
#endif
#include <fcntl.h>
#include <stdbool.h>
/* Program information for output, etc. */
#define PROG_NAME "Romulus Community Server"
#define PROG_URL "http://romulus.cc/server"
#define PROG_VERSION "1.0SVN"
#define BUFFSIZE 32
#define DATA_SEND 1
#define DATA_RECV 2
#define DATA_BUFF 3
#define DATA_PRE 4
#define DATA_POST 5
#define SERVERPASSWORD 0
#define SERVERKEY "LQHYTEFJQNAJXALKTSAZRWNZRYTPEUSSKFNPBCSDNHIHBROIMBDUNXOPSDENPFVENIZAIFZZUHIVNIZPPGTJLATCMPGUKMOARZKEYEELZXOJALBERUTKZJWSAANKHJMRSWHDCDFADRYZQPEKIDUVKRGOWKUYDQHXNMBARWKYVNUIQFUZDKLPRDXRZAGRABTYWCVGGOSNXPQRJXLCPLBXMMGZVKJKFKSHLTSGBXTUWGLZNEUFDYVBEZJGHIATFNB"
#define WELCOME "Welcome To Romulus Rom Manager Server Enjoy Your Stay"
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
int len;
int datadump;
bool SHOWHEX = true;
#include <signal.h>
char stdin_data[BUFFSIZE];
char stdout_data[BUFFSIZE];
char stderr_data[BUFFSIZE];
char user_server_data[BUFFSIZE];
void *GetTickCount(void)
{
/* Using unix timestamp as reference */
// fprintf(stderr, "Unix Timestamp: %u\n", (unsigned)time(NULL));
fprintf(stdout, "%u\r\n", (unsigned)time(NULL));
return OK;
}
bool startsWith(const char *pre, const char *str)
{
size_t lenpre = strlen(pre),
lenstr = strlen(str);
return lenstr < lenpre ? false : memcmp(pre, str, lenpre) == 0;
}
void *strip(char *buf)
{
char *x;
x = strchr(buf, '\n');
if (x) { *x='\0'; }
x = strchr(buf, '\r');
if (x) { *x='\0'; }
// exit (0);
return OK;
}
char *replace_char(char* str, char find, char replace){
char *current_pos = strchr(str,find);
while (current_pos){
*current_pos = replace;
current_pos = strchr(current_pos,find);
}
return str;
}
char *replaceWord(const char* s, const char* oldW, const char* newW)
{
char* result;
int i, cnt = 0;
int newWlen = strlen(newW);
int oldWlen = strlen(oldW);
// Counting the number of times old word
// occur in the string
for (i = 0; s[i] != '\0'; i++) {
if (strstr(&s[i], oldW) == &s[i]) {
cnt++;
// Jumping to index after the old word.
i += oldWlen - 1;
}
}
// Making new string of enough length
result = (char*)malloc(i + cnt * (newWlen - oldWlen) + 1);
i = 0;
while (*s) {
// compare the substring with the result
if (strstr(s, oldW) == s) {
strcpy(&result[i], newW);
i += newWlen;
s += oldWlen;
} else {
result[i++] = *s++;
}
}
result[i] = '\0';
return result;
}
#ifndef HEXDUMP_COLS
#define HEXDUMP_COLS 16
#endif
void *DumpHex(void *mem, unsigned int len, unsigned int datadump)
{
unsigned int i, j;
for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); i++)
{
/* print offset */
if(i % HEXDUMP_COLS == 0)
{
if (datadump == 1){fprintf(stderr, "Send: ");}
if (datadump == 2){fprintf(stderr, "Recv: ");}
if (datadump == 3){fprintf(stderr, "Buff: ");}
if (datadump == 4){fprintf(stderr, "Pre : ");}
if (datadump == 5){fprintf(stderr, "Post: ");}
fprintf(stderr, "0x%04x: ", i);
}
/* print hex data */
if(i < len)
{
fprintf(stderr, "%02x ", 0xFF & ((char*)mem)[i]);
}
else /* end of block, just aligning for ASCII dump */
{
fprintf(stderr, " ");
}
/* print ASCII dump */
if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1))
{
fprintf(stderr, "|");
for(j = i - (HEXDUMP_COLS - 1); j <= i; j++)
{
if(j >= len) /* end of block, not really printing */
{
fprintf(stderr, " ");
}
else if(isprint(((char*)mem)[j])) /* printable char */ /* warning: implicit declaration of function ‘isprint’ [-Wimplicit-function-declaration] */
{
// fprintf(stderr, "?");
fprintf(stderr, "%c", 0xFF & ((char*)mem)[j]);
}
else /* other char */
{
fprintf(stderr, ".");
}
}
fprintf(stderr, "|\n");
}
}
// fprintf(stderr, "\n");
return OK;
}
char *StringPadRight(char *string, int padded_len, char *pad){
int len = (int) strlen(string);
if (len >= padded_len) {
fprintf(stderr, "Padding Len Too Long Sending String Back To Input.\n");
return string;
}
int i;
for (i = 0; i < padded_len - len; i++) {
// fprintf(stderr, "Starting To Pad Input On String %s.\n", string);
strcat(string, pad);
}
fprintf(stderr, "Padding Success.\n");
return string;
}
void *resetsockets(void){
// fprintf(stderr, "Reseting Sockets\n");
// DumpHex(stdin_data, sizeof(stdin_data), DATA_PRE);
fflush(stdout);
fflush(stdin);
fflush(stderr);
int ch = 0;
memset(stdin_data, ch, sizeof(stdin_data));
// DumpHex(stdin_data, sizeof(stdin_data), DATA_POST);
// fprintf(stderr, "Reset Sockets\n");
// raise(SIGINT);
return OK;
}
void *senddata(char stdout_data[BUFFSIZE]){
resetsockets();
// fprintf(stderr, "Attempting To Send Data\n");
if (SHOWHEX == true){
DumpHex(stdout_data, strlen(stdout_data), DATA_SEND);
}
write(STDOUT_FILENO, stdout_data, strlen(stdout_data));
return OK; /* return success */
}
void *sendcrlf(){
senddata("\r\n");
return OK;
}
void *sendnullchar(){
senddata("0");
return OK;
}
void *getdata(char stdin_data[BUFFSIZE]){
/* Empty Buffers So We Can Get New Data */
resetsockets();
fprintf(stderr, "Requesting More Data From Client....\n");
sendcrlf();
read(STDIN_FILENO, stdin_data, BUFFSIZE);
if (SHOWHEX == true){
DumpHex(stdin_data, strlen(stdin_data), DATA_RECV);
}
return OK; /* return success */
}
// char *read_until_null(char data[100]){
// int i = 0;
// DumpHex(data, 100, DATA_BUFF);
// if (!startsWith == "0"){
// fprintf(stderr, "read_until_null returning something...\n");
// }
// return data;
// }
char *read_until_crlf(char data[100]){
int i = 0;
// char a = (char *) malloc(sizeof(char) * 1024);
if (strlen(data)){
// fprintf(stderr, "IN STRING: %s\n", a);
DumpHex(data, strlen(data), DATA_RECV);
// while (1){scanf("%c", &a[i]);if (a[i] == '\r'){break;}else{i++;}}
// while (1){scanf("%c", &a[i]);if (a[i] == '\n'){break;}else{i++;}}
// strip(a);
data[i] = '\0';
i = 0;
while (data[i] != '\0') {
fprintf(stderr, "%c", data[i]);
i++;
}
fprintf(stderr, "OUT STRING: %s\n", data);
free(data);
// getch();
// exit(0);
} else {
// fprintf(stderr, "read_until_crlf got 0 bytes\n");
}
fprintf(stderr, "read_until_crlf returning something...\n");
return data;
}
char *getClientKey(){
fprintf(stderr, "Starting Key Exchange With Connected Client.\n");
// fprintf(stderr, "Server Key Len: %d\n", sizeof(SERVERKEY));
senddata(SERVERKEY); /* KEY LEN IS 255 Bytes */
sendcrlf();
/* Get Client Key Here */
fprintf(stderr, "Get Client Key\n");
char *CLIENTKEY[24];
read(STDIN_FILENO, CLIENTKEY, sizeof(CLIENTKEY)); /* Client Key Is 24 Bytes */
// strip(stdin_data);
fprintf(stderr, "Key Exchange Done.\n");
return CLIENTKEY;
}
#include "libs/RomulusServer.h"
/* Keep Main As Small As Possible */
int main(void)
{
// char userinfo[100];
// char serverkeysize = 255;
// char clientkeysize = 24;
fprintf(stderr, "Main: New Connection.....\n");
getdata(stdin_data);
if (startsWith("RML_SRV", stdin_data)) /* 9 Bytes RML_SRV\r\n */
{
/* Tell Romulus We Are Here */
sendnullchar(); /* Null Byte */
// fprintf(stderr, "Sending CRLF\n");
sendcrlf();
fprintf(stderr, "Main: Check For Password String.\n");
/* read for 16 bytes and again until null byte */
/* if 2nd byte is null romulus not responding */
/* Romulus Client Should Limit Password Length */
read(STDIN_FILENO, stdin_data, 16);
DumpHex(stdin_data, 16, DATA_BUFF);
int loop = 0;
while (startsWith("00", stdin_data)){
fprintf(stderr, "Main: No Data Recieved.\n");
resetsockets();
read(STDIN_FILENO, stdin_data, 16);
DumpHex(stdin_data, 16, DATA_BUFF);
sleep(3);
/* Give User 3 Attempts To Send Data Here */
if (loop == 3){
fprintf(stderr, "Main: [Attempt #%d] Killing Connection....\n", loop);
exit(1);
} else {
fprintf(stderr, "Main: [Attempt #%d] Trying Again........\n", loop);
/* add to loop counter */
loop++;
}
}
fprintf(stderr, "Main: Got Data.\n");
if (startsWith("\r\n", stdin_data))
{
fprintf(stderr, "Main: No Password Has Been Sent From Client\n");
} else {
fprintf(stderr, "Main: Got Password From Client\n");
/* maybe combine these functions into 1???? */
// char *password = read_until_null(stdin_data);
/* Make Sure To utf8 encode here to stop exploits */
// utf8encode(password);
}
/* Get User Information */
/* max len of username is 25 */
/* max len of port is 5 */
/* max len of password can overflow the server */
/* total is about 62 bytes?????? */
// fprintf(stderr, "Main: Get User Information\n");
// read_until_null(STDIN_FILENO, userinfo, );
// getuserinfo();
// getdata(stdin_data);
// fprintf(stderr, "Main: Got User Information\n");
// DumpHex(userinfo, sizeof(userinfo), DATA_BUFF);
// char *userinfo = stdin_data;
// fprintf(stderr, "Got User Information: %s\n", userinfo);
/* Read For Password (If Set) */
// if (SERVERPASSWORD){
/* Get And UTF8 Decode On The Password String */
// }
/* Read For Nickname */
// fprintf(stderr, "Get Nickname\n");
// strip(stdin_data);
// DumpHex(stdin_data, sizeof(stdin_data), DATA_BUFF);
// fprintf(stderr, "Got Nickname %s\n", ClientNick);
/* Get Client IP From Binding Socket??? */
// clientip
/* Read For Client Port */
/* Convert String To Int */
// fprintf(stderr, "Get Client Port\n");
// strip(stdin_data);
// DumpHex(stdin_data, 16, DATA_BUFF);
// fprintf(stderr, "Got Client Port %s\n", ClientPort);
char *KEY[24];
char *CLIENTKEY = getClientKey(KEY[24]);
// char *CLIENTKEY = keyexchange(KEY[24]);
// DumpHex();
fprintf(stderr, "Main: CLIENT KEY IS %s\n", CLIENTKEY);
raise(SIGINT);
sendnullchar();
sendcrlf();
fprintf(stderr, "Main: User Processed!\n");
raise(SIGINT);
/* Client Should Now Be Connected And Data Flowing On Socket!!!! */
/* start looping to check for commands */
while (1){
// fprintf(stderr, "Possible Command Data On The Wire....\n");
/* Reset The Sockets So We Can Handle New Data!!!! */
resetsockets();
getdata(stdin_data);
/* Users Count ID */
if (startsWith("I\r\n", stdin_data)){
// fprintf(stderr, "Got I Command From Client\n");
GetTickCount(); /* Userlistid is based on epoch time */
}
/* Send Users List From Database???? */
else if (startsWith("U\r\n", stdin_data)){
// fprintf(stderr, "Got U Command From Client\n");
/* Get SQL DB Name Here */
/* Run SQL Query (SELECT * FROM Connections) */
/* do a for loop for each connection */
/* Format Is Username (seperator) IP (seperator) Port */
// fprintf(stderr, "Sending CRLF\n");
sendcrlf(); /* Requried */
}
/* Current Message ID */
/* Message List Count */
else if (startsWith("C\r\n", stdin_data)){
// fprintf(stderr, "Got C Command From Client\n");
/* Send Int To Str messageslist.count */
sendnullchar(); /* Null Byte */
}
else if (startsWith("W\r\n", stdin_data)){
// fprintf(stderr, "Got W Command From Client\n");
/* Send UTF8 Encoded Welcome Message */
senddata(WELCOME);
// fprintf(stderr, "Sending CRLF\n");
sendcrlf();
}
/* General Messages Response */
else if (startsWith("X\r\n", stdin_data)){
fprintf(stderr, "Got X Command From Client\n");
/* Read From STDIN */
/* Remove 1 From Messase Count??? */
/* utf8 encode and send message */
// senddata("This Is Just A Test Message????");
// sendcrlf();
}
/* General Message Entry */
else if (startsWith("M\r\n", stdin_data)){
fprintf(stderr, "Got M Command From Client\n");
/* utf8 decode and read from stdin */
/* ip = connection socket bind peer ip */
/* messagelist.Add (ip+seperator+stdin) */
// sendnullchar();
}
if (startsWith("0\r\n", stdin_data)){
fprintf(stderr, "Got NULL Byte From Client\n");
raise(SIGINT);
// fprintf(stderr, "Sending CRLF\n");
sendcrlf();
}
else {
/* Client Might Be Gone Or Have DCed By This Point */
// fprintf(stderr, "Unhandled Data\n");
fprintf(stderr, "\n\n");
DumpHex(stdin_data, 32, DATA_BUFF);
fprintf(stderr, "\n\n");
// fprintf(stderr, "Sending CRLF\n");
sendcrlf();
// fprintf(stderr, "Client Is Probley Gone So Bye Bye!! \n");
/* Shutting Down Server Because Client Is Gone */
// exit(1);
}
// fprintf(stderr, "Sleeping For 5 Seconds Before Checking Again\n");
sleep(5);
}
} else {
fprintf(stderr, "Not Romulus Exiting Program! \n");
exit(1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment