mirror of
https://github.com/sigmasternchen/CShore
synced 2025-03-15 08:08:56 +00:00
added auth stuff to ctx + demo for authentication layer
This commit is contained in:
parent
f9670860df
commit
d89225b614
9 changed files with 138 additions and 9 deletions
2
Makefile
2
Makefile
|
@ -8,7 +8,7 @@ LIBARGO = libargo/libargo.a
|
|||
LIBPARCIVAL = libparcival/libparcival.a
|
||||
LIBS = $(CFLOOR_LIB) $(LIBARGO) $(LIBPARCIVAL)
|
||||
|
||||
OBJS = obj/router.o obj/request.o obj/base_cfloor.o obj/base_cgi.o
|
||||
OBJS = obj/router.o obj/request.o obj/base_cfloor.o obj/base_cgi.o obj/auth.o obj/base64.o
|
||||
DEPS = $(OBJS:%.o=%.d)
|
||||
|
||||
DEMO_OBJS = obj/demo.o obj/entities.tab.o obj/template.tab.o
|
||||
|
|
14
demo/demo.c
14
demo/demo.c
|
@ -1,5 +1,5 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <controller.h>
|
||||
|
||||
|
@ -18,6 +18,18 @@ response_t foobar(ctx_t ctx) {
|
|||
}
|
||||
|
||||
response_t authenticate(ctx_t ctx) {
|
||||
if (ctx.auth.type != BASIC) {
|
||||
return basicAuthResponse(401, "Protected Area");
|
||||
}
|
||||
|
||||
if (strcmp(ctx.auth.basic.user, "admin") != 0 ||
|
||||
strcmp(ctx.auth.basic.password, "password") != 0
|
||||
) {
|
||||
// username or password wrong
|
||||
return basicAuthResponse(401, "Protected Area");
|
||||
}
|
||||
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
|
|
65
src/auth.c
Normal file
65
src/auth.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <headers.h>
|
||||
|
||||
#include "auth.h"
|
||||
#include "base64.h"
|
||||
|
||||
struct auth getAuthData(struct headers* headers) {
|
||||
struct auth auth = {
|
||||
.type = NONE,
|
||||
.basic = {
|
||||
.user = NULL,
|
||||
.password = NULL,
|
||||
}
|
||||
};
|
||||
|
||||
const char* header = headers_get(headers, "Authorization");
|
||||
if (header == NULL) {
|
||||
// no auth header
|
||||
return auth;
|
||||
}
|
||||
|
||||
if (strncmp(header, "Basic ", 6) != 0) {
|
||||
// unsupported auth type
|
||||
return auth;
|
||||
}
|
||||
|
||||
header += 6;
|
||||
while (*header == ' ') header++;
|
||||
|
||||
char* decoded = base64_decode(header);
|
||||
if (decoded == NULL) {
|
||||
// unable to parse base64
|
||||
return auth;
|
||||
}
|
||||
|
||||
char* username = decoded;
|
||||
char* password = decoded;
|
||||
|
||||
while(*password != '\0' && *password != ':') password++;
|
||||
|
||||
if (*password == '\0') {
|
||||
free(decoded);
|
||||
// unable to parse credential string
|
||||
return auth;
|
||||
}
|
||||
*password = '\0';
|
||||
password++;
|
||||
|
||||
auth.type = BASIC;
|
||||
auth.basic.user = username;
|
||||
auth.basic.password = password;
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
|
||||
void freeAuthData(struct auth auth) {
|
||||
if (auth.basic.user != NULL)
|
||||
free(auth.basic.user);
|
||||
|
||||
// password should be freed with user;
|
||||
}
|
25
src/auth.h
Normal file
25
src/auth.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef AUTH_H_
|
||||
#define AUTH_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <headers.h>
|
||||
|
||||
enum authType {
|
||||
NONE,
|
||||
BASIC
|
||||
};
|
||||
|
||||
struct auth {
|
||||
enum authType type;
|
||||
struct {
|
||||
char* user;
|
||||
char* password;
|
||||
} basic;
|
||||
};
|
||||
|
||||
struct auth getAuthData(struct headers*);
|
||||
|
||||
void freeAuthData(struct auth);
|
||||
|
||||
#endif
|
|
@ -11,7 +11,7 @@ static unsigned char inverseTable[256];
|
|||
__attribute__((constructor)) static void buildInverseTable() {
|
||||
memset(inverseTable, 0x80, 256);
|
||||
|
||||
size_t tableLength = strlen(charTable);
|
||||
size_t tableLength = strlen((const char*) charTable);
|
||||
for (unsigned int i = 0; i < tableLength; i++) {
|
||||
inverseTable[charTable[i]] = i;
|
||||
}
|
||||
|
@ -52,10 +52,12 @@ char* base64_encode(const char* decoded) {
|
|||
return encoded;
|
||||
}
|
||||
|
||||
char* base64_decode(const char* encoded) {
|
||||
size_t length = strlen(encoded);
|
||||
char* base64_decode(const char* _encoded) {
|
||||
size_t length = strlen(_encoded);
|
||||
size_t count = 0;
|
||||
|
||||
unsigned const char* encoded = (unsigned char*) _encoded;
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
if (inverseTable[encoded[i]] != 0x80) {
|
||||
count++;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <logging.h>
|
||||
|
||||
#include "router.h"
|
||||
#include "auth.h"
|
||||
|
||||
struct networkingConfig netConfig;
|
||||
|
||||
|
@ -20,13 +21,16 @@ static void handler(struct request request, struct response _response) {
|
|||
path: request.metaData.path,
|
||||
queryString: request.metaData.queryString,
|
||||
peerAddr: request.peer.addr,
|
||||
peerPort: request.peer.port
|
||||
peerPort: request.peer.port,
|
||||
auth: getAuthData(request.headers)
|
||||
};
|
||||
|
||||
response_t response = routerHandler(ctx);
|
||||
if (response.output == NULL) {
|
||||
response = errorResponse(500, "route did not provide a reponse handler");
|
||||
}
|
||||
|
||||
freeAuthData(ctx.auth);
|
||||
|
||||
int fd = _response.sendHeader(response.status, &response.headers, &request);
|
||||
headers_free(&response.headers);
|
||||
|
|
|
@ -104,21 +104,24 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
// TODO use request headers
|
||||
|
||||
headers_free(&headers);
|
||||
|
||||
ctx_t ctx = {
|
||||
method: getMethod(or(getenv("REQUEST_METHOD"), "GET")),
|
||||
path: or(getenv("PATH_INFO"), "/"),
|
||||
queryString: or(getenv("QUERY_STRING"), ""),
|
||||
peerAddr: or(getenv("REMOTE_ADDR"), ""),
|
||||
peerPort: 0 // TODO
|
||||
peerPort: 0, // TODO
|
||||
auth: getAuthData(request.headers)
|
||||
};
|
||||
|
||||
headers_free(&headers);
|
||||
|
||||
response_t response = routerHandler(ctx);
|
||||
if (response.output == NULL) {
|
||||
response = errorResponse(500, "route did not provide a reponse handler");
|
||||
}
|
||||
|
||||
freeAuthData(ctx.auth);
|
||||
|
||||
printf("Status: %d\n\r", response.status);
|
||||
headers_dump(&response.headers, stdout);
|
||||
|
|
|
@ -258,3 +258,17 @@ response_t next() {
|
|||
response.status = NEXT_RESPONSE_STATUS;
|
||||
return response;
|
||||
}
|
||||
|
||||
response_t basicAuthResponse(int status, const char* realm) {
|
||||
response_t response = emptyResponse();
|
||||
response.status = status;
|
||||
response._userData = "";
|
||||
response.output = rawOutput;
|
||||
|
||||
size_t bufferLength = strlen(realm) + 14;
|
||||
char buffer[bufferLength + 1];
|
||||
snprintf(buffer, bufferLength + 1, "Basic realm=\"%s\"", realm);
|
||||
headers_mod(&response.headers, "WWW-Authenticate", buffer);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <headers.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "auth.h"
|
||||
|
||||
#define NEXT_RESPONSE_STATUS (0)
|
||||
|
||||
|
@ -16,6 +17,7 @@ typedef struct {
|
|||
const char* queryString;
|
||||
const char* peerAddr;
|
||||
int peerPort;
|
||||
struct auth auth;
|
||||
} ctx_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -37,6 +39,8 @@ response_t emptyResponse();
|
|||
|
||||
response_t next();
|
||||
|
||||
response_t basicAuthResponse(int status, const char* realm);
|
||||
|
||||
response_t statusResponse(int status, const char* message);
|
||||
response_t errorResponse(int status, const char* message);
|
||||
|
||||
|
|
Loading…
Reference in a new issue