Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save unicornsasfuel/557d4b4e978fc0c042fd9576dc04e64e to your computer and use it in GitHub Desktop.
Save unicornsasfuel/557d4b4e978fc0c042fd9576dc04e64e to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
int doprocessing (int sock);
int authtest(char *username, char *password);
int runcode();
void controlgate(int action);
int countlines(char *filename);
int runcode() {
/*
* Dead Code. Just a stub for now in case this is useful later.
*/
system("/opt/local/bin/secret");
}
#define RESPLINES 56
int authtest(char *username, char *password) {
FILE *fppass, *fpresp;
int randline;
char grampass[16] = "grampass.txt";
char gramresp[16] = "gramresp.txt";
char userpass[16];
char validpass[16];
char *response;
/* The only username allowed is "admin" */
if (strcmp(username, "admin") != 0) return 0;
strcpy(userpass, password);
/* Get the password for authentication from the file */
fppass = fopen(grampass, "r");
if (fppass == NULL) {
perror("Cannot open grampass file");
return 0;
}
if (fgets(validpass, sizeof(validpass), fppass)==NULL) {
perror("Cannot read from grampass file");
return 0;
}
fclose(fppass);
validpass[strlen(validpass)-1] = 0; /* Remove newline */
if (strcmp(userpass, validpass) == 0) {
/* Success */
return 1;
} else {
/* Return custom message, selected at random from gramresp file */
srand(time(NULL));
randline=rand()%countlines(gramresp);
fpresp = fopen(gramresp, "r");
if (fpresp == NULL) {
perror("Cannot open gramresp file");
return 0;
}
/*
* Allocate memory for response text, then skip to that line in the
* response file.
*/
response=malloc(128);
for (int i=0; i < randline; i++) {
fgets(response, 128, fpresp);
}
fclose(fpresp);
response[strlen(response)-1] = 0; /* Remove newline */
printf("ERR \"%s\"\n",response);
free(response);
return 0;
}
return 0;
}
int countlines(char *filename) {
FILE *fp;
unsigned int lines=0;
fp = fopen(filename, "r");
if (fp == NULL) {
return 0;
}
while (EOF != (fscanf(fp, "%*[^\n]"), fscanf(fp, "%*c"))) {
++lines;
}
fclose(fp);
return lines;
}
#define OPENGATE 1
#define CLOSEGATE 1
void controlgate(int action) {
FILE *gpio, *export, *direction;
export = fopen("/sys/class/gpio/export", "wb");
if (export != NULL) {
fwrite("11\n", 1, 3, export);
fclose(export);
}
direction = fopen("/sys/class/gpio/gpio11", "wb");
if (direction != NULL) {
fwrite("out\n", 1, 4, direction);
fclose(direction);
}
gpio = fopen("/sys/class/gpio/gpio11", "wb");
if (gpio != NULL) {
if (action == OPENGATE) {
fwrite("1\n", 1, 2, gpio);
} else {
fwrite("0\n", 1, 2, gpio);
fclose(gpio);
}
}
}
int doprocessing (int sock) {
int n, gotuser=0, gotpass=0;
char buffer[1024], strchr[2] = "\n\x00", *token;
char username[256], password[256];
memset(buffer, 0, 256);
chdir("/opt/local/sbin");
/* Send stdout and stderr to socket client */
dup2(sock, STDOUT_FILENO);
dup2(sock, STDERR_FILENO);
printf("OK GRAMGATE ready. Send USER command.\n"); fflush(stdout);
while(1) {
n = read(sock, buffer, 1024);
if (n < 0) {
perror("ERROR reading from socket");
return 0;
}
/* Tolkeinize the received string, parsing combined commands delineated with \n */
token = strtok(buffer, strchr);
while (token != NULL) {
/* Got everything we need, don't parse the rest of the buffer */
if (gotuser == 1 && gotpass == 1) {
break;
}
if (strncmp(token, "USER ", 5) == 0) {
strncpy(username, token+5, sizeof(username));
gotuser=1;
if (gotpass == 0) {
printf("OK Send PASS command.\n"); fflush(stdout);
}
} else if (strncmp(token, "PASS ", 5) == 0) {
strncpy(password, token+5, sizeof(password));
gotpass=1;
if (gotuser == 0) {
printf("OK Send USER command.\n"); fflush(stdout);
}
}
token = strtok(NULL, strchr);
}
if (gotuser==1 && gotpass==1) {
break;
}
}
if (authtest(username, password)) {
printf("OK Authentication Success. Send OPEN or CLOSE command.\n"); fflush(stdout);
n = read(sock, buffer, 1024);
if (n < 0) {
perror("ERROR reading from socket");
return 0;
}
if (strncmp(buffer, "OPEN", 4) == 0) {
controlgate(OPENGATE);
} else if (strncmp(buffer, "CLOSE", 5) == 0) {
controlgate(CLOSEGATE);
} else {
printf("ERR Command Unrecognized.\n"); fflush(stdout);
return 1;
}
} else {
printf("ERR Authentication Failed.\n"); fflush(stdout);
return 0;
}
return 0;
}
int main( int argc, char *argv[] ) {
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n, pid, sockyes=1;
/* First call to socket() function */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("ERROR opening socket");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockyes, sizeof(int)) == -1) {
perror("ERROR setting socket options");
exit(1);
}
/* Initialize socket structure */
memset((char *) &serv_addr, 0, sizeof(serv_addr));
portno = 5001;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
/* Now bind the host address using bind() call.*/
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("ERROR on binding");
exit(1);
}
/* Now start listening for the clients, here
* process will go in sleep mode and will wait
* for the incoming connection
*/
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) {
perror("ERROR on accept");
exit(1);
}
/* Create child process */
pid = fork();
if (pid < 0) {
perror("ERROR on fork");
exit(1);
}
if (pid == 0) {
/* This is the client process */
close(sockfd);
exit(doprocessing(newsockfd));
} else {
close(newsockfd);
}
} /* end of while */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment