error handling

buf fix
This commit is contained in:
oupson 2021-10-25 11:22:53 +02:00
parent eb2ee9e570
commit 8aad4d71cf
9 changed files with 177 additions and 99 deletions

View File

@ -2,8 +2,7 @@
all: lib/libauthunivorleans.so lib/libauthunivorleans.a bin/test all: lib/libauthunivorleans.so lib/libauthunivorleans.a bin/test
OPTIMISATION ?= 0 CFLAGS += -Iinclude $(DEFINES) `pkg-config --cflags libcurl` -fPIC -Wall -Werror
CFLAGS = -Iinclude $(DEFINES) `pkg-config --cflags libcurl` -fPIC -Wall -Werror
FLAGS = -g FLAGS = -g
@ -24,16 +23,16 @@ CC ?= $(CC)
obj/%.o: src/%.c obj/%.o: src/%.c
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) -c -O$(OPTIMISATION) -MMD -g -o $@ $< $(CFLAGS) $(FLAGS) $(CC) -c -MMD -o $@ $< $(CFLAGS) $(FLAGS)
lib/libauthunivorleans.so: obj/auth_univ_orleans.o obj/cookie_iterator.o lib/libauthunivorleans.so: obj/auth_univ_orleans.o obj/cookie_iterator.o obj/result.o
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) -fpic -shared -O$(OPTIMISATION) $(FLAGS) -flto -o $@ $^ `pkg-config --libs libcurl` `pkg-config --libs tidy` $(CC) -fpic -shared $(CFLAGS) $(FLAGS) -o $@ $^ `pkg-config --libs libcurl` `pkg-config --libs tidy`
lib/libauthunivorleans.a: obj/auth_univ_orleans.o obj/cookie_iterator.o lib/libauthunivorleans.a: obj/auth_univ_orleans.o obj/cookie_iterator.o obj/result.o
@mkdir -p $(@D) @mkdir -p $(@D)
$(AR) -cr $@ $^ $(AR) -cr $@ $^
bin/test: obj/test.o lib/libauthunivorleans.a bin/test: obj/test.o lib/libauthunivorleans.a
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) -g -O$(OPTIMISATION) -flto -o $@ $^ `pkg-config --libs libcurl` `pkg-config --libs tidy` $(CC) -o $@ $^ $(CFLAGS) `pkg-config --libs libcurl` `pkg-config --libs tidy`

View File

@ -1,9 +0,0 @@
#ifndef AUTH_UNIV_ORLEANS
#define AUTH_UNIV_ORLEANS
#include <cookie_iterator.h>
#include <curl/curl.h>
cookie_iterator_t *auth_univ_get_session_token(char *username, char *password);
int auth_univ_orleans_login(CURL *handle, char *username, char *password);
#endif

View File

@ -0,0 +1,10 @@
#ifndef AUTH_UNIV_ORLEANS
#define AUTH_UNIV_ORLEANS
#include <auth_univ_orleans/cookie_iterator.h>
#include <auth_univ_orleans/result.h>
#include <curl/curl.h>
result_t* auth_univ_get_session_token(char *username, char *password);
int auth_univ_orleans_login(CURL *handle, char *username, char *password);
#endif

View File

@ -0,0 +1,28 @@
#ifndef ERROR_H
#define ERROR_H
typedef struct result result_t;
#include <auth_univ_orleans/auth_univ_orleans.h>
enum result_type {
OK = 0,
ERR = 1,
};
union inner_result {
cookie_iterator_t *ok;
char *error;
};
struct result {
enum result_type type;
union inner_result inner;
};
enum result_type get_result_type(result_t *result);
cookie_iterator_t *get_result_ok(result_t *result);
const char *get_result_err(result_t *result);
void result_free(result_t *result);
#endif

View File

