Created
December 16, 2016 02:44
-
-
Save unicornsasfuel/557d4b4e978fc0c042fd9576dc04e64e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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