Compare commits

..

No commits in common. "33edd2ceaf6885d38d68aba8c141aa817179a1f3" and "8612aae24c06ebecdae1c855df7e327de5b80091" have entirely different histories.

15 changed files with 36 additions and 408 deletions

View file

@ -1,62 +0,0 @@
{
"guard": "TELODENDRIA_KEY_UPLOAD_H",
"header": "Schema/KeyUpload.h",
"types": {
"DeviceKeys": {
"type": "struct",
"fields": {
"device_id": {
"type": "string",
"required": true
},
"user_id": {
"type": "string",
"required": true
},
"algorithms": {
"type": "[string]",
"required": true
},
"keys": {
"type": "{string}",
"required": true
},
"signatures": {
"//": "TODO: More complex j2s types.",
"//": "This is meant to be a map from user ID to ",
"//": "algo+device ID to a signature(string).",
"type": "object",
"required": true
}
}
},
"KeyResponse": {
"type": "struct",
"fields": {
"one_time_key_counts": {
"type": "{integer}",
"required": true
}
}
},
"KeyUploadRequest": {
"type": "struct",
"fields": {
"device_keys": {
"type": "DeviceKeys",
"required": false
},
"fallback_keys": {
"//": "This is a one-time key.",
"type": "object",
"required": false
},
"one_time_keys": {
"//": "This is a one-time key.",
"type": "object",
"required": false
}
}
}
}
}

View file

@ -38,10 +38,6 @@
"redacted_because": {
"type": "object",
"required": false
},
"transaction_id": {
"type": "string",
"required": false
}
}
},

View file

@ -68,7 +68,6 @@
"sender": { "type": "string", "required": true },
"state_key": { "type": "string" },
"redacts": { "type": "string" },
"_unsigned": { "type": "object" },
"type": { "type": "string", "required": true }
},
"type": "struct"
@ -106,9 +105,6 @@
},
"rooms": {
"type": "Rooms"
},
"device_one_time_keys_count": {
"type": "{integer}"
}
},
"type": "struct"

View file

@ -348,11 +348,6 @@ RoomEventFetch(Room *room, char *id, bool prev)
"pdu_status",
JsonValueDuplicate(HashMapGet(DbJson(event_ref), "status"))
));
JsonValueFree(HashMapSet(
unsign,
"transaction_id",
JsonValueDuplicate(HashMapGet(DbJson(event_ref), "transaction"))
));
ts = JsonValueAsInteger(HashMapGet(ret, "origin_server_ts"));
JsonValueFree(HashMapSet(
unsign,
@ -396,7 +391,7 @@ finish:
}
HashMap *
RoomEventCreate(char *sender, char *type, char *key, HashMap *c, char *txn)
RoomEventCreate(char *sender, char *type, char *key, HashMap *c)
{
HashMap *event;
if (!sender || !type || !c)
@ -408,7 +403,6 @@ RoomEventCreate(char *sender, char *type, char *key, HashMap *c, char *txn)
JsonSet(event, JsonValueObject(c), 1, "content");
JsonSet(event, JsonValueString(sender), 1, "sender");
JsonSet(event, JsonValueString(type), 1, "type");
JsonSet(event, JsonValueString(txn), 1, "transaction");
if (key)
{
JsonSet(event, JsonValueString(key), 1, "state_key");
@ -563,7 +557,7 @@ RoomSendInvite(User *sender, bool direct, char *user, Room *room)
content = HashMapCreate();
JsonSet(content, JsonValueBoolean(direct), 1, "is_direct");
JsonSet(content, JsonValueString("invite"), 1, "membership");
event = RoomEventCreate(senderStr, "m.room.member", user, content, NULL);
event = RoomEventCreate(senderStr, "m.room.member", user, content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);
@ -698,7 +692,7 @@ RoomLeave(Room *room, User *user, char **errp)
content = HashMapCreate();
JsonSet(content, JsonValueString("leave"), 1, "membership");
event = RoomEventCreate(userString, "m.room.member", userString, content, NULL);
event = RoomEventCreate(userString, "m.room.member", userString, content);
pdu = RoomEventSend(room, event, errp);
/* TODO: One ought to be extremely careful with managing users in those
@ -762,7 +756,7 @@ RoomRedact(Room *room, User *user, char *eventID, char *reason, char **errp)
HashMapSet(content, "reason", JsonValueString(reason));
event = RoomEventCreate(userString,
"m.room.redaction", NULL,
content, NULL
content
);
HashMapSet(event, "redacts", JsonValueString(eventID));
pdu = RoomEventSend(room, event, errp);
@ -817,7 +811,7 @@ RoomJoin(Room *room, User *user, char **errp)
content = HashMapCreate();
JsonSet(content, JsonValueString("join"), 1, "membership");
event = RoomEventCreate(userString, "m.room.member", userString, content, NULL);
event = RoomEventCreate(userString, "m.room.member", userString, content);
pdu = RoomEventSend(room, event, errp);
/* TODO: One ought to be extremely careful with managing users in those

View file

@ -97,7 +97,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
}
JsonValueFree(HashMapSet(content, key, JsonValueDuplicate(val)));
}
event = RoomEventCreate(sender_str, "m.room.create", "", content, NULL);
event = RoomEventCreate(sender_str, "m.room.create", "", content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);
UserAddJoin(user, room->id);
@ -105,7 +105,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
/* m.room.member */
content = HashMapCreate();
JsonSet(content, JsonValueString("join"), 1, "membership");
event = RoomEventCreate(sender_str, "m.room.member", sender_str, content, NULL);
event = RoomEventCreate(sender_str, "m.room.member", sender_str, content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);
@ -126,7 +126,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
}
HashMapSet(content, key, JsonValueDuplicate(val));
}
event = RoomEventCreate(sender_str, "m.room.power_levels", "", content, NULL);
event = RoomEventCreate(sender_str, "m.room.power_levels", "", content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);
@ -174,7 +174,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
, 1, a); \
event = RoomEventCreate( \
sender_str, \
"m.room." #p, "", content, NULL); \
"m.room." #p, "", content); \
JsonFree(RoomEventSend(room, event, NULL)); \
JsonFree(event); \
} \
@ -208,7 +208,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
{
content = HashMapCreate();
JsonSet(content, JsonValueString(req->name), 1, "name");
event = RoomEventCreate(sender_str, "m.room.name", "", content, NULL);
event = RoomEventCreate(sender_str, "m.room.name", "", content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);
}
@ -216,7 +216,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
{
content = HashMapCreate();
JsonSet(content, JsonValueString(req->topic), 1, "topic");
event = RoomEventCreate(sender_str, "m.room.topic", "", content, NULL);
event = RoomEventCreate(sender_str, "m.room.topic", "", content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);
}
@ -240,7 +240,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
JsonSet(content, JsonValueString(fullStr), 1, "alias");
event = RoomEventCreate(
sender_str,
"m.room.canonical_alias", "", content, NULL);
"m.room.canonical_alias", "", content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);
@ -270,7 +270,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
}
event = RoomEventCreate(sender_str, "m.room.power_levels", "", pl_content, NULL);
event = RoomEventCreate(sender_str, "m.room.power_levels", "", pl_content);
JsonFree(RoomEventSend(room, event, NULL));
JsonFree(event);

View file

@ -29,8 +29,6 @@ PopulateEventV1(Room * room, HashMap * event, PduV1 * pdu, ServerPart serv)
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "type")));
pdu->redacts =
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "redacts")));
pdu->_unsigned.transaction_id =
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "transaction")));
if (JsonGet(event, 1, "state_key"))
{
pdu->state_key =

View file

@ -242,11 +242,6 @@ RoomAddEventV1(Room *room, PduV1 pdu, PduV1Status status)
JsonValueArray(ArrayCreate()),
1, "next_events"
);
JsonSet(
DbJson(event_ref),
JsonValueString(pdu._unsigned.transaction_id),
1, "transaction"
);
DbUnlock(room->db, event_ref);
Free(safe_id);
@ -338,6 +333,13 @@ RoomAddEventV1(Room *room, PduV1 pdu, PduV1Status status)
/* If we have a membership change, then add it to the
* proper table. */
{
CommonID *id = UserIdParse(pdu.sender, NULL);
User *user = UserLockID(room->db, id);
UserPushEvent(user, pdu_json);
UserUnlock(user);
UserIdFree(id);
}
if (relates_to && RelationFromJson(relates_to, &rel, &errp))
{
DbRef *relate = DbLock(

View file

@ -298,7 +298,7 @@ ROUTE_IMPL(RouteKickRoom, path, argp)
membership = RoomEventCreate(
sender,
"m.room.member", kicked,
content, NULL
content
);
HashMapSet(content, "membership", JsonValueString(membershipState));

View file

@ -34,105 +34,8 @@
#include <Room.h>
#include <string.h>
#include <Schema/KeyUpload.h>
#include <Schema/Filter.h>
HashMap *
UploadKey(RouteArgs *args, User *user, KeyUploadRequest *req, char *sender)
{
char *deviceId = UserGetDeviceId(user);
KeyResponse response = { 0 };
HashMap *json;
char *fbKey;
JsonValue *fbValue;
size_t i;
if (!user || !req || !sender)
{
return NULL;
}
Log(LOG_ERR, "did=%s", deviceId);
if (req->device_keys.user_id)
{
HashMap *publicKeys;
char *pkTag, *pk;
/* We have device key information */
if (!StrEquals(req->device_keys.user_id, sender))
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
return MatrixErrorCreate(
M_UNAUTHORIZED, "Device key update has an invalid user ID"
);
}
if (!StrEquals(req->device_keys.device_id, deviceId))
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
return MatrixErrorCreate(
M_UNAUTHORIZED, "Device key update has an invalid device ID"
);
}
/* Check the public key list */
publicKeys = req->device_keys.keys;
i = 0;
while (HashMapIterateReentrant(publicKeys, &pkTag, (void **) &pk, &i))
{
char *pktDID = strchr(pkTag, ':');
/* Maybe C does need NULL saturation */
pktDID = pktDID ? pktDID + 1 : NULL;
if (!StrEquals(pktDID, deviceId))
{
/* As far as I know, we're not meant to handle other devices'
* public keys */
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
Log(LOG_ERR, "%s!=%s 1", pktDID, deviceId);
return MatrixErrorCreate(
M_UNAUTHORIZED, "Device key update has an invalid device ID"
);
}
}
UserSetDeviceKeys(user, &req->device_keys);
}
UserClearFallbackKeys(user);
i = 0;
while (HashMapIterateReentrant(req->fallback_keys, &fbKey, (void **) &fbValue, &i))
{
char *fbKID = strchr(fbKey, ':');
size_t len = fbKID ? fbKID - fbKey : 0;
char algo[len + 1];
memcpy(algo, fbKey, len);
algo[len] = '\0';
/* Maybe C does need NULL saturation */
fbKID = fbKID ? fbKID + 1 : NULL;
UserAddKey(user, fbKey, fbValue, true);
(void) fbKID;
}
i = 0;
while (HashMapIterateReentrant(req->one_time_keys, &fbKey, (void **) &fbValue, &i))
{
char *fbKID = strchr(fbKey, ':');
size_t len = fbKID ? fbKID - fbKey : 0;
char algo[len + 1];
memcpy(algo, fbKey, len);
algo[len] = '\0';
/* Maybe C does need NULL saturation */
fbKID = fbKID ? fbKID + 1 : NULL;
UserAddKey(user, fbKey, fbValue, false);
(void) fbKID;
}
response.one_time_key_counts = UserGetOnetimeCounts(user);
UserNotifyUser(UserGetName(user));
json = KeyResponseToJson(&response);
KeyResponseFree(&response);
return json;
}
ROUTE_IMPL(RouteKeyQuery, path, argp)
{
@ -142,14 +45,9 @@ ROUTE_IMPL(RouteKeyQuery, path, argp)
HashMap *request = NULL;
HashMap *response = NULL;
CommonID *id = NULL;
char *token = NULL;
User *user = NULL;
char *token = NULL;
char *serverName = NULL;
char *sender = NULL;
char *method = ArrayGet(path, 0);
char *err;
if (HttpRequestMethodGet(args->context) != HTTP_POST)
@ -173,11 +71,6 @@ ROUTE_IMPL(RouteKeyQuery, path, argp)
response = MatrixErrorCreate(M_UNKNOWN_TOKEN, NULL);
goto finish;
}
serverName = ConfigGetServerName(db);
id = UserIdParse(UserGetName(user), serverName);
id->sigil = '@';
sender = ParserRecomposeCommonID(*id);
request = JsonDecode(HttpServerStream(args->context));
if (!request)
{
@ -186,37 +79,10 @@ ROUTE_IMPL(RouteKeyQuery, path, argp)
goto finish;
}
if (StrEquals(method, "upload"))
{
KeyUploadRequest upload = { 0 };
if (!KeyUploadRequestFromJson(request, &upload, &err))
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_BAD_JSON, err);
goto finish;
}
if ((response = UploadKey(args, user, &upload, sender)))
{
KeyUploadRequestFree(&upload);
goto finish;
}
KeyUploadRequestFree(&upload);
}
else if (StrEquals(method, "query"))
{
/* TODO: Fetch a user's key information */
}
response = HashMapCreate();
(void) path;
finish:
JsonFree(request);
UserUnlock(user);
Free(serverName);
UserIdFree(id);
Free(sender);
return response;
}

View file

@ -122,7 +122,7 @@ ROUTE_IMPL(RouteSendEvent, path, argp)
goto finish;
}
event = RoomEventCreate(sender, eventType, NULL, JsonDuplicate(request), transId);
event = RoomEventCreate(sender, eventType, NULL, JsonDuplicate(request));
filled = RoomEventSend(room, event, &err);
JsonFree(event);
@ -266,7 +266,7 @@ ROUTE_IMPL(RouteSendState, path, argp)
event = RoomEventCreate(
sender,
eventType, stateKey ? stateKey : "",
JsonDuplicate(request), NULL
JsonDuplicate(request)
);
filled = RoomEventSend(room, event, &err);
JsonFree(event);

View file

@ -139,17 +139,12 @@ ROUTE_IMPL(RouteSync, path, argp)
/* TODO: I only am manually parsing this because j2s does not support
* a hashmap of unknown keys pointing to a known type. */
sync.rooms.invite = NULL;
sync.rooms.join = NULL;
sync.account_data.events = NULL;
sync.device_one_time_keys_count = UserGetOnetimeCounts(user);
sync.rooms.invite = HashMapCreate();
sync.rooms.join = HashMapCreate();
sync.account_data.events = ArrayCreate();
/* account data */
accountData = UserGetAccountDataSync(user, currBatch);
if (ArraySize(accountData) > 0)
{
sync.account_data.events = ArrayCreate();
}
for (i = 0; i < ArraySize(accountData); i++)
{
char *key = ArrayGet(accountData, i);
@ -163,10 +158,6 @@ ROUTE_IMPL(RouteSync, path, argp)
/* invites */
invites = UserGetInvites(user, currBatch);
if (ArraySize(invites) > 0)
{
sync.rooms.invite = HashMapCreate();
}
for (i = 0; i < ArraySize(invites); i++)
{
char *roomId = ArrayGet(invites, i);
@ -180,7 +171,7 @@ ROUTE_IMPL(RouteSync, path, argp)
invited = Malloc(sizeof(*invited));
memset(invited, 0, sizeof(*invited));
// TODO: Populate the invitestate
/* TODO: Populate the invitestate */
invited->invite_state.events = ArrayCreate();
HashMapSet(sync.rooms.invite, roomId, invited);
}
@ -188,12 +179,9 @@ ROUTE_IMPL(RouteSync, path, argp)
/* Joins */
joins = UserGetJoins(user, currBatch);
if (ArraySize(joins) > 0)
{
sync.rooms.join = HashMapCreate();
}
for (i = 0; i < ArraySize(joins); i++)
{
/* TODO: Rename these variables */
char *roomId = ArrayGet(joins, i);
JoinedRooms *joined;
char *firstEvent = NULL;
@ -242,8 +230,8 @@ ROUTE_IMPL(RouteSync, path, argp)
joined->timeline.prev_batch = UserNewMessageToken(
user, roomId, firstEvent
);
// TODO: Don't shove the entire state.
// That's a recipe for disaster, especially on large rooms.
/* TODO: Don't shove the entire state.
* That's a recipe for disaster, especially on large rooms. */
joined->state.events = ArrayCreate();
while (StateIterate(state, &type, &key, (void **) &id))
{
@ -265,13 +253,12 @@ ROUTE_IMPL(RouteSync, path, argp)
if (prevBatch)
{
/* TODO: Should we be dropping syncs? */
//UserDropSync(user, prevBatch);
UserDropSync(user, prevBatch);
nextBatch = UserInitSyncDiff(user);
}
sync.next_batch = nextBatch;
response = SyncResponseToJson(&sync);
SyncResponseFree(&sync);
(void) i;
finish:
FilterDestroy(filterData);
UserUnlock(user);

View file

@ -56,7 +56,7 @@ SendMembership(Db *db, User *user)
HashMap *content = HashMapCreate();
HashMap *membership = RoomEventCreate(
sender, "m.room.member", sender,
content, NULL
content
);
HashMapSet(content, "membership", JsonValueString("join"));

View file

@ -1387,8 +1387,6 @@ UserPushEvent(User *user, HashMap *event)
UserPushJoinSync(user, roomId);
/* TODO: In some very fun cases, this loop could be cosmically slow.
* Especially in the scale of 1.5k sync tokens. It can happen. */
entries = DbList(user->db, 3, "users", user->name, "sync");
for (i = 0; i < ArraySize(entries); i++)
{
@ -1535,7 +1533,6 @@ UserGetAccountDataSync(User *user, char *batch)
syncRef = DbLock(db, 4, "users", user->name, "sync", batch);
if (!syncRef)
{
Log(LOG_ERR, "Tried to get batch=%s (user=%s), but it's gone?", batch, user->deviceId);
return NULL;
}
@ -1861,7 +1858,7 @@ UserIsSyncOld(User *user, char *token)
dt = UtilTsMillis() - JsonValueAsInteger(HashMapGet(map, "creation"));
DbUnlock(user->db, ref);
return dt > (3 * 60 * 60 * 1000); /* Three hours of timeout. */
return dt > (3 * 24 * 60 * 60 * 1000); /* Three days of timeout. */
}
bool
UserSyncExists(User *user, char *sync)
@ -2156,125 +2153,3 @@ UserSetAccountData(User *user, char *key, HashMap *obj)
UserPushAccountData(user, key);
}
void
UserSetDeviceKeys(User *user, DeviceKeys *keys)
{
char *device;
HashMap *deviceObj;
if (!user || !keys)
{
return;
}
device = UserGetDeviceId(user);
deviceObj = JsonValueAsObject(HashMapGet(
UserGetDevices(user), device
));
if (!deviceObj)
{
return;
}
JsonValueFree(HashMapSet(deviceObj, "deviceKeys", JsonValueObject(DeviceKeysToJson(keys))));
}
void
UserClearFallbackKeys(User *user)
{
char *device;
HashMap *deviceObj;
if (!user)
{
return;
}
device = UserGetDeviceId(user);
deviceObj = JsonValueAsObject(HashMapGet(
UserGetDevices(user), device
));
if (!deviceObj)
{
return;
}
if (!HashMapGet(deviceObj, "oneTimeKeys"))
{
JsonValueFree(HashMapSet(deviceObj,
"oneTimeKeys", JsonValueObject(HashMapCreate())
));
}
JsonValueFree(HashMapSet(deviceObj,
"fallbackKeys", JsonValueObject(HashMapCreate())
));
}
void
UserAddKey(User *user, char *algo, JsonValue *key, bool fb)
{
char *device;
HashMap *deviceObj, *method;
if (!user || !algo || !key)
{
return;
}
device = UserGetDeviceId(user);
deviceObj = JsonValueAsObject(HashMapGet(
UserGetDevices(user), device
));
if (!deviceObj)
{
return;
}
method = JsonValueAsObject(HashMapGet(
deviceObj, fb ? "fallbackKeys" : "oneTimeKeys"
));
JsonValueFree(HashMapSet(method, algo, JsonValueDuplicate(key)));
}
HashMap *
UserGetOnetimeCounts(User *user)
{
char *device, *algoKey;
HashMap *deviceObj, *otk, *ret;
void *ignore;
if (!user)
{
return NULL;
}
device = UserGetDeviceId(user);
deviceObj = JsonValueAsObject(HashMapGet(
UserGetDevices(user), device
));
if (!deviceObj)
{
return NULL;
}
otk = JsonValueAsObject(HashMapGet(
deviceObj, "oneTimeKeys"
));
ret = HashMapCreate();
while (HashMapIterate(otk, &algoKey, &ignore))
{
char *algo = StrDuplicate(algoKey);
char *end = strchr(algo, ':');
int64_t *ptr;
if (end)
{
*end = '\0';
}
if (!(ptr = HashMapGet(ret, algo)))
{
ptr = Malloc(sizeof(*ptr));
*ptr = 0;
HashMapSet(ret, algo, ptr);
}
(*ptr)++;
Free(algo);
}
return ret;
}

View file

@ -195,7 +195,7 @@ extern bool RoomAddEventV1(Room *, PduV1, PduV1Status);
* Creates a barebones JSON object to be sent to
* .Fn RoomEventFetch .
*/
extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *, char *);
extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *);
/**
* Computes an approximation of the PDU depth by looking at

View file

@ -44,8 +44,6 @@
#include <Parser.h>
#include <Schema/KeyUpload.h>
#include <stdbool.h>
/**
@ -524,26 +522,4 @@ extern HashMap * UserGetAccountData(User *, char *);
* Replaces an account data entry.
*/
extern void UserSetAccountData(User *, char *, HashMap *);
/**
* Sets the device key list.
*/
extern void UserSetDeviceKeys(User *, DeviceKeys *);
/**
* Clears the fallback/one-time key list.
*/
extern void UserClearFallbackKeys(User *);
/**
* Adds a one-time/fallback key.
*/
extern void UserAddKey(User *, char *, JsonValue *, bool);
/**
* Generates a hashmap from algorithm to one-time key count as
* a pointer to the uint64_t.
* This is intended for /keys/upload. Please do not use this
* elsewhere */
extern HashMap * UserGetOnetimeCounts(User *);
#endif /* TELODENDRIA_USER_H */