mirror of
https://github.com/sigmasternchen/CShore
synced 2025-03-15 16:18: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
|
LIBPARCIVAL = libparcival/libparcival.a
|
||||||
LIBS = $(CFLOOR_LIB) $(LIBARGO) $(LIBPARCIVAL)
|
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)
|
DEPS = $(OBJS:%.o=%.d)
|
||||||
|
|
||||||
DEMO_OBJS = obj/demo.o obj/entities.tab.o obj/template.tab.o
|
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 <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <controller.h>
|
#include <controller.h>
|
||||||
|
|
||||||
|
@ -18,6 +18,18 @@ response_t foobar(ctx_t ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
response_t authenticate(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();
|
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() {
|
__attribute__((constructor)) static void buildInverseTable() {
|
||||||
memset(inverseTable, 0x80, 256);
|
memset(inverseTable, 0x80, 256);
|
||||||
|
|
||||||
size_t tableLength = strlen(charTable);
|
size_t tableLength = strlen((const char*) charTable);
|
||||||
for (unsigned int i = 0; i < tableLength; i++) {
|
for (unsigned int i = 0; i < tableLength; i++) {
|
||||||
inverseTable[charTable[i]] = i;
|
inverseTable[charTable[i]] = i;
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,12 @@ char* base64_encode(const char* decoded) {
|
||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* base64_decode(const char* encoded) {
|
char* base64_decode(const char* _encoded) {
|
||||||
size_t length = strlen(encoded);
|
size_t length = strlen(_encoded);
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
|
unsigned const char* encoded = (unsigned char*) _encoded;
|
||||||
|
|
||||||
for (size_t i = 0; i < length; i++) {
|
for (size_t i = 0; i < length; i++) {
|
||||||
if (inverseTable[encoded[i]] != 0x80) {
|
if (inverseTable[encoded[i]] != 0x80) {
|
||||||
count++;
|
count++;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
|
||||||
#include "router.h"
|
#include "router.h"
|
||||||
|
#include "auth.h"
|
||||||
|
|
||||||
struct networkingConfig netConfig;
|
struct networkingConfig netConfig;
|
||||||
|
|
||||||
|
@ -20,13 +21,16 @@ static void handler(struct request request, struct response _response) {
|
||||||
path: request.metaData.path,
|
path: request.metaData.path,
|
||||||
queryString: request.metaData.queryString,
|
queryString: request.metaData.queryString,
|
||||||
peerAddr: request.peer.addr,
|
peerAddr: request.peer.addr,
|
||||||
peerPort: request.peer.port
|
peerPort: request.peer.port,
|
||||||
|
auth: getAuthData(request.headers)
|
||||||
};
|
};
|
||||||
|
|
||||||
response_t response = routerHandler(ctx);
|
response_t response = routerHandler(ctx);
|
||||||
if (response.output == NULL) {
|
if (response.output == NULL) {
|
||||||
response = errorResponse(500, "route did not provide a reponse handler");
|
response = errorResponse(500, "route did not provide a reponse handler");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeAuthData(ctx.auth);
|
||||||
|
|
||||||
int fd = _response.sendHeader(response.status, &response.headers, &request);
|
int fd = _response.sendHeader(response.status, &response.headers, &request);
|
||||||
headers_free(&response.headers);
|
headers_free(&response.headers);
|
||||||
|
|
|
@ -104,21 +104,24 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO use request headers
|
// TODO use request headers
|
||||||
|
|
||||||
headers_free(&headers);
|
|
||||||
|
|
||||||
ctx_t ctx = {
|
ctx_t ctx = {
|
||||||
method: getMethod(or(getenv("REQUEST_METHOD"), "GET")),
|
method: getMethod(or(getenv("REQUEST_METHOD"), "GET")),
|
||||||
path: or(getenv("PATH_INFO"), "/"),
|
path: or(getenv("PATH_INFO"), "/"),
|
||||||
queryString: or(getenv("QUERY_STRING"), ""),
|
queryString: or(getenv("QUERY_STRING"), ""),
|
||||||
peerAddr: or(getenv("REMOTE_ADDR"), ""),
|
peerAddr: or(getenv("REMOTE_ADDR"), ""),
|
||||||
peerPort: 0 // TODO
|
peerPort: 0, // TODO
|
||||||
|
auth: getAuthData(request.headers)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
headers_free(&headers);
|
||||||
|
|
||||||
response_t response = routerHandler(ctx);
|
response_t response = routerHandler(ctx);
|
||||||
if (response.output == NULL) {
|
if (response.output == NULL) {
|
||||||
response = errorResponse(500, "route did not provide a reponse handler");
|
response = errorResponse(500, "route did not provide a reponse handler");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeAuthData(ctx.auth);
|
||||||
|
|
||||||
printf("Status: %d\n\r", response.status);
|
printf("Status: %d\n\r", response.status);
|
||||||
headers_dump(&response.headers, stdout);
|
headers_dump(&response.headers, stdout);
|
||||||
|
|
|
@ -258,3 +258,17 @@ response_t next() {
|
||||||
response.status = NEXT_RESPONSE_STATUS;
|
response.status = NEXT_RESPONSE_STATUS;
|
||||||
return response;
|
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 <headers.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "auth.h"
|
||||||
|
|
||||||
#define NEXT_RESPONSE_STATUS (0)
|
#define NEXT_RESPONSE_STATUS (0)
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ typedef struct {
|
||||||
const char* queryString;
|
const char* queryString;
|
||||||
const char* peerAddr;
|
const char* peerAddr;
|
||||||
int peerPort;
|
int peerPort;
|
||||||
|
struct auth auth;
|
||||||
} ctx_t;
|
} ctx_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -37,6 +39,8 @@ response_t emptyResponse();
|
||||||
|
|
||||||
response_t next();
|
response_t next();
|
||||||
|
|
||||||
|
response_t basicAuthResponse(int status, const char* realm);
|
||||||
|
|
||||||
response_t statusResponse(int status, const char* message);
|
response_t statusResponse(int status, const char* message);
|
||||||
response_t errorResponse(int status, const char* message);
|
response_t errorResponse(int status, const char* message);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue