From: Patrick Date: Fri, 19 May 2023 22:02:34 +0000 (+0200) Subject: get Login example working with CURL X-Git-Url: https://gitweb.ps.run/matrix_esp_thesis/commitdiff_plain/71b13552379398dafcbc8fa8347d119a8984f448 get Login example working with CURL --- diff --git a/Makefile b/Makefile index d19abaa..f30f057 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,13 @@ CC=gcc C_OPTS=-Wall -Wextra -pedantic C_OPTS+=-I src/ C_OPTS+=-I ext/olm/include/ +C_OPTS+=-I ext/mjson/src C_OPTS+=src/matrix.c +C_OPTS+=src/matrix_http_curl.c +C_OPTS+=ext/mjson/src/mjson.c +C_OPTS+=-l curl -out/examples/%: examples/%.c +out/examples/%: examples/%.c src/* $(CC) -o out/examples/$* examples/$*.c $(C_OPTS) diff --git a/examples/Login.c b/examples/Login.c index 5f07e87..69ac3a1 100644 --- a/examples/Login.c +++ b/examples/Login.c @@ -1,27 +1,34 @@ #include #include +#include -#define SERVER FixedBuf("matrix.org") -#define USERNAME FixedBuf("@pscho:matrix.org") -#define PASSWORD FixedBuf("abcde") +#define SERVER "https://matrix.org" +#define USERNAME "pscho" +#define PASSWORD "Wc23EbmB9G3faMq" +#define DISPLAYNAME "MatrixClient" int -main( - int argc, - char **argv) +main() { MatrixClient client; - MatrixClientInit(&client, SERVER); + MatrixClientInit(&client, SERVER, strlen(SERVER)); + + curl_global_init(CURL_GLOBAL_DEFAULT); + client.httpUserData = (void *)curl_easy_init(); MatrixClientLoginPassword(&client, - USERNAME, - PASSWORD); + USERNAME, strlen(USERNAME), + PASSWORD, strlen(PASSWORD), + DISPLAYNAME, strlen(DISPLAYNAME)); - static char accessTokenCharBuffer[ACCESS_TOKEN_LEN]; - FixedBuffer accessTokenBuffer = { accessTokenCharBuffer, ACCESS_TOKEN_LEN, 0 }; - MatrixClientGetAccessToken(&client, &accessTokenBuffer); - printf("Access Token: %.*s\n", accessTokenBuffer.len, (char *)accessTokenBuffer.ptr); + printf("Access Token: %.*s\n", client.accessTokenLen, client.accessTokenBuffer); + printf("Device ID: %.*s\n", client.deviceIdLen, client.deviceIdBuffer); + printf("Expires in (ms): %.*s\n", client.expireMsLen, client.expireMsBuffer); + printf("Refresh Token: %.*s\n", client.refreshTokenLen, client.refreshTokenBuffer); + + curl_easy_cleanup((CURL *)client.httpUserData); + curl_global_cleanup(); return 0; } \ No newline at end of file diff --git a/src/matrix.c b/src/matrix.c index 082806a..90132af 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -1,27 +1,81 @@ #include "matrix.h" +#include + + +#define LOGIN_REQUEST_SIZE 1024 +#define LOGIN_RESPONSE_SIZE 1024 +#define LOGIN_URL "/_matrix/client/v3/login" + bool MatrixClientInit( MatrixClient * client, - FixedBuffer server + char * server, int serverLen ) { + strcpy_s( + client->server, + SERVER_SIZE, + server + ); + client->serverLen = serverLen; + return true; } +// https://spec.matrix.org/v1.6/client-server-api/#post_matrixclientv3login bool MatrixClientLoginPassword( MatrixClient * client, - FixedBuffer username, - FixedBuffer password + char * username, int usernameLen, + char * password, int passwordLen, + char * displayName, int displayNameLen ) { + static char requestBuffer[LOGIN_REQUEST_SIZE]; -} + int requestLen = + mjson_snprintf(requestBuffer, LOGIN_REQUEST_SIZE, + "{" + "\"type\": \"m.login.password\"," + "\"identifier\": {" + "\"type\": \"m.id.user\"," + "\"user\": \"%.*s\"" + "}," + "\"password\": \"%.*s\"," + "\"initial_device_display_name\": \"%.*s\"" + "}", + usernameLen, username, + passwordLen, password, + displayNameLen, displayName); + + static char responseBuffer[LOGIN_RESPONSE_SIZE]; + int responseLen; + bool result = + MatrixHttpPost(client, + LOGIN_URL, + requestBuffer, requestLen, + responseBuffer, LOGIN_RESPONSE_SIZE, &responseLen); + + if (!result) + return false; -bool -MatrixClientGetAccessToken( - MatrixClient * client, - FixedBuffer * outBuffer -) { + client->accessTokenLen = + mjson_get_string(responseBuffer, responseLen, + "$.access_token", + client->accessTokenBuffer, ACCESS_TOKEN_SIZE); + client->deviceIdLen = + mjson_get_string(responseBuffer, responseLen, + "$.device_id", + client->deviceIdBuffer, DEVICE_ID_SIZE); + client->expireMsLen = + mjson_get_string(responseBuffer, responseLen, + "$.expires_in_ms", + client->expireMsBuffer, EXPIRE_MS_SIZE); + client->refreshTokenLen = + mjson_get_string(responseBuffer, responseLen, + "$.refresh_token", + client->refreshTokenBuffer, REFRESH_TOKEN_SIZE); + return true; } + diff --git a/src/matrix.h b/src/matrix.h index 5f53e0e..d37474f 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -6,34 +6,48 @@ #include -#include "fixedbuffer.h" +// TODO: fix +#define SERVER_SIZE 20 +#define ACCESS_TOKEN_SIZE 40 +#define DEVICE_ID_SIZE 20 +#define EXPIRE_MS_SIZE 20 +#define REFRESH_TOKEN_SIZE 20 +#define MAX_URL_LEN 128 -#define ACCESS_TOKEN_LEN 20 // TODO: fix typedef struct MatrixClient { - OlmAccount * olmAcc; - char accessToken[ACCESS_TOKEN_LEN]; + void * httpUserData; + OlmAccount * olmAccount; + OlmSession * olmSession; + char server[SERVER_SIZE]; int serverLen; + char accessTokenBuffer[ACCESS_TOKEN_SIZE]; int accessTokenLen; + char deviceIdBuffer[DEVICE_ID_SIZE]; int deviceIdLen; + char expireMsBuffer[EXPIRE_MS_SIZE]; int expireMsLen; + char refreshTokenBuffer[REFRESH_TOKEN_SIZE]; int refreshTokenLen; } MatrixClient; bool MatrixClientInit( MatrixClient * client, - FixedBuffer server + char * server, int serverLen ); bool MatrixClientLoginPassword( MatrixClient * client, - FixedBuffer username, - FixedBuffer password + char * username, int usernameLen, + char * password, int passwordLen, + char * displayName, int displayNameLen ); bool -MatrixClientGetAccessToken( +MatrixHttpPost( MatrixClient * client, - FixedBuffer * outBuffer + const char * url, + char * requestBuffer, int requestLen, + char * outResponseBuffer, int outResponseCap, int * outResponseLen ); #endif diff --git a/src/matrix_http_curl.c b/src/matrix_http_curl.c new file mode 100644 index 0000000..577c5ec --- /dev/null +++ b/src/matrix_http_curl.c @@ -0,0 +1,113 @@ +#include "matrix.h" + +#include + + + +typedef struct { + char * ptr; + int cap; + int len; +} WriteStr; + +// typedef struct { +// Str str; +// size_t pos; +// } ReadStr; + +size_t curlWriteString(char *ptr, size_t size, size_t nmemb, void *userdata) { + WriteStr *writeStr = (WriteStr *)userdata; + + int toWrite = (int)size*nmemb; + + int writable = writeStr->cap - writeStr->len; + int gonnaWrite = writable < (toWrite) ? writable : (toWrite); + + for (int i = 0; i < gonnaWrite; i++) + { + int offset = writeStr->len; + writeStr->ptr[i+offset] = ptr[i]; + } + + writeStr->len += gonnaWrite; + + return gonnaWrite; +} +// size_t curlReadString(char *dst, size_t size, size_t nmemb, void *userdata) { +// ReadStr *readStr = (ReadStr *)userdata; + +// size_t copyAmount = size*nmemb; +// if (copyAmount > (readStr->str.len - readStr->pos)) { +// copyAmount = (readStr->str.len - readStr->pos); +// } + +// memcpy(dst, readStr->str.str + readStr->pos, copyAmount); +// readStr->pos += copyAmount; +// return copyAmount; +// } + +CURLcode +curlPerform(CURL *curl) { + // struct curl_slist *list = NULL; + // list = curl_slist_append(list, uTokenHeaderStr); + + // curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list); + + CURLcode result = curl_easy_perform(curl); + + // curl_slist_free_all(list); + + return result; +} + + + +bool +MatrixHttpPost( + MatrixClient * client, + const char * url, + char * requestBuffer, int requestLen, + char * outResponseBuffer, int outResponseCap, int * outResponseLen +) { + CURL *curl = (CURL *)client->httpUserData; + + CURLcode res; + + if(curl) { + int urlLen = strlen(url); + + char fullUrl[MAX_URL_LEN]; + for (int i = 0; i < client->serverLen; i++) + fullUrl[i] = client->server[i]; + for (int i = 0; i < urlLen; i++) + fullUrl[client->serverLen+i] = url[i]; + fullUrl[client->serverLen+urlLen] = '\0'; + curl_easy_setopt(curl, CURLOPT_URL, fullUrl); + + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBuffer); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestLen); + + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + + WriteStr writeStr = { + outResponseBuffer, + outResponseCap, + 0 + }; + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlWriteString); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &writeStr); + + res = curlPerform(curl); + + *outResponseLen = writeStr.len; + + if(res != CURLE_OK) + fprintf(stderr, "curl_easy_perform() failed: %s\n", + curl_easy_strerror(res)); + } + + + return res == CURLE_OK; +} \ No newline at end of file