]> gitweb.ps.run Git - matrix_esp_thesis/commitdiff
get Login example working with CURL
authorPatrick <patrick.schoenberger@posteo.de>
Fri, 19 May 2023 22:02:34 +0000 (00:02 +0200)
committerPatrick <patrick.schoenberger@posteo.de>
Fri, 19 May 2023 22:02:34 +0000 (00:02 +0200)
Makefile
examples/Login.c
src/matrix.c
src/matrix.h
src/matrix_http_curl.c [new file with mode: 0644]

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