mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 16:45:10 +00:00
[MOD] HMAC-based mediachecking
This commit is contained in:
parent
692cb8aa6f
commit
39cc04fc2e
6 changed files with 115 additions and 9 deletions
4
LICENSE
4
LICENSE
|
|
@ -1,5 +1,5 @@
|
||||||
For the files src/XML/*, tools/*, src/include/XML.h, etc/*, and Makefile, see COPYING.CC0
|
For the files src/Parsee/HMAC.c, src/XML/*, tools/*, src/include/XML.h, etc/*, and Makefile,
|
||||||
to be present.
|
see COPYING.CC0.
|
||||||
For any other file in src/, see COPYING.AGPL as the primary license.
|
For any other file in src/, see COPYING.AGPL as the primary license.
|
||||||
|
|
||||||
As Parsee depends on Cytoplasm, its license is left here in COPYING.CYTO
|
As Parsee depends on Cytoplasm, its license is left here in COPYING.CYTO
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ JoinMUC(ParseeData *data, HashMap *event, char *jid, char *muc, char *name)
|
||||||
while (!XMPPJoinMUC(data->jabber, jid, rev, true) && nonce < 32)
|
while (!XMPPJoinMUC(data->jabber, jid, rev, true) && nonce < 32)
|
||||||
{
|
{
|
||||||
char *nonce_str = StrInt(nonce);
|
char *nonce_str = StrInt(nonce);
|
||||||
char *input = StrConcat(4, sender, name, data->id, nonce_str);
|
char *input = StrConcat(3, sender, name, nonce_str);
|
||||||
char *hex = ParseeSHA256(input);
|
char *hex = ParseeHMACS(data->id, input);
|
||||||
|
|
||||||
if (strlen(hex) >= 8)
|
if (strlen(hex) >= 8)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
76
src/Parsee/HMAC.c
Normal file
76
src/Parsee/HMAC.c
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* CC0 implementation of a HMAC system based on Cytoplasm.
|
||||||
|
* Ignore the scary "Parsee.h", its practically unused. */
|
||||||
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Sha.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* A 64-byte key! */
|
||||||
|
static uint8_t *
|
||||||
|
ComputeKPad(char *key, uint8_t pad)
|
||||||
|
{
|
||||||
|
size_t klen;
|
||||||
|
uint8_t *kp;
|
||||||
|
uint8_t *kopad;
|
||||||
|
size_t i;
|
||||||
|
if ((klen = strlen(key)) <= 64)
|
||||||
|
{
|
||||||
|
kp = Malloc(klen * sizeof(uint8_t));
|
||||||
|
memcpy(kp, key, klen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kp = (uint8_t *) Sha256(key);
|
||||||
|
klen = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now that we have K', lets compute it XORd with opad */
|
||||||
|
kopad = Malloc(64 * sizeof(uint8_t));
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
uint8_t byte = i < klen ? kp[i] : 0x00;
|
||||||
|
kopad[i] = byte ^ pad;
|
||||||
|
}
|
||||||
|
|
||||||
|
Free(kp);
|
||||||
|
return kopad;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ParseeHMAC(char *key, uint8_t *msg, size_t msglen)
|
||||||
|
{
|
||||||
|
uint8_t *opad, *ipad;
|
||||||
|
uint8_t *innersha;
|
||||||
|
uint8_t *outer;
|
||||||
|
unsigned char *sha;
|
||||||
|
char *str;
|
||||||
|
if (!key || !msg || !msglen)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
opad = ComputeKPad(key, 0x5C);
|
||||||
|
|
||||||
|
ipad = ComputeKPad(key, 0x36);
|
||||||
|
ipad = Realloc(ipad, 64 + msglen);
|
||||||
|
memcpy(ipad + 64, msg, msglen);
|
||||||
|
innersha = Sha256Raw(ipad, 64 + msglen);
|
||||||
|
|
||||||
|
outer = Malloc(64 + 32);
|
||||||
|
memcpy(outer, opad, 64);
|
||||||
|
memcpy(outer + 64, innersha, 32);
|
||||||
|
|
||||||
|
sha = Sha256Raw(outer, 64 + 32);
|
||||||
|
str = ShaToHex(sha, HASH_SHA256);
|
||||||
|
|
||||||
|
Free(innersha);
|
||||||
|
Free(outer);
|
||||||
|
Free(ipad);
|
||||||
|
Free(opad);
|
||||||
|
Free(sha);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
@ -667,7 +667,8 @@ ParseeToUnauth(ParseeData *data, char *mxc)
|
||||||
{
|
{
|
||||||
Uri *url = NULL;
|
Uri *url = NULL;
|
||||||
char *ret;
|
char *ret;
|
||||||
#define PAT "%s/_matrix/client/v1/media/download/%s%s"
|
char *key, *hmac;
|
||||||
|
#define PAT "%s/_matrix/client/v1/media/download/%s%s?hmac=%s"
|
||||||
size_t l;
|
size_t l;
|
||||||
if (!data || !mxc)
|
if (!data || !mxc)
|
||||||
{
|
{
|
||||||
|
|
@ -684,18 +685,25 @@ ParseeToUnauth(ParseeData *data, char *mxc)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key = StrConcat(2, url->host, url->path);
|
||||||
|
hmac = ParseeHMACS(data->id, key);
|
||||||
|
Free(key);
|
||||||
|
|
||||||
l = snprintf(NULL, 0,
|
l = snprintf(NULL, 0,
|
||||||
PAT,
|
PAT,
|
||||||
data->config->media_base,
|
data->config->media_base,
|
||||||
url->host, url->path
|
url->host, url->path,
|
||||||
|
hmac
|
||||||
);
|
);
|
||||||
ret = Malloc(l + 3);
|
ret = Malloc(l + 3);
|
||||||
snprintf(ret, l + 1,
|
snprintf(ret, l + 1,
|
||||||
PAT,
|
PAT,
|
||||||
data->config->media_base,
|
data->config->media_base,
|
||||||
url->host, url->path
|
url->host, url->path,
|
||||||
|
hmac
|
||||||
);
|
);
|
||||||
UriFree(url);
|
UriFree(url);
|
||||||
|
Free(hmac);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,27 +2,41 @@
|
||||||
|
|
||||||
#include <Cytoplasm/Memory.h>
|
#include <Cytoplasm/Memory.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
|
||||||
#include <Matrix.h>
|
#include <Matrix.h>
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
#include <AS.h>
|
#include <AS.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
RouteHead(RouteMedia, arr, argp)
|
RouteHead(RouteMedia, arr, argp)
|
||||||
{
|
{
|
||||||
ParseeHttpArg *args = argp;
|
ParseeHttpArg *args = argp;
|
||||||
HttpClientContext *cctx;
|
HttpClientContext *cctx;
|
||||||
HashMap *reqh;
|
HashMap *reqh, *params;
|
||||||
char *server = ArrayGet(arr, 0);
|
char *server = ArrayGet(arr, 0);
|
||||||
char *identi = ArrayGet(arr, 1);
|
char *identi = ArrayGet(arr, 1);
|
||||||
char *path, *key, *val;
|
char *path, *key, *val;
|
||||||
|
char *hmac, *chkmak = NULL;
|
||||||
|
|
||||||
|
params = HttpRequestParams(args->ctx);
|
||||||
|
hmac = HashMapGet(params, "hmac");
|
||||||
|
|
||||||
/* TODO: Make it check the DB for its validicity. "Purging" would be useful.
|
/* TODO: Make it check the DB for its validicity. "Purging" would be useful.
|
||||||
*/
|
*/
|
||||||
if (!server || !identi)
|
|
||||||
{
|
{
|
||||||
|
char *concat = StrConcat(3, server, "/", identi);
|
||||||
|
chkmak = ParseeHMACS(args->data->id, concat);
|
||||||
|
Free(concat);
|
||||||
|
}
|
||||||
|
if (!server || !identi || !hmac || !StrEquals(hmac, chkmak))
|
||||||
|
{
|
||||||
|
Free(chkmak);
|
||||||
HttpResponseStatus(args->ctx, HTTP_BAD_REQUEST);
|
HttpResponseStatus(args->ctx, HTTP_BAD_REQUEST);
|
||||||
return MatrixCreateError("M_NOT_YET_UPLOADED", "No server/identifier");
|
return MatrixCreateError("M_NOT_YET_UPLOADED", "No server/identifier");
|
||||||
}
|
}
|
||||||
|
Free(chkmak);
|
||||||
|
|
||||||
server = HttpUrlEncode(server);
|
server = HttpUrlEncode(server);
|
||||||
identi = HttpUrlEncode(identi);
|
identi = HttpUrlEncode(identi);
|
||||||
|
|
|
||||||
|
|
@ -361,4 +361,12 @@ extern char * ParseeGenerateMTO(char *common_id);
|
||||||
* Modifies: the Parsee config */
|
* Modifies: the Parsee config */
|
||||||
extern void ParseeSetThreads(int xmpp, int http);
|
extern void ParseeSetThreads(int xmpp, int http);
|
||||||
|
|
||||||
|
/** Computes an HMAC (with SHA-256) with a known key, and a generic message.
|
||||||
|
* --------------
|
||||||
|
* Returns: a hex representation of the HMAC[HEAP].
|
||||||
|
* Thrasher: Free
|
||||||
|
* Modifies: NOTHING */
|
||||||
|
extern char * ParseeHMAC(char *key, uint8_t *msg, size_t msglen);
|
||||||
|
#define ParseeHMACS(key, msg) ParseeHMAC(key, (uint8_t *) msg, strlen(msg))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue