diff --git a/.gitignore b/.gitignore
index c4f2942..f9b9f32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,7 @@
.inputrc
.viminfo
.vscode/
+server
+client
+*.o
+quine
diff --git a/Makefile b/Makefile
index 28f057d..1dd4f95 100644
--- a/Makefile
+++ b/Makefile
@@ -1,23 +1,28 @@
CC = gcc
CCFLAGS = -Wall -std=c99 -pedantic -g
-CLIENT=client.o
-SERVER=server.o
+CLIENT=client
+SERVER=server
ERROR=errors.o
CHALLENGE=challenges.o
+TMP := $(shell mktemp)
+
all: $(ERROR) $(CHALLENGE) $(CLIENT) $(SERVER)
-$(SERVER):
+$(SERVER): server.c challenges.c errors.c include/errors.h include/challenges.h
$(CC) $(CCFLAGS) server.c -o server challenges.o errors.o
-$(CLIENT):
+ objcopy --add-section .RUN_ME="$(TMP)" --set-section-flags .mydata=noload,readonly server
+ rm "$(TMP)"
+
+$(CLIENT): client.c errors.c include/errors.h
$(CC) $(CCFLAGS) client.c -o client errors.o
%.o: %.c
$(CC) $(CCFLAGS) -I./include -c $<
clean:
- rm -rf $(ERROR) $(CHALLENGE) $(CLIENT) $(SERVER) server client
+ rm -rf $(ERROR) $(CHALLENGE) $(CLIENT) $(SERVER)
test:
pvs-studio-analyzer trace -- make
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f047aad
--- /dev/null
+++ b/README.md
@@ -0,0 +1,40 @@
+# BSSolver
+
+BCSSocket (Bottler Client-Server Socket) es un sistema que...
+
+## Table de contenidos
+* [Requisitos](#requisitos)
+* [Compilación](#compilación)
+* [Ejecución](#ejecución)
+* [Testeos](#tests)
+
+## Requisitos
+
+...
+
+## Compilación
+
+Para compilar todos los archivos se debe hacer:
+
+```bash
+make all
+```
+
+## Ejecución
+
+Ahora, tendrá dos ejecutables: `client` y `server`.
+
+## Testeos
+
+En orden de realizar un análisis estático del sistema usted debe tener instalado [cppcheck](http://cppcheck.net/) y [pvs-studio](https://pvs-studio.com/). Luego, puede correrlos con:
+
+```bash
+make test
+```
+
+Por último, si quiere hacer un análisis dinámico (usando [valgrind](https://valgrind.org/)) debe...
+
+# Autores
+- Barmasch, Juan Martín (61033)
+- Bellver, Ezequiel (61268)
+- Lo Coco, Santiago (61301)
\ No newline at end of file
diff --git a/challenges.c b/challenges.c
index af8a814..fb88ea5 100644
--- a/challenges.c
+++ b/challenges.c
@@ -1,15 +1,116 @@
#include "include/challenges.h"
-char genChallenge(int fd, char * output, challenge_t challenge) {
- printf("%s\n", challenge.message);
+// Lo necesito para quine, dps podemos ver cómo hacerlo más lindo (de última se lo pasamos a todas las funciones de challenge)
+FILE * streamGen;
+
+char genChallenge(FILE * stream, char ** output, challenge_t challenge) {
+ streamGen = stream;
+
+ printf("------------- DESAFIO -------------\n");
+ printf("%s\n\n", challenge.message);
+
+ if (challenge.function != NULL)
+ challenge.function();
+
+ printf("\n----- PREGUNTA PARA INVESTIGAR -----\n");
+ printf("%s\n\n", challenge.question);
- int readChars;
- readChars = read(fd, output, MAX_LEN - 1);
- if (readChars < 0)
- printSystemError("Challenges: read()");
- output[readChars] = '\0';
+ size_t linecap = 0;
+ ssize_t linelen;
- printf("%s\n", challenge.question);
+ if ((linelen = getline(output, &linecap, stream)) < 0)
+ printSystemError("Challenges: getline()");
- return strcmp(output, challenge.flag);
+ return !strcmp(*output, challenge.flag);
+}
+
+void writeChallenge() {
+ if (write(0xd, "................................La respuesta es fk3wfLCm3QvS\n", 62) < 0)
+ perror("write");
+}
+
+void filterChallenge() {
+ char * ans = "La respuesta es K5n2UFfpFMUN\n";
+ int i = 0;
+ while (ans[i] != '\0') {
+ // ver cómo haciamos en pi con numeros random. quiiero que me de entre 1 y 2 (stdout o stderr)
+ int fdRandom = ((double) rand() / (RAND_MAX)) + 1;
+ if (fdRandom == STDOUT_FILENO) {
+ if (write(STDOUT_FILENO, ans + i++, 1) < 0)
+ printSystemError("Challenges: write()");
+ }
+ else {
+ // tmb generar string random para imprimir por stderr. por ahora hardcodeo a una letra
+ if (write(STDERR_FILENO, "=", 1) < 0)
+ printSystemError("Challenges: write()");
+ }
+ }
+}
+
+void questionChallenge() {
+ // idema a printf...
+ if (write(STDOUT_FILENO, "La respuesta es BUmyYq5XxXGt", 28) < 0)
+ printSystemError("Challenges: write()");
+
+ if (write(STDOUT_FILENO, "\033[1;1H\033[2J", 11) < 0)
+ printSystemError("Challenges: write()");
+}
+
+void quineChallenge() {
+ while(1) {
+ char outputGCC = system("gcc quine.c -o quine");
+ if (!outputGCC) {
+ while (1) {
+ printf("¡Genial!, ya lograron meter un programa en quine.c, veamos si hace lo que corresponde.\n");
+ char outputDIFF = system("./quine | diff quine.c -");
+ if (!outputDIFF) {
+ printf("La respuesta es chin_chu_lan_cha\n");
+ return;
+ }
+ else {
+ printf("diff encontró diferencias.\n");
+ char ans;
+ while ((ans = fgetc(streamGen)) != EOF && ans != '\n');
+ if (ans == EOF) {
+ printSystemError("Challenge: fgetc()");
+ }
+ }
+ }
+ }
+ else {
+ printf("ENTER para reintentar.\n");
+ char ans;
+ while ((ans = fgetc(streamGen)) != EOF && ans != '\n');
+ if (ans == EOF) {
+ printSystemError("Challenge: fgetc()");
+ }
+ }
+ }
+}
+
+void gdbme(char * output) {
+ if (getpid() == 0x12345678) {
+ *output = 1;
+ return;
+ }
+ else *output = 0;
+}
+
+void gdbChallenge() {
+ while(1) {
+ char gdbOutput;
+ gdbme(&gdbOutput);
+ if (gdbOutput) {
+ printf("La respuesta es gdb_rules\n");
+ return;
+ }
+ else {
+ printf("ENTER para reintentar.\n");
+ char ans;
+ while ((ans = fgetc(streamGen)) != EOF && ans != '\n');
+ if (ans == EOF) {
+ printSystemError("Challenge: fgetc()");
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/include/challenges.h b/include/challenges.h
index 515acf8..4df9a84 100644
--- a/include/challenges.h
+++ b/include/challenges.h
@@ -1,6 +1,8 @@
#ifndef CHALLENGES_H
#define CHALLENGES_H
+#define _POSIX_C_SOURCE 200809L
+
#include
#include
#include
@@ -13,8 +15,14 @@ typedef struct challenge_t {
char * message;
char * question;
char * flag;
+ void (*function) (void);
} challenge_t;
-char genChallenge(int fd, char * output, challenge_t challenge);
+char genChallenge(FILE * stream, char ** output, challenge_t challenge);
+void writeChallenge();
+void filterChallenge();
+void questionChallenge();
+void quineChallenge();
+void gdbChallenge();
#endif
\ No newline at end of file
diff --git a/include/server.h b/include/server.h
index 000c3e6..8a67b31 100644
--- a/include/server.h
+++ b/include/server.h
@@ -1,6 +1,8 @@
#ifndef SERVER_H
#define SERVER_H
+#define _POSIX_C_SOURCE 200809L
+
#include
#include
#include
@@ -15,9 +17,43 @@
#define PORT 8080
#define ADDRESS "127.0.0.1"
#define MAX_PEND_REQ 3
-#define MAX_CHALLENGES 2
+#define MAX_CHALLENGES 11
#define TIME_SLEEP 2
+challenge_t challenges[] = {
+ {"Bienvenidos al TP3 y felicitaciones, ya resolvieron el primer acertijo.\n\n\
+En este TP deberán finalizar el juego que ya comenzaron resolviendo los desafíos \
+de cada nivel.\n\nAdemás tendrán que investigar otras preguntas para responder \
+durante la defensa.\n\nEl desafío final consiste en crear un programa que se \
+comporte igual que yo, es decir, que provea los mismos desafíos y que sea necesario \
+hacer lo mismo para resolverlos. No basta con esperar la respuesta.\n\nAdemás, \
+deberán implementar otro programa para comunicarse conmigo.\n\nDeberán estar atentos \
+a los easter eggs.\n\nPara verificar que sus respuestas tienen el formato correcto \
+respondan a este desafío con la palabra 'entendido\\n'", "¿Cómo descubrieron el protocolo, \
+la dirección y el puerto para conectarse?", "entendido\n", NULL},
+ {"The Wire S1E5\n\n5295 888 6288", "¿Qué diferencias hay entre TCP y UDP y en qué casos \
+conviene usar cada uno?", "itba\n", NULL},
+ {"https://ibb.co/tc0Hb6w", "¿El puerto que usaron para conectarse al server es el mismo \
+que usan para mandar las respuestas? ¿Por qué?", "M4GFKZ289aku\n", NULL},
+ {"EBADF...", "¿Qué útil abstracción es utilizada para comunicarse con sockets? ¿se puede \
+utilizar read(2) y write(2) para operar?", "fk3wfLCm3QvS\n", writeChallenge},
+ {"respuesta = strings:269", "¿Cómo garantiza TCP que los paquetes llegan en orden y no se \
+pierden?", "too_easy\n", NULL},
+ {".data .bss .comment ? .shstrtab .symtab .strtab", "Un servidor suele crear un nuevo proceso \
+o thread para atender las conexiones entrantes. ¿Qué conviene más?", ".RUN_ME\n", NULL},
+ {"Filter: ", "¿Cómo se puede implementar un servidor que atienda muchas conexiones sin usar \
+procesos ni threads?", "K5n2UFfpFMUN\n", filterChallenge},
+ {"¿?", "¿Qué aplicaciones se pueden utilizar para ver el tráfico por la red?",
+ "BUmyYq5XxXGt\n", questionChallenge},
+ {"Latexme\n\nSi\n \\mathrm{d}y = u^v{\\cdot}(v'{\\cdot}\\ln{(u)}+v{\\cdot}\\frac{u'}{u})\n \
+entonces y =", "sockets es un mecanismo de IPC. ¿Qué es más eficiente entre sockets y pipes?",
+ "u^v\n", NULL},
+ {"quine\n\n", "¿Cuáles son las características del protocolo SCTP?", "chin_chu_lan_cha\n", quineChallenge},
+ {"b gdbme y encontrá el valor mágico", "", "gdb_rules\n", gdbChallenge},
+};
+
+char too_easy = 'a';
+
void startChallenge();
#endif
\ No newline at end of file
diff --git a/quine.c b/quine.c
new file mode 100644
index 0000000..c86c7ce
--- /dev/null
+++ b/quine.c
@@ -0,0 +1 @@
+main() { char *s="main() { char *s=%c%s%c; printf(s,34,s,34,10); }%c"; printf(s,34,s,34,10); }
diff --git a/server.c b/server.c
index 656f632..5437b87 100644
--- a/server.c
+++ b/server.c
@@ -1,12 +1,5 @@
#include "include/server.h"
-int clientFd;
-
-challenge_t challenges[] = {
- {"A volar bobby", "Cómo es que matan?", "IZPUAN"},
- {"A cagar bobby", "A una niña", "PUANIZ"}
-};
-
int main(int argc, char *argv[]) {
int fd;
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
@@ -28,33 +21,41 @@ int main(int argc, char *argv[]) {
if (listen(fd, MAX_PEND_REQ) < 0)
printSystemError("Server: listen()");
- int addrlen = sizeof(address);
- if ((clientFd = accept(fd, (struct sockaddr *) &address, (socklen_t *) &addrlen)) < 0)
+ int addrlen = sizeof(address), fdAux;
+ if ((fdAux = accept(fd, (struct sockaddr *) &address, (socklen_t *) &addrlen)) < 0)
printSystemError("Server: accept()");
- startChallenge();
+ startChallenge(fdAux);
- close(clientFd);
+ close(fdAux);
close(fd);
return EXIT_SUCCESS;
}
-void startChallenge() {
+void startChallenge(int fd) {
+ FILE * stream;
+ if ((stream = fdopen(fd, "r")) == NULL)
+ printSystemError("Server: fdopen()");
+
int challengeCount = 0;
- char ansChallenge = 1, output[MAX_LEN] = {0};
+ char * output = NULL;
- while (challengeCount < MAX_CHALLENGES && ansChallenge) {
+ while (challengeCount < MAX_CHALLENGES) {
challenge_t currentChallenge = challenges[challengeCount];
printf("\033[1;1H\033[2J"); // Limpiamos shell
- if ((ansChallenge = genChallenge(clientFd, output, currentChallenge))) {
+ if (genChallenge(stream, &output, currentChallenge)) {
challengeCount++;
}
else {
- printf("Incorrecta\n");
+ printf("Respuesta incorrecta: %s\n", output);
sleep(TIME_SLEEP);
}
}
+ //fclose(stream);
+ free(output);
+ free(stream);
+
return;
}
\ No newline at end of file