@ -1,93 +1,109 @@
#include <auth_univ_orleans.h> #include <auth_univ_orleans/auth_univ_orleans.h>
#include <cookie_iterator.h> #include <auth_univ_orleans/cookie_iterator.h>
#include <auth_univ_orleans/result.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <tidy/tidy.h> #include <tidy/tidy.h>
#include <tidy/tidybuffio.h> #include <tidy/tidybuffio.h>
int private_auth_univ_orleans_post_login(CURL *handle, char *lt, char *action, int __auth_univ_orleans_post_login(CURL *handle, char *lt, char *action,
char *username, char *password); char *username, char *password);
int private_auth_univ_orleans_get_action_and_lt(CURL *handle, char **lt, int __get_action_and_lt(CURL *handle, char **lt, char **action);
char **action);
size_t private_auth_univ_orleans_dumb_write_callback(void *data, size_t size, size_t __dumb_write_callback(void *data, size_t size, size_t nmemb,
size_t nmemb, void *userp) {
void *userp) {
return size * nmemb; return size * nmemb;
} }
uint private_auth_univ_orleans_tidy_buf_write_cb(char *in, uint size, size_t __tidy_buf_write_cb(void *in, size_t size, size_t nmemb, void *out) {
uint nmemb, TidyBuffer *out) { size_t r;
uint r;
r = size * nmemb; r = size * nmemb;
tidyBufAppend(out, in, r); tidyBufAppend((TidyBuffer *)out, in, r);
return r; return r;
} }
int private_auth_univ_orleans_get_action_and_lt_from_node(TidyDoc doc, int __get_action_and_lt_from_node(TidyDoc doc, TidyNode tnod, char **lt,
TidyNode tnod, char **action);
char **lt,
char **action);
cookie_iterator_t *auth_univ_get_session_token(char *username, char *password) { result_t *auth_univ_get_session_token(char *username, char *password) {
CURL *handle = curl_easy_init(); CURL *handle = curl_easy_init();
char errbuf[CURL_ERROR_SIZE]; char errbuf[CURL_ERROR_SIZE];
curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errbuf); curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errbuf);
curl_easy_setopt(handle, CURLOPT_TCP_KEEPALIVE, 1L);
/* set the error buffer as empty before performing a request */ /* set the error buffer as empty before performing a request */
errbuf[0] = 0; errbuf[0] = 0;
// curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 1L); // curl_easy_setopt(handle, CURLOPT_NOPROGRESS, 1L);
auth_univ_orleans_login(handle, username, password); int res = auth_univ_orleans_login(handle, username, password);
cookie_iterator_t *list = new_cookie_iterator_from_curl(handle); if (res == CURLE_OK) {
curl_easy_cleanup(handle); cookie_iterator_t *list = new_cookie_iterator_from_curl(handle);
return list; curl_easy_cleanup(handle);
struct result *res = (struct result *)calloc(1, sizeof(struct result));
res->type = OK;
res->inner.ok = list;
return res;
} else {
struct result *res = (struct result *)calloc(1, sizeof(struct result));
res->type = ERR;
res->inner.error = strdup(errbuf);
curl_easy_cleanup(handle);
return res;
}
} }
int auth_univ_orleans_login(CURL *handle, char *username, char *password) { int auth_univ_orleans_login(CURL *handle, char *username, char *password) {
int res = 0;
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(handle, CURLOPT_COOKIEFILE, ""); curl_easy_setopt(handle, CURLOPT_COOKIEFILE, "");
curl_easy_setopt(handle, CURLOPT_USERAGENT, curl_easy_setopt(handle, CURLOPT_USERAGENT,
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) " "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:93.0) "
"Gecko/20100101 Firefox/93.0"); "Gecko/20100101 Firefox/93.0");
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, __dumb_write_callback);
private_auth_univ_orleans_dumb_write_callback);
curl_easy_setopt(handle, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(handle, CURLOPT_URL, "https://ent.univ-orleans.fr/"); curl_easy_setopt(handle, CURLOPT_URL, "https://ent.univ-orleans.fr/");
curl_easy_perform(handle); res = curl_easy_perform(handle);
char *lt = NULL; if (res == CURLE_OK) {
char *action = NULL; char *lt = NULL;
private_auth_univ_orleans_get_action_and_lt(handle, &lt, &action); char *action = NULL;
res = __get_action_and_lt(handle, &lt, &action);
if (lt == NULL || action == NULL) { if (res == CURLE_OK) {
return 0; if (lt == NULL || action == NULL) {
return 0;
}
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,
__dumb_write_callback);
res = __auth_univ_orleans_post_login(handle, lt, action, username,
password);
free(lt);
free(action);
return res;
} else {
return res;
}
} else {
return res;
} }
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION,
private_auth_univ_orleans_dumb_write_callback);
private_auth_univ_orleans_post_login(handle, lt, action, username,
password);
free(lt);
free(action);
return 0; return 0;
} }
int private_auth_univ_orleans_get_action_and_lt(CURL *handle, char **lt, int __get_action_and_lt(CURL *handle, char **lt, char **action) {
char **action) {
TidyDoc tdoc; TidyDoc tdoc;
TidyBuffer docbuf = {0}; TidyBuffer docbuf = {0};
// TidyBuffer tidy_errbuf = {0}; // TidyBuffer tidy_errbuf = {0};
@ -98,8 +114,7 @@ int private_auth_univ_orleans_get_action_and_lt(CURL *handle, char **lt,
"https://auth.univ-orleans.fr/cas/login?service=https://" "https://auth.univ-orleans.fr/cas/login?service=https://"
"ent.univ-orleans.fr/uPortal/" "ent.univ-orleans.fr/uPortal/"
"Login%3FrefUrl%3D%2FuPortal%2Ff%2Faccueil%2Fnormal%2Frender.uPn"); "Login%3FrefUrl%3D%2FuPortal%2Ff%2Faccueil%2Fnormal%2Frender.uPn");
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, __tidy_buf_write_cb);
private_auth_univ_orleans_tidy_buf_write_cb);
tdoc = tidyCreate(); tdoc = tidyCreate();
tidyOptSetBool(tdoc, TidyShowWarnings, no); tidyOptSetBool(tdoc, TidyShowWarnings, no);
@ -110,22 +125,23 @@ int private_auth_univ_orleans_get_action_and_lt(CURL *handle, char **lt,
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &docbuf); curl_easy_setopt(handle, CURLOPT_WRITEDATA, &docbuf);
err = curl_easy_perform(handle); err = curl_easy_perform(handle);
if (!err) { if (err == CURLE_OK) {
err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */ err = tidyParseBuffer(tdoc, &docbuf);
/* parse the input */ // TODO ERROR
if (err >= 0) { if (err >= 0) {
private_auth_univ_orleans_get_action_and_lt_from_node( err = __get_action_and_lt_from_node(tdoc, tidyGetRoot(tdoc), lt,
tdoc, tidyGetRoot(tdoc), lt, action); /* walk the tree */ action); /* walk the tree */
} }
} }
tidyBufFree(&docbuf); tidyBufFree(&docbuf);
// tidyBufFree(&tidy_errbuf); // tidyBufFree(&tidy_errbuf);
tidyRelease(tdoc); tidyRelease(tdoc);
return 0; return err;
} }
int private_auth_univ_orleans_post_login(CURL *handle, char *lt, char *action, int __auth_univ_orleans_post_login(CURL *handle, char *lt, char *action,
char *username, char *password) { char *username, char *password) {
char form_data[256]; char form_data[256];
char *encoded_lt = curl_easy_escape(handle, lt, strlen(lt)); char *encoded_lt = curl_easy_escape(handle, lt, strlen(lt));
char *encoded_username = char *encoded_username =
@ -145,12 +161,12 @@ int private_auth_univ_orleans_post_login(CURL *handle, char *lt, char *action,
int action_size = strlen(action); int action_size = strlen(action);
char *url = (char *)calloc(28 + action_size + 1, sizeof(char)); char *url = (char *)calloc(28 + action_size + 1, sizeof(char));
strncpy(url, "https://auth.univ-orleans.fr", 29); memcpy(url, "https://auth.univ-orleans.fr", 29);
strncpy(url + 28, action, action_size); memcpy(url + 28, action, action_size);
curl_easy_setopt(handle, CURLOPT_URL, url); curl_easy_setopt(handle, CURLOPT_URL, url);
curl_easy_perform(handle); int res = curl_easy_perform(handle);
free(url); free(url);
@ -158,13 +174,11 @@ int private_auth_univ_orleans_post_login(CURL *handle, char *lt, char *action,
curl_free(encoded_username); curl_free(encoded_username);
curl_free(encoded_password); curl_free(encoded_password);
return 0; return res;
} }
int private_auth_univ_orleans_get_action_and_lt_from_node(TidyDoc doc, int __get_action_and_lt_from_node(TidyDoc doc, TidyNode tnod, char **lt,
TidyNode tnod, char **action) {
char **lt,
char **action) {
TidyNode child; TidyNode child;
for (child = tidyGetChild(tnod); child; child = tidyGetNext(child)) { for (child = tidyGetChild(tnod); child; child = tidyGetNext(child)) {
ctmbstr name = tidyNodeGetName(child); ctmbstr name = tidyNodeGetName(child);
@ -202,11 +216,10 @@ int private_auth_univ_orleans_get_action_and_lt_from_node(TidyDoc doc,
} }
if (*lt == NULL || *action == NULL) { if (*lt == NULL || *action == NULL) {
if (private_auth_univ_orleans_get_action_and_lt_from_node( if (__get_action_and_lt_from_node(doc, child, lt, action) == 0) {
doc, child, lt, action)) { return 0;
return 1;
} }
} }
} }
return *lt != NULL && *action != NULL; return (*lt != NULL && *action != NULL) ? 0 : -1;
} }

View File

@ -1,4 +1,4 @@
#include <cookie_iterator.h> #include <auth_univ_orleans/cookie_iterator.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -27,7 +27,10 @@ cookie_t *cookie_iterator_next(cookie_iterator_t *iterator) {
return NULL; return NULL;
} }
bool have_value = false;
if (iterator->current != NULL) { if (iterator->current != NULL) {
have_value = true;
char *data = iterator->current->data; char *data = iterator->current->data;
char buf[STR_BUF_SIZE]; char buf[STR_BUF_SIZE];
@ -112,11 +115,11 @@ cookie_t *cookie_iterator_next(cookie_iterator_t *iterator) {
i++; i++;
} }
iterator->cookie->value[i] = '\0'; iterator->cookie->value[i] = '\0';
iterator->current = iterator->current->next; iterator->current = iterator->current->next;
} }
return (iterator->current != NULL) ? iterator->cookie : NULL; return (have_value) ? iterator->cookie : NULL;
} }
void cookie_iterator_free(cookie_iterator_t *iterator) { void cookie_iterator_free(cookie_iterator_t *iterator) {

24
src/result.c Normal file
View File

@ -0,0 +1,24 @@
#include <auth_univ_orleans/cookie_iterator.h>
#include <auth_univ_orleans/result.h>
#include <stdlib.h>
enum result_type get_result_type(result_t *result) { return result->type; }
cookie_iterator_t *get_result_ok(result_t *result) { return result->inner.ok; }
const char *get_result_err(result_t *result) {
return result->inner.error;
}
void result_free(result_t *result) {
if (result->type == OK) {
if (result->inner.ok != NULL) {
cookie_iterator_free(result->inner.ok);
result->inner.ok = NULL;
}
} else {
free(result->inner.error);
result->inner.error = NULL;
}
free(result);
}

View File

@ -1,5 +1,5 @@
#include <auth_univ_orleans.h> #include <auth_univ_orleans/auth_univ_orleans.h>
#include <cookie_iterator.h> #include <auth_univ_orleans/cookie_iterator.h>
#include <stdlib.h> #include <stdlib.h>
int main(void) { int main(void) {
@ -11,21 +11,31 @@ int main(void) {
return -1; return -1;
} }
cookie_iterator_t *iter = auth_univ_get_session_token(username, password); result_t *res = auth_univ_get_session_token(username, password);
cookie_t *cookie;
while ((cookie = cookie_iterator_next(iter))) { if (get_result_type(res) == OK) {
printf("%s :\n"
"\thostname: %s\n" cookie_iterator_t *iter = get_result_ok(res);
"\tinclude subdomains : %d\n" cookie_t *cookie;
"\tpath : %s\n"
"\tsecure : %d\n" while ((cookie = cookie_iterator_next(iter))) {
"\texpire : %d\n" printf("%s :\n"
"\tvalue: %s\n", "\thostname: %s\n"
cookie_name(cookie), cookie_hostname(cookie), "\tinclude subdomains : %d\n"
cookie_include_subdomains(cookie), cookie_path(cookie), "\tpath : %s\n"
cookie_secure(cookie), cookie_expire(cookie), cookie_value(cookie)); "\tsecure : %d\n"
"\texpire : %d\n"
"\tvalue: %s\n",
cookie_name(cookie), cookie_hostname(cookie),
cookie_include_subdomains(cookie), cookie_path(cookie),
cookie_secure(cookie), cookie_expire(cookie),
cookie_value(cookie));
}
} else {
fprintf(stderr, "error : %s\n", get_result_err(res));
} }
cookie_iterator_free(iter); result_free(res);
} }