Added login page and fixed some bugs
This commit is contained in:
parent
92e7d1ed15
commit
8d3718c9ae
5
Makefile
5
Makefile
@ -3,7 +3,7 @@ SD ?= src
|
||||
LIBS_DIR ?= libs
|
||||
LIBS ?= $(wildcard $(LIBS_DIR)/*)
|
||||
|
||||
CGI_EXECS ?= view_comments.cgi
|
||||
CGI_EXECS ?= view_comments.cgi new_client.cgi
|
||||
EXEC_TARGETS := $(patsubst %.cgi,$(BD)/%.cgi,$(CGI_EXECS))
|
||||
|
||||
LDFLAGS ?= -L$(BD)/ -lcgic -lqments -lhiredis -ltomcrypt -luuid
|
||||
@ -27,13 +27,14 @@ $(BD)/libqments.a:
|
||||
cp $(LIBS_DIR)/qments/$(BD)/libqments.a $(BD)
|
||||
|
||||
$(BD)/%.cgi: $(BD)/%.o $(OBJ_FILES)
|
||||
mkdir -p $(@D)
|
||||
$(CC) $(INCLUDE_DIRS) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
||||
|
||||
$(BD)/%.o: $(SD)/%.c $(LIB_TARGETS)
|
||||
mkdir -p $(@D)
|
||||
$(CC) $(INCLUDE_DIRS) $(CFLAGS) -c $< -o $@ $(LDFLAGS)
|
||||
|
||||
all: $(BD)/$(CGI_EXECS)
|
||||
all: $(EXEC_TARGETS)
|
||||
|
||||
clean:
|
||||
rm -rfI $(BD)/
|
||||
|
@ -1,7 +1,7 @@
|
||||
#define RA_USER_MAX_LENGTH 64
|
||||
#define RA_PASSWORD_MAX_LENGTH 256
|
||||
|
||||
#define RA_SESSION_EXPIRY 86400
|
||||
#define RA_SESSION_EXPIRE 86400
|
||||
|
||||
#define RA_CONNECTION_TIMEOUT {1, 500000}
|
||||
#define RA_HOSTNAME "ra-socket"
|
||||
@ -16,3 +16,5 @@
|
||||
#define DRIVER_DATA { QMENTS_PATH }
|
||||
#define DRIVER unix_fs_driver
|
||||
|
||||
#define SESSION_COOKIE_NAME "thecookie"
|
||||
#define HOSTNAME "localhost"
|
||||
|
98
src/new_client.c
Normal file
98
src/new_client.c
Normal file
@ -0,0 +1,98 @@
|
||||
#include "cgic.h"
|
||||
#include "auth.h"
|
||||
#include "config.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define UUID_SIZE 36
|
||||
|
||||
/* TODO: place cookie normally */
|
||||
void
|
||||
validate_credentials()
|
||||
{
|
||||
char username[RA_USER_MAX_LENGTH + 1], password[RA_PASSWORD_MAX_LENGTH + 1];
|
||||
char session_id[UUID_SIZE];
|
||||
cgiFormResultType err;
|
||||
int auth;
|
||||
|
||||
err = cgiFormString("username", username, RA_USER_MAX_LENGTH + 1);
|
||||
if (err == cgiFormTruncated) {
|
||||
fprintf(cgiOut, "Username too long(max %d chars)\n", RA_USER_MAX_LENGTH);
|
||||
return;
|
||||
}
|
||||
if (err == cgiFormNotFound) {
|
||||
fprintf(cgiOut, "Username not provided\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = cgiFormString("password", password, RA_PASSWORD_MAX_LENGTH + 1);
|
||||
if (err == cgiFormTruncated) {
|
||||
fprintf(cgiOut, "Password too long(max %d+1(NUL) bytes)\n", RA_PASSWORD_MAX_LENGTH);
|
||||
return;
|
||||
}
|
||||
if (err == cgiFormNotFound) {
|
||||
fprintf(cgiOut, "Password not provided\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_valid_username(username)) {
|
||||
fprintf(cgiOut, "Username must be [A-Za-z0-9_]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_valid_password(password)) {
|
||||
fprintf(cgiOut, "Password must be a sequence of bytes in range 32-255\n");
|
||||
return;
|
||||
}
|
||||
|
||||
auth = authenticate(username, password, session_id);
|
||||
if (auth < 0) {
|
||||
fprintf(cgiOut, "Some error occured, contact system administrator\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (auth) {
|
||||
cgiHeaderCookieSet(SESSION_COOKIE_NAME, session_id, RA_SESSION_EXPIRE, "/", HOSTNAME, 0);
|
||||
fprintf(cgiOut, "You've successfully logged in as %s\n", username);
|
||||
} else {
|
||||
fprintf(cgiOut, "Failed to log in, check credentials\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
print_login_form()
|
||||
{
|
||||
fputs("<form action=\"\" method=\"POST\">\n"
|
||||
"<label>Username:</label>\n"
|
||||
"<input type=\"text\" name=\"username\"><br>\n"
|
||||
"<label>Password: </label>\n"
|
||||
"<input type=\"password\" name=\"password\"><br>\n"
|
||||
"<input type=\"submit\" name=\"login\" value=\"Submit\">\n"
|
||||
"</form>\n", cgiOut);
|
||||
}
|
||||
|
||||
int
|
||||
cgiMain()
|
||||
{
|
||||
cgiHeaderContentType("text/html");
|
||||
|
||||
fprintf(cgiOut, "<html>\n");
|
||||
|
||||
fprintf(cgiOut, "<head>\n");
|
||||
fprintf(cgiOut, "<title> Simple discuss powered by qments </title>\n");
|
||||
fprintf(cgiOut, "</head>\n");
|
||||
|
||||
fprintf(cgiOut, "<body>\n");
|
||||
|
||||
if (cgiFormSubmitClicked("login") == cgiFormSuccess) {
|
||||
validate_credentials();
|
||||
}
|
||||
|
||||
print_login_form();
|
||||
|
||||
fprintf(cgiOut, "</body>\n");
|
||||
|
||||
fprintf(cgiOut, "</html>\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
@ -105,7 +105,7 @@ authenticate(const char *username, const char *password, char *session_id)
|
||||
if (memcmp(db_hash, got_hash, SHA512_DIGEST_SIZE)) {
|
||||
FAIL_AUTH();
|
||||
} else {
|
||||
redisCommand(ctx, "GET session:%s", username);
|
||||
sid_reply = redisCommand(ctx, "GET session:%s", username);
|
||||
if (sid_reply->type != REDIS_REPLY_STRING) {
|
||||
/* assuming there is no session for this user */
|
||||
freeReplyObject(sid_reply);
|
||||
@ -115,11 +115,10 @@ authenticate(const char *username, const char *password, char *session_id)
|
||||
|
||||
sid_reply = redisCommand(ctx, "SET session:%s %s", username, session_id);
|
||||
freeReplyObject(sid_reply);
|
||||
|
||||
sid_reply = redisCommand(ctx, "EXPIRY session:%s %d", username, RA_SESSION_EXPIRY);
|
||||
} else {
|
||||
strcpy(session_id, sid_reply->str);
|
||||
}
|
||||
sid_reply = redisCommand(ctx, "EXPIRE session:%s %d", username, RA_SESSION_EXPIRE);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
@ -128,4 +127,5 @@ defer:
|
||||
freeReplyObject(salt_reply);
|
||||
freeReplyObject(hash_reply);
|
||||
freeReplyObject(sid_reply);
|
||||
return retval;
|
||||
}
|
||||
|
35
src/utils.c
35
src/utils.c
@ -1,15 +1,44 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "string_buffer.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define VALID_FOR_USERNAME(c) (isalpha(c) || c == '_')
|
||||
|
||||
int
|
||||
contain_special(const char *s)
|
||||
{
|
||||
return strchr(s, '&') || strchr(s, '"') || strchr(s, '\'') || strchr(s, '<') || strchr(s, '>');
|
||||
}
|
||||
|
||||
int
|
||||
is_valid_username(const char *s)
|
||||
{
|
||||
char c;
|
||||
while ((c = *s++)) {
|
||||
if (!VALID_FOR_USERNAME(c)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
is_valid_password(const char *s)
|
||||
{
|
||||
char c;
|
||||
unsigned char b;
|
||||
while ((c = *s++)) {
|
||||
b = (unsigned char) c;
|
||||
if (b < 32) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *
|
||||
mk_specialchars(const char *input)
|
||||
{
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
int contain_special(const char *s);
|
||||
|
||||
int is_valid_username(const char *s);
|
||||
int is_valid_password(const char *s);
|
||||
|
||||
char *mk_specialchars(const char *input);
|
||||
|
||||
#endif /* UTILS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user