diff options
Diffstat (limited to 'src/service/messenger/messenger_api_message.c')
-rw-r--r-- | src/service/messenger/messenger_api_message.c | 1149 |
1 files changed, 1149 insertions, 0 deletions
diff --git a/src/service/messenger/messenger_api_message.c b/src/service/messenger/messenger_api_message.c new file mode 100644 index 000000000..f77d171f6 --- /dev/null +++ b/src/service/messenger/messenger_api_message.c | |||
@@ -0,0 +1,1149 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2023 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_message.c | ||
23 | * @brief messenger api: client and service implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "platform.h" | ||
27 | #include "messenger_api_message.h" | ||
28 | |||
29 | struct GNUNET_MESSENGER_MessageSignature | ||
30 | { | ||
31 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
32 | struct GNUNET_HashCode hash; | ||
33 | }; | ||
34 | |||
35 | struct GNUNET_MESSENGER_ShortMessage | ||
36 | { | ||
37 | enum GNUNET_MESSENGER_MessageKind kind; | ||
38 | struct GNUNET_MESSENGER_MessageBody body; | ||
39 | }; | ||
40 | |||
41 | struct GNUNET_MESSENGER_Message* | ||
42 | create_message (enum GNUNET_MESSENGER_MessageKind kind) | ||
43 | { | ||
44 | struct GNUNET_MESSENGER_Message *message = GNUNET_new (struct | ||
45 | GNUNET_MESSENGER_Message); | ||
46 | |||
47 | message->header.kind = kind; | ||
48 | |||
49 | switch (message->header.kind) | ||
50 | { | ||
51 | case GNUNET_MESSENGER_KIND_NAME: | ||
52 | message->body.name.name = NULL; | ||
53 | break; | ||
54 | case GNUNET_MESSENGER_KIND_TEXT: | ||
55 | message->body.text.text = NULL; | ||
56 | break; | ||
57 | case GNUNET_MESSENGER_KIND_FILE: | ||
58 | message->body.file.uri = NULL; | ||
59 | break; | ||
60 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
61 | message->body.privacy.length = 0; | ||
62 | message->body.privacy.data = NULL; | ||
63 | break; | ||
64 | default: | ||
65 | break; | ||
66 | } | ||
67 | |||
68 | return message; | ||
69 | } | ||
70 | |||
71 | |||
72 | struct GNUNET_MESSENGER_Message* | ||
73 | copy_message (const struct GNUNET_MESSENGER_Message *message) | ||
74 | { | ||
75 | GNUNET_assert (message); | ||
76 | |||
77 | struct GNUNET_MESSENGER_Message *copy = GNUNET_new (struct | ||
78 | GNUNET_MESSENGER_Message); | ||
79 | |||
80 | GNUNET_memcpy (copy, message, sizeof(struct GNUNET_MESSENGER_Message)); | ||
81 | |||
82 | switch (message->header.kind) | ||
83 | { | ||
84 | case GNUNET_MESSENGER_KIND_NAME: | ||
85 | copy->body.name.name = GNUNET_strdup (message->body.name.name); | ||
86 | break; | ||
87 | case GNUNET_MESSENGER_KIND_TEXT: | ||
88 | copy->body.text.text = GNUNET_strdup (message->body.text.text); | ||
89 | break; | ||
90 | case GNUNET_MESSENGER_KIND_FILE: | ||
91 | copy->body.file.uri = GNUNET_strdup (message->body.file.uri); | ||
92 | break; | ||
93 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
94 | copy->body.privacy.data = copy->body.privacy.length ? GNUNET_malloc ( | ||
95 | copy->body.privacy.length) : NULL; | ||
96 | |||
97 | if (copy->body.privacy.data) | ||
98 | { | ||
99 | GNUNET_memcpy (copy->body.privacy.data, message->body.privacy.data, | ||
100 | copy->body.privacy.length); | ||
101 | } | ||
102 | |||
103 | break; | ||
104 | default: | ||
105 | break; | ||
106 | } | ||
107 | |||
108 | return copy; | ||
109 | } | ||
110 | |||
111 | |||
112 | static void | ||
113 | destroy_message_body (enum GNUNET_MESSENGER_MessageKind kind, | ||
114 | struct GNUNET_MESSENGER_MessageBody *body) | ||
115 | { | ||
116 | switch (kind) | ||
117 | { | ||
118 | case GNUNET_MESSENGER_KIND_NAME: | ||
119 | GNUNET_free (body->name.name); | ||
120 | break; | ||
121 | case GNUNET_MESSENGER_KIND_TEXT: | ||
122 | GNUNET_free (body->text.text); | ||
123 | break; | ||
124 | case GNUNET_MESSENGER_KIND_FILE: | ||
125 | GNUNET_free (body->file.uri); | ||
126 | break; | ||
127 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
128 | GNUNET_free (body->privacy.data); | ||
129 | break; | ||
130 | default: | ||
131 | break; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | |||
136 | void | ||
137 | cleanup_message (struct GNUNET_MESSENGER_Message *message) | ||
138 | { | ||
139 | GNUNET_assert (message); | ||
140 | |||
141 | destroy_message_body (message->header.kind, &(message->body)); | ||
142 | } | ||
143 | |||
144 | |||
145 | void | ||
146 | destroy_message (struct GNUNET_MESSENGER_Message *message) | ||
147 | { | ||
148 | GNUNET_assert (message); | ||
149 | |||
150 | destroy_message_body (message->header.kind, &(message->body)); | ||
151 | |||
152 | GNUNET_free (message); | ||
153 | } | ||
154 | |||
155 | |||
156 | int | ||
157 | is_message_session_bound (const struct GNUNET_MESSENGER_Message *message) | ||
158 | { | ||
159 | GNUNET_assert (message); | ||
160 | |||
161 | if ((GNUNET_MESSENGER_KIND_JOIN == message->header.kind) || | ||
162 | (GNUNET_MESSENGER_KIND_LEAVE == message->header.kind) || | ||
163 | (GNUNET_MESSENGER_KIND_NAME == message->header.kind) || | ||
164 | (GNUNET_MESSENGER_KIND_KEY == message->header.kind) || | ||
165 | (GNUNET_MESSENGER_KIND_ID == message->header.kind)) | ||
166 | return GNUNET_YES; | ||
167 | else | ||
168 | return GNUNET_NO; | ||
169 | } | ||
170 | |||
171 | |||
172 | static void | ||
173 | fold_short_message (const struct GNUNET_MESSENGER_Message *message, | ||
174 | struct GNUNET_MESSENGER_ShortMessage *shortened) | ||
175 | { | ||
176 | shortened->kind = message->header.kind; | ||
177 | |||
178 | GNUNET_memcpy (&(shortened->body), &(message->body), sizeof(struct | ||
179 | GNUNET_MESSENGER_MessageBody)); | ||
180 | } | ||
181 | |||
182 | |||
183 | static void | ||
184 | unfold_short_message (struct GNUNET_MESSENGER_ShortMessage *shortened, | ||
185 | struct GNUNET_MESSENGER_Message *message) | ||
186 | { | ||
187 | destroy_message_body (message->header.kind, &(message->body)); | ||
188 | |||
189 | message->header.kind = shortened->kind; | ||
190 | |||
191 | GNUNET_memcpy (&(message->body), &(shortened->body), sizeof(struct | ||
192 | GNUNET_MESSENGER_MessageBody)); | ||
193 | } | ||
194 | |||
195 | |||
196 | #define member_size(type, member) sizeof(((type*) NULL)->member) | ||
197 | |||
198 | static uint16_t | ||
199 | get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind) | ||
200 | { | ||
201 | uint16_t length = 0; | ||
202 | |||
203 | switch (kind) | ||
204 | { | ||
205 | case GNUNET_MESSENGER_KIND_INFO: | ||
206 | length += member_size (struct GNUNET_MESSENGER_Message, | ||
207 | body.info.messenger_version); | ||
208 | break; | ||
209 | case GNUNET_MESSENGER_KIND_PEER: | ||
210 | length += member_size (struct GNUNET_MESSENGER_Message, body.peer.peer); | ||
211 | break; | ||
212 | case GNUNET_MESSENGER_KIND_ID: | ||
213 | length += member_size (struct GNUNET_MESSENGER_Message, body.id.id); | ||
214 | break; | ||
215 | case GNUNET_MESSENGER_KIND_MISS: | ||
216 | length += member_size (struct GNUNET_MESSENGER_Message, body.miss.peer); | ||
217 | break; | ||
218 | case GNUNET_MESSENGER_KIND_MERGE: | ||
219 | length += member_size (struct GNUNET_MESSENGER_Message, | ||
220 | body.merge.previous); | ||
221 | break; | ||
222 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
223 | length += member_size (struct GNUNET_MESSENGER_Message, body.request.hash); | ||
224 | break; | ||
225 | case GNUNET_MESSENGER_KIND_INVITE: | ||
226 | length += member_size (struct GNUNET_MESSENGER_Message, body.invite.door); | ||
227 | length += member_size (struct GNUNET_MESSENGER_Message, body.invite.key); | ||
228 | break; | ||
229 | case GNUNET_MESSENGER_KIND_TEXT: | ||
230 | break; | ||
231 | case GNUNET_MESSENGER_KIND_FILE: | ||
232 | length += member_size (struct GNUNET_MESSENGER_Message, body.file.key); | ||
233 | length += member_size (struct GNUNET_MESSENGER_Message, body.file.hash); | ||
234 | length += member_size (struct GNUNET_MESSENGER_Message, body.file.name); | ||
235 | break; | ||
236 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
237 | length += member_size (struct GNUNET_MESSENGER_Message, body.privacy.key); | ||
238 | break; | ||
239 | case GNUNET_MESSENGER_KIND_DELETE: | ||
240 | length += member_size (struct GNUNET_MESSENGER_Message, body.deletion.hash); | ||
241 | length += member_size (struct GNUNET_MESSENGER_Message, | ||
242 | body.deletion.delay); | ||
243 | break; | ||
244 | default: | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | return length; | ||
249 | } | ||
250 | |||
251 | |||
252 | typedef uint32_t kind_t; | ||
253 | |||
254 | uint16_t | ||
255 | get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind, | ||
256 | int include_header) | ||
257 | { | ||
258 | uint16_t length = 0; | ||
259 | |||
260 | if (GNUNET_YES == include_header) | ||
261 | { | ||
262 | length += member_size (struct GNUNET_MESSENGER_Message, header.timestamp); | ||
263 | length += member_size (struct GNUNET_MESSENGER_Message, header.sender_id); | ||
264 | length += member_size (struct GNUNET_MESSENGER_Message, header.previous); | ||
265 | } | ||
266 | |||
267 | length += sizeof(kind_t); | ||
268 | |||
269 | return length + get_message_body_kind_size (kind); | ||
270 | } | ||
271 | |||
272 | |||
273 | static uint16_t | ||
274 | get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind, | ||
275 | const struct GNUNET_MESSENGER_MessageBody *body) | ||
276 | { | ||
277 | uint16_t length = 0; | ||
278 | |||
279 | switch (kind) | ||
280 | { | ||
281 | case GNUNET_MESSENGER_KIND_JOIN: | ||
282 | length += GNUNET_CRYPTO_public_key_get_length (&(body->join.key)); | ||
283 | break; | ||
284 | case GNUNET_MESSENGER_KIND_NAME: | ||
285 | length += (body->name.name ? strlen (body->name.name) : 0); | ||
286 | break; | ||
287 | case GNUNET_MESSENGER_KIND_KEY: | ||
288 | length += GNUNET_CRYPTO_public_key_get_length (&(body->key.key)); | ||
289 | break; | ||
290 | case GNUNET_MESSENGER_KIND_TEXT: | ||
291 | length += strlen (body->text.text); | ||
292 | break; | ||
293 | case GNUNET_MESSENGER_KIND_FILE: | ||
294 | length += strlen (body->file.uri); | ||
295 | break; | ||
296 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
297 | length += body->privacy.length; | ||
298 | break; | ||
299 | default: | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | return length; | ||
304 | } | ||
305 | |||
306 | |||
307 | uint16_t | ||
308 | get_message_size (const struct GNUNET_MESSENGER_Message *message, | ||
309 | int include_header) | ||
310 | { | ||
311 | GNUNET_assert (message); | ||
312 | |||
313 | uint16_t length = 0; | ||
314 | |||
315 | if (GNUNET_YES == include_header) | ||
316 | length += GNUNET_CRYPTO_signature_get_length ( | ||
317 | &(message->header.signature)); | ||
318 | |||
319 | length += get_message_kind_size (message->header.kind, include_header); | ||
320 | length += get_message_body_size (message->header.kind, &(message->body)); | ||
321 | |||
322 | return length; | ||
323 | } | ||
324 | |||
325 | |||
326 | static uint16_t | ||
327 | get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message, | ||
328 | int include_body) | ||
329 | { | ||
330 | const uint16_t minimum_size = sizeof(struct GNUNET_HashCode) + sizeof(kind_t); | ||
331 | |||
332 | if (message) | ||
333 | return minimum_size + get_message_body_kind_size (message->kind) | ||
334 | + (include_body == GNUNET_YES? get_message_body_size (message->kind, | ||
335 | &(message->body)) | ||
336 | : 0); | ||
337 | else | ||
338 | return minimum_size; | ||
339 | } | ||
340 | |||
341 | |||
342 | static uint16_t | ||
343 | calc_usual_padding () | ||
344 | { | ||
345 | uint16_t padding = 0; | ||
346 | uint16_t kind_size; | ||
347 | |||
348 | for (int i = 0; i <= GNUNET_MESSENGER_KIND_MAX; i++) | ||
349 | { | ||
350 | kind_size = get_message_kind_size ((enum GNUNET_MESSENGER_MessageKind) i, | ||
351 | GNUNET_YES); | ||
352 | |||
353 | if (kind_size > padding) | ||
354 | padding = kind_size; | ||
355 | } | ||
356 | |||
357 | return padding + GNUNET_MESSENGER_PADDING_MIN; | ||
358 | } | ||
359 | |||
360 | |||
361 | #define max(x, y) (x > y? x : y) | ||
362 | |||
363 | static uint16_t | ||
364 | calc_padded_length (uint16_t length) | ||
365 | { | ||
366 | static uint16_t usual_padding = 0; | ||
367 | |||
368 | if (! usual_padding) | ||
369 | usual_padding = calc_usual_padding (); | ||
370 | |||
371 | const uint16_t padded_length = max ( | ||
372 | length + GNUNET_MESSENGER_PADDING_MIN, | ||
373 | usual_padding | ||
374 | ); | ||
375 | |||
376 | if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL0) | ||
377 | return GNUNET_MESSENGER_PADDING_LEVEL0; | ||
378 | |||
379 | if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL1) | ||
380 | return GNUNET_MESSENGER_PADDING_LEVEL1; | ||
381 | |||
382 | if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL2) | ||
383 | return GNUNET_MESSENGER_PADDING_LEVEL2; | ||
384 | |||
385 | return GNUNET_MESSENGER_MAX_MESSAGE_SIZE; | ||
386 | |||
387 | } | ||
388 | |||
389 | |||
390 | #define min(x, y) (x < y? x : y) | ||
391 | |||
392 | #define encode_step_ext(dst, offset, src, size) do { \ | ||
393 | GNUNET_memcpy (dst + offset, src, size); \ | ||
394 | offset += size; \ | ||
395 | } while (0) | ||
396 | |||
397 | #define encode_step(dst, offset, src) do { \ | ||
398 | encode_step_ext (dst, offset, src, sizeof(*src)); \ | ||
399 | } while (0) | ||
400 | |||
401 | #define encode_step_key(dst, offset, src, length) do { \ | ||
402 | ssize_t result = GNUNET_CRYPTO_write_public_key_to_buffer ( \ | ||
403 | src, dst + offset, length - offset \ | ||
404 | ); \ | ||
405 | if (result < 0) \ | ||
406 | GNUNET_break (0); \ | ||
407 | else \ | ||
408 | offset += result; \ | ||
409 | } while (0) | ||
410 | |||
411 | #define encode_step_signature(dst, offset, src, length) do { \ | ||
412 | ssize_t result = GNUNET_CRYPTO_write_signature_to_buffer ( \ | ||
413 | src, dst + offset, length - offset \ | ||
414 | ); \ | ||
415 | if (result < 0) \ | ||
416 | GNUNET_break (0); \ | ||
417 | else \ | ||
418 | offset += result; \ | ||
419 | } while (0) | ||
420 | |||
421 | static void | ||
422 | encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, | ||
423 | const struct GNUNET_MESSENGER_MessageBody *body, | ||
424 | uint16_t length, | ||
425 | char *buffer, | ||
426 | uint16_t offset) | ||
427 | { | ||
428 | uint32_t version; | ||
429 | switch (kind) | ||
430 | { | ||
431 | case GNUNET_MESSENGER_KIND_INFO: | ||
432 | version = GNUNET_htobe32 (body->info.messenger_version); | ||
433 | |||
434 | encode_step (buffer, offset, &version); | ||
435 | break; | ||
436 | case GNUNET_MESSENGER_KIND_JOIN: | ||
437 | encode_step_key (buffer, offset, &(body->join.key), length); | ||
438 | break; | ||
439 | case GNUNET_MESSENGER_KIND_NAME: | ||
440 | if (body->name.name) | ||
441 | encode_step_ext (buffer, offset, body->name.name, min (length - offset, | ||
442 | strlen ( | ||
443 | body->name.name))); | ||
444 | break; | ||
445 | case GNUNET_MESSENGER_KIND_KEY: | ||
446 | encode_step_key (buffer, offset, &(body->key.key), length); | ||
447 | break; | ||
448 | case GNUNET_MESSENGER_KIND_PEER: | ||
449 | encode_step (buffer, offset, &(body->peer.peer)); | ||
450 | break; | ||
451 | case GNUNET_MESSENGER_KIND_ID: | ||
452 | encode_step (buffer, offset, &(body->id.id)); | ||
453 | break; | ||
454 | case GNUNET_MESSENGER_KIND_MISS: | ||
455 | encode_step (buffer, offset, &(body->miss.peer)); | ||
456 | break; | ||
457 | case GNUNET_MESSENGER_KIND_MERGE: | ||
458 | encode_step (buffer, offset, &(body->merge.previous)); | ||
459 | break; | ||
460 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
461 | encode_step (buffer, offset, &(body->request.hash)); | ||
462 | break; | ||
463 | case GNUNET_MESSENGER_KIND_INVITE: | ||
464 | encode_step (buffer, offset, &(body->invite.door)); | ||
465 | encode_step (buffer, offset, &(body->invite.key)); | ||
466 | break; | ||
467 | case GNUNET_MESSENGER_KIND_TEXT: | ||
468 | encode_step_ext (buffer, offset, body->text.text, min (length - offset, | ||
469 | strlen ( | ||
470 | body->text.text))); | ||
471 | break; | ||
472 | case GNUNET_MESSENGER_KIND_FILE: | ||
473 | encode_step (buffer, offset, &(body->file.key)); | ||
474 | encode_step (buffer, offset, &(body->file.hash)); | ||
475 | encode_step_ext (buffer, offset, body->file.name, sizeof(body->file.name)); | ||
476 | encode_step_ext (buffer, offset, body->file.uri, min (length - offset, | ||
477 | strlen ( | ||
478 | body->file.uri))); | ||
479 | break; | ||
480 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
481 | encode_step (buffer, offset, &(body->privacy.key)); | ||
482 | encode_step_ext (buffer, offset, body->privacy.data, min (length - offset, | ||
483 | body->privacy. | ||
484 | length)); | ||
485 | break; | ||
486 | case GNUNET_MESSENGER_KIND_DELETE: | ||
487 | encode_step (buffer, offset, &(body->deletion.hash)); | ||
488 | encode_step (buffer, offset, &(body->deletion.delay)); | ||
489 | break; | ||
490 | default: | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | if (offset >= length) | ||
495 | return; | ||
496 | |||
497 | const uint16_t padding = length - offset; | ||
498 | const uint16_t used_padding = sizeof(padding) + sizeof(char); | ||
499 | |||
500 | GNUNET_assert (padding >= used_padding); | ||
501 | |||
502 | buffer[offset++] = '\0'; | ||
503 | |||
504 | if (padding > used_padding) | ||
505 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, buffer + offset, | ||
506 | padding - used_padding); | ||
507 | |||
508 | GNUNET_memcpy (buffer + length - sizeof(padding), &padding, sizeof(padding)); | ||
509 | } | ||
510 | |||
511 | |||
512 | void | ||
513 | encode_message (const struct GNUNET_MESSENGER_Message *message, | ||
514 | uint16_t length, | ||
515 | char *buffer, | ||
516 | int include_header) | ||
517 | { | ||
518 | GNUNET_assert ((message) && (buffer)); | ||
519 | |||
520 | uint16_t offset = 0; | ||
521 | |||
522 | if (GNUNET_YES == include_header) | ||
523 | encode_step_signature (buffer, offset, &(message->header.signature), | ||
524 | length); | ||
525 | |||
526 | const kind_t kind = GNUNET_htobe32 ((kind_t) message->header.kind); | ||
527 | |||
528 | if (GNUNET_YES == include_header) | ||
529 | { | ||
530 | encode_step (buffer, offset, &(message->header.timestamp)); | ||
531 | encode_step (buffer, offset, &(message->header.sender_id)); | ||
532 | encode_step (buffer, offset, &(message->header.previous)); | ||
533 | } | ||
534 | |||
535 | encode_step (buffer, offset, &kind); | ||
536 | |||
537 | encode_message_body (message->header.kind, &(message->body), length, buffer, | ||
538 | offset); | ||
539 | } | ||
540 | |||
541 | |||
542 | static void | ||
543 | encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message, | ||
544 | uint16_t length, | ||
545 | char *buffer) | ||
546 | { | ||
547 | struct GNUNET_HashCode hash; | ||
548 | uint16_t offset = sizeof(hash); | ||
549 | |||
550 | const kind_t kind = GNUNET_htobe32 ((kind_t) message->kind); | ||
551 | |||
552 | encode_step (buffer, offset, &kind); | ||
553 | |||
554 | encode_message_body (message->kind, &(message->body), length, buffer, offset); | ||
555 | |||
556 | GNUNET_CRYPTO_hash ( | ||
557 | buffer + sizeof(hash), | ||
558 | length - sizeof(hash), | ||
559 | &hash | ||
560 | ); | ||
561 | |||
562 | GNUNET_memcpy (buffer, &hash, sizeof(hash)); | ||
563 | } | ||
564 | |||
565 | |||
566 | #define decode_step_ext(src, offset, dst, size) do { \ | ||
567 | GNUNET_memcpy (dst, src + offset, size); \ | ||
568 | offset += size; \ | ||
569 | } while (0) | ||
570 | |||
571 | #define decode_step(src, offset, dst) do { \ | ||
572 | decode_step_ext (src, offset, dst, sizeof(*dst)); \ | ||
573 | } while (0) | ||
574 | |||
575 | #define decode_step_malloc(src, offset, dst, size, zero) do { \ | ||
576 | dst = GNUNET_malloc (size + zero); \ | ||
577 | if (zero) dst[size] = 0; \ | ||
578 | decode_step_ext (src, offset, dst, size); \ | ||
579 | } while (0) | ||
580 | |||
581 | #define decode_step_key(src, offset, dst, length) do { \ | ||
582 | enum GNUNET_GenericReturnValue result; \ | ||
583 | size_t read; \ | ||
584 | result = GNUNET_CRYPTO_read_public_key_from_buffer ( \ | ||
585 | src + offset, length - offset, dst, &read \ | ||
586 | ); \ | ||
587 | if (GNUNET_SYSERR == result) \ | ||
588 | GNUNET_break (0); \ | ||
589 | else \ | ||
590 | offset += read; \ | ||
591 | } while (0) | ||
592 | |||
593 | static uint16_t | ||
594 | decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, | ||
595 | struct GNUNET_MESSENGER_MessageBody *body, | ||
596 | uint16_t length, | ||
597 | const char *buffer, | ||
598 | uint16_t offset) | ||
599 | { | ||
600 | uint16_t padding = 0; | ||
601 | |||
602 | GNUNET_memcpy (&padding, buffer + length - sizeof(padding), sizeof(padding)); | ||
603 | |||
604 | if (padding > length - offset) | ||
605 | padding = 0; | ||
606 | |||
607 | const uint16_t end_zero = length - padding; | ||
608 | |||
609 | if ((padding) && (buffer[end_zero] != '\0')) | ||
610 | padding = 0; | ||
611 | |||
612 | length -= padding; | ||
613 | |||
614 | uint32_t version; | ||
615 | switch (*kind) | ||
616 | { | ||
617 | case GNUNET_MESSENGER_KIND_INFO: { | ||
618 | decode_step (buffer, offset, &version); | ||
619 | |||
620 | body->info.messenger_version = GNUNET_be32toh (version); | ||
621 | break; | ||
622 | } case GNUNET_MESSENGER_KIND_JOIN: { | ||
623 | decode_step_key (buffer, offset, &(body->join.key), length); | ||
624 | break; | ||
625 | } case GNUNET_MESSENGER_KIND_NAME: | ||
626 | if (length - offset > 0) | ||
627 | decode_step_malloc (buffer, offset, body->name.name, length - offset, 1); | ||
628 | else | ||
629 | body->name.name = NULL; | ||
630 | break; | ||
631 | case GNUNET_MESSENGER_KIND_KEY: | ||
632 | decode_step_key (buffer, offset, &(body->key.key), length); | ||
633 | break; | ||
634 | case GNUNET_MESSENGER_KIND_PEER: | ||
635 | decode_step (buffer, offset, &(body->peer.peer)); | ||
636 | break; | ||
637 | case GNUNET_MESSENGER_KIND_ID: | ||
638 | decode_step (buffer, offset, &(body->id.id)); | ||
639 | break; | ||
640 | case GNUNET_MESSENGER_KIND_MISS: | ||
641 | decode_step (buffer, offset, &(body->miss.peer)); | ||
642 | break; | ||
643 | case GNUNET_MESSENGER_KIND_MERGE: | ||
644 | decode_step (buffer, offset, &(body->merge.previous)); | ||
645 | break; | ||
646 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
647 | decode_step (buffer, offset, &(body->request.hash)); | ||
648 | break; | ||
649 | case GNUNET_MESSENGER_KIND_INVITE: | ||
650 | decode_step (buffer, offset, &(body->invite.door)); | ||
651 | decode_step (buffer, offset, &(body->invite.key)); | ||
652 | break; | ||
653 | case GNUNET_MESSENGER_KIND_TEXT: | ||
654 | decode_step_malloc (buffer, offset, body->text.text, length - offset, 1); | ||
655 | break; | ||
656 | case GNUNET_MESSENGER_KIND_FILE: | ||
657 | decode_step (buffer, offset, &(body->file.key)); | ||
658 | decode_step (buffer, offset, &(body->file.hash)); | ||
659 | decode_step_ext (buffer, offset, body->file.name, sizeof(body->file.name)); | ||
660 | decode_step_malloc (buffer, offset, body->file.uri, length - offset, 1); | ||
661 | break; | ||
662 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
663 | decode_step (buffer, offset, &(body->privacy.key)); | ||
664 | |||
665 | body->privacy.length = (length - offset); | ||
666 | decode_step_malloc (buffer, offset, body->privacy.data, length - offset, 0); | ||
667 | break; | ||
668 | case GNUNET_MESSENGER_KIND_DELETE: | ||
669 | decode_step (buffer, offset, &(body->deletion.hash)); | ||
670 | decode_step (buffer, offset, &(body->deletion.delay)); | ||
671 | break; | ||
672 | default: | ||
673 | *kind = GNUNET_MESSENGER_KIND_UNKNOWN; | ||
674 | break; | ||
675 | } | ||
676 | |||
677 | return padding; | ||
678 | } | ||
679 | |||
680 | |||
681 | int | ||
682 | decode_message (struct GNUNET_MESSENGER_Message *message, | ||
683 | uint16_t length, | ||
684 | const char *buffer, | ||
685 | int include_header, | ||
686 | uint16_t *padding) | ||
687 | { | ||
688 | GNUNET_assert ( | ||
689 | (message) && | ||
690 | (buffer) && | ||
691 | (length >= get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN, | ||
692 | include_header)) | ||
693 | ); | ||
694 | |||
695 | uint16_t offset = 0; | ||
696 | |||
697 | if (GNUNET_YES == include_header) | ||
698 | { | ||
699 | ssize_t result = GNUNET_CRYPTO_read_signature_from_buffer ( | ||
700 | &(message->header.signature), buffer, length - offset | ||
701 | ); | ||
702 | |||
703 | if (result < 0) | ||
704 | return GNUNET_NO; | ||
705 | else | ||
706 | offset += result; | ||
707 | } | ||
708 | |||
709 | const uint16_t count = length - offset; | ||
710 | |||
711 | if (count < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN, | ||
712 | include_header)) | ||
713 | return GNUNET_NO; | ||
714 | |||
715 | kind_t kind; | ||
716 | |||
717 | if (GNUNET_YES == include_header) | ||
718 | { | ||
719 | decode_step (buffer, offset, &(message->header.timestamp)); | ||
720 | decode_step (buffer, offset, &(message->header.sender_id)); | ||
721 | decode_step (buffer, offset, &(message->header.previous)); | ||
722 | } | ||
723 | |||
724 | decode_step (buffer, offset, &kind); | ||
725 | |||
726 | message->header.kind = (enum GNUNET_MESSENGER_MessageKind) GNUNET_be32toh ( | ||
727 | kind); | ||
728 | |||
729 | if (count < get_message_kind_size (message->header.kind, include_header)) | ||
730 | return GNUNET_NO; | ||
731 | |||
732 | const uint16_t result = decode_message_body (&(message->header.kind), | ||
733 | &(message->body), length, buffer, | ||
734 | offset); | ||
735 | |||
736 | if (padding) | ||
737 | *padding = result; | ||
738 | |||
739 | return GNUNET_YES; | ||
740 | } | ||
741 | |||
742 | |||
743 | static int | ||
744 | decode_short_message (struct GNUNET_MESSENGER_ShortMessage *message, | ||
745 | uint16_t length, | ||
746 | const char *buffer) | ||
747 | { | ||
748 | struct GNUNET_HashCode expected, hash; | ||
749 | uint16_t offset = sizeof(hash); | ||
750 | |||
751 | if (length < get_short_message_size (NULL, GNUNET_NO)) | ||
752 | return GNUNET_NO; | ||
753 | |||
754 | GNUNET_memcpy (&hash, buffer, sizeof(hash)); | ||
755 | |||
756 | GNUNET_CRYPTO_hash ( | ||
757 | buffer + sizeof(hash), | ||
758 | length - sizeof(hash), | ||
759 | &expected | ||
760 | ); | ||
761 | |||
762 | if (0 != GNUNET_CRYPTO_hash_cmp (&hash, &expected)) | ||
763 | return GNUNET_NO; | ||
764 | |||
765 | kind_t kind; | ||
766 | |||
767 | decode_step (buffer, offset, &kind); | ||
768 | |||
769 | message->kind = (enum GNUNET_MESSENGER_MessageKind) GNUNET_be32toh (kind); | ||
770 | |||
771 | if (length < get_short_message_size (message, GNUNET_NO)) | ||
772 | return GNUNET_NO; | ||
773 | |||
774 | decode_message_body (&(message->kind), &(message->body), length, buffer, | ||
775 | offset); | ||
776 | |||
777 | if (GNUNET_MESSENGER_KIND_UNKNOWN == message->kind) | ||
778 | return GNUNET_NO; | ||
779 | |||
780 | return GNUNET_YES; | ||
781 | } | ||
782 | |||
783 | |||
784 | void | ||
785 | hash_message (const struct GNUNET_MESSENGER_Message *message, | ||
786 | uint16_t length, | ||
787 | const char *buffer, | ||
788 | struct GNUNET_HashCode *hash) | ||
789 | { | ||
790 | GNUNET_assert ((message) && (buffer) && (hash)); | ||
791 | |||
792 | const ssize_t offset = GNUNET_CRYPTO_signature_get_length ( | ||
793 | &(message->header.signature) | ||
794 | ); | ||
795 | |||
796 | GNUNET_CRYPTO_hash (buffer + offset, length - offset, hash); | ||
797 | } | ||
798 | |||
799 | |||
800 | void | ||
801 | sign_message (struct GNUNET_MESSENGER_Message *message, | ||
802 | uint16_t length, | ||
803 | char *buffer, | ||
804 | const struct GNUNET_HashCode *hash, | ||
805 | const struct GNUNET_CRYPTO_PrivateKey *key) | ||
806 | { | ||
807 | GNUNET_assert ((message) && (buffer) && (hash) && (key)); | ||
808 | |||
809 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sign message by member: %s\n", | ||
810 | GNUNET_h2s (hash)); | ||
811 | |||
812 | struct GNUNET_MESSENGER_MessageSignature signature; | ||
813 | |||
814 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | ||
815 | signature.purpose.size = htonl (sizeof(signature)); | ||
816 | |||
817 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
818 | GNUNET_CRYPTO_sign (key, &signature, &(message->header.signature)); | ||
819 | |||
820 | message->header.signature.type = key->type; | ||
821 | |||
822 | uint16_t offset = 0; | ||
823 | encode_step_signature (buffer, offset, &(message->header.signature), length); | ||
824 | } | ||
825 | |||
826 | |||
827 | void | ||
828 | sign_message_by_peer (struct GNUNET_MESSENGER_Message *message, | ||
829 | uint16_t length, | ||
830 | char *buffer, | ||
831 | const struct GNUNET_HashCode *hash, | ||
832 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
833 | { | ||
834 | GNUNET_assert ((message) && (buffer) && (hash) && (cfg)); | ||
835 | |||
836 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sign message by peer: %s\n", | ||
837 | GNUNET_h2s (hash)); | ||
838 | |||
839 | struct GNUNET_MESSENGER_MessageSignature signature; | ||
840 | |||
841 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | ||
842 | signature.purpose.size = htonl (sizeof(signature)); | ||
843 | |||
844 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
845 | GNUNET_CRYPTO_sign_by_peer_identity (cfg, &signature.purpose, | ||
846 | &(message->header.signature. | ||
847 | eddsa_signature)); | ||
848 | |||
849 | message->header.signature.type = htonl (GNUNET_PUBLIC_KEY_TYPE_EDDSA); | ||
850 | |||
851 | uint16_t offset = 0; | ||
852 | encode_step_signature (buffer, offset, &(message->header.signature), length); | ||
853 | } | ||
854 | |||
855 | |||
856 | int | ||
857 | verify_message (const struct GNUNET_MESSENGER_Message *message, | ||
858 | const struct GNUNET_HashCode *hash, | ||
859 | const struct GNUNET_CRYPTO_PublicKey *key) | ||
860 | { | ||
861 | GNUNET_assert ((message) && (hash) && (key)); | ||
862 | |||
863 | if (key->type != message->header.signature.type) | ||
864 | return GNUNET_SYSERR; | ||
865 | |||
866 | struct GNUNET_MESSENGER_MessageSignature signature; | ||
867 | |||
868 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | ||
869 | signature.purpose.size = htonl (sizeof(signature)); | ||
870 | |||
871 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
872 | |||
873 | return GNUNET_CRYPTO_signature_verify ( | ||
874 | GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature, | ||
875 | &(message->header.signature), key); | ||
876 | } | ||
877 | |||
878 | |||
879 | int | ||
880 | verify_message_by_peer (const struct GNUNET_MESSENGER_Message *message, | ||
881 | const struct GNUNET_HashCode *hash, | ||
882 | const struct GNUNET_PeerIdentity *identity) | ||
883 | { | ||
884 | GNUNET_assert ((message) && (hash) && (identity)); | ||
885 | |||
886 | if (ntohl (GNUNET_PUBLIC_KEY_TYPE_EDDSA) != message->header.signature.type) | ||
887 | return GNUNET_SYSERR; | ||
888 | |||
889 | struct GNUNET_MESSENGER_MessageSignature signature; | ||
890 | |||
891 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | ||
892 | signature.purpose.size = htonl (sizeof(signature)); | ||
893 | |||
894 | GNUNET_memcpy (&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
895 | |||
896 | return GNUNET_CRYPTO_verify_peer_identity ( | ||
897 | GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature.purpose, | ||
898 | &(message->header.signature. | ||
899 | eddsa_signature), identity); | ||
900 | } | ||
901 | |||
902 | |||
903 | int | ||
904 | encrypt_message (struct GNUNET_MESSENGER_Message *message, | ||
905 | const struct GNUNET_CRYPTO_PublicKey *key) | ||
906 | { | ||
907 | GNUNET_assert ((message) && (key)); | ||
908 | |||
909 | if (GNUNET_YES == is_service_message (message)) | ||
910 | return GNUNET_NO; | ||
911 | |||
912 | struct GNUNET_MESSENGER_ShortMessage shortened; | ||
913 | |||
914 | fold_short_message (message, &shortened); | ||
915 | |||
916 | const uint16_t length = get_short_message_size (&shortened, GNUNET_YES); | ||
917 | const uint16_t padded_length = calc_padded_length ( | ||
918 | length + GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES | ||
919 | ); | ||
920 | |||
921 | message->header.kind = GNUNET_MESSENGER_KIND_PRIVATE; | ||
922 | message->body.privacy.data = GNUNET_malloc (padded_length); | ||
923 | message->body.privacy.length = padded_length; | ||
924 | |||
925 | const uint16_t encoded_length = ( | ||
926 | padded_length - GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES | ||
927 | ); | ||
928 | |||
929 | encode_short_message (&shortened, encoded_length, message->body.privacy.data); | ||
930 | |||
931 | if (GNUNET_OK != GNUNET_CRYPTO_encrypt (message->body.privacy.data, | ||
932 | encoded_length, | ||
933 | key, | ||
934 | message->body.privacy.data, | ||
935 | padded_length)) | ||
936 | { | ||
937 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Encrypting message failed!\n"); | ||
938 | |||
939 | unfold_short_message (&shortened, message); | ||
940 | return GNUNET_NO; | ||
941 | } | ||
942 | |||
943 | destroy_message_body (shortened.kind, &(shortened.body)); | ||
944 | return GNUNET_YES; | ||
945 | } | ||
946 | |||
947 | |||
948 | int | ||
949 | decrypt_message (struct GNUNET_MESSENGER_Message *message, | ||
950 | const struct GNUNET_CRYPTO_PrivateKey *key) | ||
951 | { | ||
952 | GNUNET_assert ((message) && (key)); | ||
953 | |||
954 | const uint16_t padded_length = message->body.privacy.length; | ||
955 | |||
956 | if (padded_length < GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES) | ||
957 | { | ||
958 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
959 | "Message length too short to decrypt!\n"); | ||
960 | |||
961 | return GNUNET_NO; | ||
962 | } | ||
963 | |||
964 | const uint16_t encoded_length = ( | ||
965 | padded_length - GNUNET_CRYPTO_ENCRYPT_OVERHEAD_BYTES | ||
966 | ); | ||
967 | |||
968 | if (GNUNET_OK != GNUNET_CRYPTO_decrypt (message->body.privacy.data, | ||
969 | padded_length, | ||
970 | key, | ||
971 | message->body.privacy.data, | ||
972 | encoded_length)) | ||
973 | { | ||
974 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Decrypting message failed!\n"); | ||
975 | |||
976 | return GNUNET_NO; | ||
977 | } | ||
978 | |||
979 | struct GNUNET_MESSENGER_ShortMessage shortened; | ||
980 | |||
981 | if (GNUNET_YES != decode_short_message (&shortened, | ||
982 | encoded_length, | ||
983 | message->body.privacy.data)) | ||
984 | { | ||
985 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
986 | "Decoding decrypted message failed!\n"); | ||
987 | |||
988 | return GNUNET_NO; | ||
989 | } | ||
990 | |||
991 | unfold_short_message (&shortened, message); | ||
992 | return GNUNET_YES; | ||
993 | } | ||
994 | |||
995 | |||
996 | struct GNUNET_MQ_Envelope* | ||
997 | pack_message (struct GNUNET_MESSENGER_Message *message, | ||
998 | struct GNUNET_HashCode *hash, | ||
999 | const GNUNET_MESSENGER_SignFunction sign, | ||
1000 | int mode, | ||
1001 | const void *cls) | ||
1002 | { | ||
1003 | GNUNET_assert (message); | ||
1004 | |||
1005 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1006 | "Packing message kind=%u and sender: %s\n", | ||
1007 | message->header.kind, GNUNET_sh2s (&(message->header.sender_id))); | ||
1008 | |||
1009 | struct GNUNET_MessageHeader *header; | ||
1010 | |||
1011 | const uint16_t length = get_message_size (message, GNUNET_YES); | ||
1012 | const uint16_t padded_length = calc_padded_length (length); | ||
1013 | |||
1014 | struct GNUNET_MQ_Envelope *env; | ||
1015 | char *buffer; | ||
1016 | |||
1017 | if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE == mode) | ||
1018 | { | ||
1019 | env = GNUNET_MQ_msg_extra (header, padded_length, | ||
1020 | GNUNET_MESSAGE_TYPE_CADET_CLI); | ||
1021 | |||
1022 | buffer = (char*) &(header[1]); | ||
1023 | } | ||
1024 | else | ||
1025 | { | ||
1026 | env = NULL; | ||
1027 | |||
1028 | buffer = GNUNET_malloc (padded_length); | ||
1029 | } | ||
1030 | |||
1031 | encode_message (message, padded_length, buffer, GNUNET_YES); | ||
1032 | |||
1033 | if (hash) | ||
1034 | { | ||
1035 | hash_message (message, length, buffer, hash); | ||
1036 | |||
1037 | if (sign) | ||
1038 | sign (cls, message, length, buffer, hash); | ||
1039 | } | ||
1040 | |||
1041 | if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE != mode) | ||
1042 | GNUNET_free (buffer); | ||
1043 | |||
1044 | return env; | ||
1045 | } | ||
1046 | |||
1047 | |||
1048 | int | ||
1049 | is_peer_message (const struct GNUNET_MESSENGER_Message *message) | ||
1050 | { | ||
1051 | switch (message->header.kind) | ||
1052 | { | ||
1053 | case GNUNET_MESSENGER_KIND_INFO: | ||
1054 | case GNUNET_MESSENGER_KIND_PEER: | ||
1055 | case GNUNET_MESSENGER_KIND_MISS: | ||
1056 | case GNUNET_MESSENGER_KIND_MERGE: | ||
1057 | return GNUNET_YES; | ||
1058 | default: | ||
1059 | return GNUNET_NO; | ||
1060 | } | ||
1061 | } | ||
1062 | |||
1063 | |||
1064 | int | ||
1065 | is_service_message (const struct GNUNET_MESSENGER_Message *message) | ||
1066 | { | ||
1067 | if (GNUNET_YES == is_peer_message (message)) | ||
1068 | return GNUNET_YES; | ||
1069 | |||
1070 | switch (message->header.kind) | ||
1071 | { | ||
1072 | case GNUNET_MESSENGER_KIND_INFO: | ||
1073 | return GNUNET_YES; // Reserved for connection handling only! | ||
1074 | case GNUNET_MESSENGER_KIND_JOIN: | ||
1075 | return GNUNET_YES; // Reserved for member handling only! | ||
1076 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
1077 | return GNUNET_YES; // Reserved for member handling only! | ||
1078 | case GNUNET_MESSENGER_KIND_NAME: | ||
1079 | return GNUNET_YES; // Reserved for member name handling only! | ||
1080 | case GNUNET_MESSENGER_KIND_KEY: | ||
1081 | return GNUNET_YES; // Reserved for member key handling only! | ||
1082 | case GNUNET_MESSENGER_KIND_PEER: | ||
1083 | return GNUNET_YES; // Reserved for connection handling only! | ||
1084 | case GNUNET_MESSENGER_KIND_ID: | ||
1085 | return GNUNET_YES; // Reserved for member id handling only! | ||
1086 | case GNUNET_MESSENGER_KIND_MISS: | ||
1087 | return GNUNET_YES; // Reserved for connection handling only! | ||
1088 | case GNUNET_MESSENGER_KIND_MERGE: | ||
1089 | return GNUNET_YES; // Reserved for peers only! | ||
1090 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
1091 | return GNUNET_YES; // Requests should not apply individually! (inefficieny) | ||
1092 | case GNUNET_MESSENGER_KIND_INVITE: | ||
1093 | return GNUNET_NO; | ||
1094 | case GNUNET_MESSENGER_KIND_TEXT: | ||
1095 | return GNUNET_NO; | ||
1096 | case GNUNET_MESSENGER_KIND_FILE: | ||
1097 | return GNUNET_NO; | ||
1098 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
1099 | return GNUNET_YES; // Prevent duplicate encryption breaking all access! | ||
1100 | case GNUNET_MESSENGER_KIND_DELETE: | ||
1101 | return GNUNET_YES; // Deletion should not apply individually! (inefficieny) | ||
1102 | default: | ||
1103 | return GNUNET_SYSERR; | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | |||
1108 | int | ||
1109 | filter_message_sending (const struct GNUNET_MESSENGER_Message *message) | ||
1110 | { | ||
1111 | if (GNUNET_YES == is_peer_message (message)) | ||
1112 | return GNUNET_SYSERR; // Requires signature of peer rather than ego! | ||
1113 | |||
1114 | switch (message->header.kind) | ||
1115 | { | ||
1116 | case GNUNET_MESSENGER_KIND_INFO: | ||
1117 | return GNUNET_SYSERR; // Reserved for connection handling only! | ||
1118 | case GNUNET_MESSENGER_KIND_JOIN: | ||
1119 | return GNUNET_NO; // Use #GNUNET_MESSENGER_enter_room(...) instead! | ||
1120 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
1121 | return GNUNET_NO; // Use #GNUNET_MESSENGER_close_room(...) instead! | ||
1122 | case GNUNET_MESSENGER_KIND_NAME: | ||
1123 | return GNUNET_YES; | ||
1124 | case GNUNET_MESSENGER_KIND_KEY: | ||
1125 | return GNUNET_NO; // Use #GNUNET_MESSENGER_set_key_by_ego(...) instead! | ||
1126 | case GNUNET_MESSENGER_KIND_PEER: | ||
1127 | return GNUNET_SYSERR; // Use #GNUNET_MESSENGER_open_room(...) instead! | ||
1128 | case GNUNET_MESSENGER_KIND_ID: | ||
1129 | return GNUNET_NO; // Reserved for member id handling only! | ||
1130 | case GNUNET_MESSENGER_KIND_MISS: | ||
1131 | return GNUNET_SYSERR; // Reserved for connection handling only! | ||
1132 | case GNUNET_MESSENGER_KIND_MERGE: | ||
1133 | return GNUNET_SYSERR; // Reserved for peers only! | ||
1134 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
1135 | return GNUNET_YES; | ||
1136 | case GNUNET_MESSENGER_KIND_INVITE: | ||
1137 | return GNUNET_YES; | ||
1138 | case GNUNET_MESSENGER_KIND_TEXT: | ||
1139 | return GNUNET_YES; | ||
1140 | case GNUNET_MESSENGER_KIND_FILE: | ||
1141 | return GNUNET_YES; | ||
1142 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
1143 | return GNUNET_NO; // Use #GNUNET_MESSENGER_send_message(...) with a contact instead! | ||
1144 | case GNUNET_MESSENGER_KIND_DELETE: | ||
1145 | return GNUNET_YES; | ||
1146 | default: | ||
1147 | return GNUNET_SYSERR; | ||
1148 | } | ||
1149 | } | ||