abouttreesummaryrefslogcommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--examples/Login.c33
-rw-r--r--src/matrix.c72
-rw-r--r--src/matrix.h32
-rw-r--r--src/matrix_http_curl.c113
5 files changed, 224 insertions, 32 deletions
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 <stdio.h>
#include <matrix.h>
+#include <curl/curl.h>
-#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 <mjson.h>
+
+
+#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 <olm/olm.h>
-#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 <curl/curl.h>
+
+
+
+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