summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/ActivityPubServerService.ts
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2024-07-20 21:33:20 +0900
committersyuilo <4439005+syuilo@users.noreply.github.com>2024-07-20 21:33:20 +0900
commit337b42bcb179bdfb993888ed94342a0158e8f3cb (patch)
treebd40424cf34c72b17effe19e5ce3cf866b3c6241 /packages/backend/src/server/ActivityPubServerService.ts
parentdocs(misskey-js): fix broken i-want-you image link in README.md (#14265) (diff)
downloadsharkey-337b42bcb179bdfb993888ed94342a0158e8f3cb.tar.gz
sharkey-337b42bcb179bdfb993888ed94342a0158e8f3cb.tar.bz2
sharkey-337b42bcb179bdfb993888ed94342a0158e8f3cb.zip
revert 5f88d56d96
バグがある(かつすぐに修正できそうにない) & まだレビュー途中で意図せずマージされたため
Diffstat (limited to 'packages/backend/src/server/ActivityPubServerService.ts')
-rw-r--r--packages/backend/src/server/ActivityPubServerService.ts87
1 files changed, 53 insertions, 34 deletions
diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts
index 753eaad047..3255d64621 100644
--- a/packages/backend/src/server/ActivityPubServerService.ts
+++ b/packages/backend/src/server/ActivityPubServerService.ts
@@ -3,10 +3,11 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
+import * as crypto from 'node:crypto';
import { IncomingMessage } from 'node:http';
import { Inject, Injectable } from '@nestjs/common';
import fastifyAccepts from '@fastify/accepts';
-import { verifyDigestHeader, parseRequestSignature } from '@misskey-dev/node-http-message-signatures';
+import httpSignature from '@peertube/http-signature';
import { Brackets, In, IsNull, LessThan, Not } from 'typeorm';
import accepts from 'accepts';
import vary from 'vary';
@@ -30,17 +31,12 @@ import { IActivity } from '@/core/activitypub/type.js';
import { isQuote, isRenote } from '@/misc/is-renote.js';
import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions, FastifyBodyParser } from 'fastify';
import type { FindOptionsWhere } from 'typeorm';
-import { LoggerService } from '@/core/LoggerService.js';
-import Logger from '@/logger.js';
const ACTIVITY_JSON = 'application/activity+json; charset=utf-8';
const LD_JSON = 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"; charset=utf-8';
@Injectable()
export class ActivityPubServerService {
- private logger: Logger;
- private inboxLogger: Logger;
-
constructor(
@Inject(DI.config)
private config: Config,
@@ -75,11 +71,8 @@ export class ActivityPubServerService {
private queueService: QueueService,
private userKeypairService: UserKeypairService,
private queryService: QueryService,
- private loggerService: LoggerService,
) {
//this.createServer = this.createServer.bind(this);
- this.logger = this.loggerService.getLogger('server-ap', 'gray');
- this.inboxLogger = this.logger.createSubLogger('inbox', 'gray');
}
@bindThis
@@ -107,44 +100,70 @@ export class ActivityPubServerService {
}
@bindThis
- private async inbox(request: FastifyRequest, reply: FastifyReply) {
- if (request.body == null) {
- this.inboxLogger.warn('request body is empty');
- reply.code(400);
+ private inbox(request: FastifyRequest, reply: FastifyReply) {
+ let signature;
+
+ try {
+ signature = httpSignature.parseRequest(request.raw, { 'headers': [] });
+ } catch (e) {
+ reply.code(401);
return;
}
- let signature: ReturnType<typeof parseRequestSignature>;
-
- const verifyDigest = await verifyDigestHeader(request.raw, request.rawBody || '', true);
- if (verifyDigest !== true) {
- this.inboxLogger.warn('digest verification failed');
+ if (signature.params.headers.indexOf('host') === -1
+ || request.headers.host !== this.config.host) {
+ // Host not specified or not match.
reply.code(401);
return;
}
- try {
- signature = parseRequestSignature(request.raw, {
- requiredInputs: {
- draft: ['(request-target)', 'digest', 'host', 'date'],
- },
- });
- } catch (err) {
- this.inboxLogger.warn('signature header parsing failed', { err });
+ if (signature.params.headers.indexOf('digest') === -1) {
+ // Digest not found.
+ reply.code(401);
+ } else {
+ const digest = request.headers.digest;
- if (typeof request.body === 'object' && 'signature' in request.body) {
- // LD SignatureがあればOK
- this.queueService.inbox(request.body as IActivity, null);
- reply.code(202);
+ if (typeof digest !== 'string') {
+ // Huh?
+ reply.code(401);
return;
}
- this.inboxLogger.warn('signature header parsing failed and LD signature not found');
- reply.code(401);
- return;
+ const re = /^([a-zA-Z0-9\-]+)=(.+)$/;
+ const match = digest.match(re);
+
+ if (match == null) {
+ // Invalid digest
+ reply.code(401);
+ return;
+ }
+
+ const algo = match[1].toUpperCase();
+ const digestValue = match[2];
+
+ if (algo !== 'SHA-256') {
+ // Unsupported digest algorithm
+ reply.code(401);
+ return;
+ }
+
+ if (request.rawBody == null) {
+ // Bad request
+ reply.code(400);
+ return;
+ }
+
+ const hash = crypto.createHash('sha256').update(request.rawBody).digest('base64');
+
+ if (hash !== digestValue) {
+ // Invalid digest
+ reply.code(401);
+ return;
+ }
}
this.queueService.inbox(request.body as IActivity, signature);
+
reply.code(202);
}
@@ -621,7 +640,7 @@ export class ActivityPubServerService {
if (this.userEntityService.isLocalUser(user)) {
reply.header('Cache-Control', 'public, max-age=180');
this.setResponseType(request, reply);
- return (this.apRendererService.addContext(this.apRendererService.renderKey(user, keypair.publicKey)));
+ return (this.apRendererService.addContext(this.apRendererService.renderKey(user, keypair)));
} else {
reply.code(400);
return;