GNUnet 0.27.0
 
Loading...
Searching...
No Matches
gnunet-hello.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2024, 2026 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
26#include "platform.h"
27
28#include "gnunet_common.h"
29#include "gnunet_time_lib.h"
30#include "gnunet_util_lib.h"
32#include "gnunet_pils_service.h"
33#include "gnunet_util_lib.h"
35
39static int ret;
40
41/*
42 * Handle to PEERSTORE service
43 */
45
46/*
47 * Handle to PILS service
48 */
50
55
60
65
69static char *expirationstring;
70
75
80
84static int print_hellos;
85
90
95
102static void
103shutdown_task (void *cls)
104{
105 (void) cls;
106 if (NULL != shc)
107 {
109 shc = NULL;
110 }
111 if (NULL != iter_ctx)
112 {
114 }
115 if (NULL != peerstore_handle)
116 {
118 peerstore_handle = NULL;
119 }
120 if (NULL != op)
122 if (NULL != pils_handle)
123 {
125 peerstore_handle = NULL;
126 }
127}
128
129
137static void
139 const struct GNUNET_PeerIdentity *pid,
140 const char *uri)
141{
142 (void) cls;
143
144
145 printf ("|- %s\n", uri);
146}
147
148
149static void
150url_resign_cb (void *cls,
151 const struct GNUNET_PeerIdentity *pid,
152 const struct GNUNET_CRYPTO_EddsaSignature *sig)
153{
154 struct GNUNET_HELLO_Builder *builder = cls;
155 char *url;
156
157 op = NULL;
159 pid,
160 sig,
162 &url);
163
164 printf ("%s\n", url);
165 GNUNET_free (url); // TODO is this right?
168}
169
170
171static void
173{
174 const struct GNUNET_MessageHeader *msg;
175
177 fwrite (msg, 1, ntohs (msg->size), stdout);
178}
179
180
181static void
182output_parser (const struct GNUNET_HELLO_Parser *parser)
183{
185 {
186 char *url;
187 url = GNUNET_HELLO_parser_to_url (parser);
188 printf ("%s\n", url);
189 GNUNET_free (url);
191 return;
192 }
193 else
194 {
195 struct GNUNET_MQ_Envelope *env;
197 output_env (env);
199 }
200}
201
202
203static void
205 const struct GNUNET_PeerIdentity *pid,
206 const struct GNUNET_CRYPTO_EddsaSignature *sig)
207{
208 struct GNUNET_HELLO_Builder *builder = cls;
209 struct GNUNET_MQ_Envelope *env;
210
211 op = NULL;
213 pid,
214 sig,
216 output_env (env);
220}
221
222
223static void
224hello_iter (void *cls, const struct GNUNET_PEERSTORE_Record *record,
225 const char *emsg)
226{
227 struct GNUNET_HELLO_Parser *hp;
228 struct GNUNET_TIME_Absolute hello_exp;
229 const struct GNUNET_PeerIdentity *pid;
230
231 if ((NULL == record) && (NULL == emsg))
232 {
236 iter_ctx = NULL;
238 return;
239 }
240 if (NULL != emsg)
241 {
242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
244 return;
245 }
247 &record->peer);
248 if (NULL == hp)
249 {
251 "The HELLO is invalid. Skipping.\n");
253 return;
254 }
257 if (print_hellos)
258 {
259 printf ("`%s' (expires: %s):\n", GNUNET_i2s (pid),
262 }
265}
266
267
268static void
269hello_store_success (void *cls, int success)
270{
271 shc = NULL;
272 if (GNUNET_OK != success)
273 {
275 "Storing hello uri failed\n");
276 }
277 printf ("HELLO imported.");
279}
280
281
282static void
283pid_changed_cb (void *cls,
284 const struct GNUNET_HELLO_Parser *parser,
285 const struct GNUNET_HashCode *addr_hash)
286{
288 if (! export_own_hello)
289 return;
290
291 if (NULL != expirationstring)
292 {
296 builder,
299 builder);
300 return;
301 }
302 output_parser (parser);
304}
305
306
315static void
316run (void *cls,
317 char *const *args,
318 const char *cfgfile,
319 const struct GNUNET_CONFIGURATION_Handle *cfg)
320{
321 struct GNUNET_HELLO_Parser *hp;
322 struct GNUNET_MQ_Envelope *env;
323 struct GNUNET_TIME_Relative hello_validity_rel;
324 char *keyfile;
325 (void) cls;
326 (void) cfgfile;
327
328 if (NULL != args[0])
329 {
330 fprintf (stderr, _ ("Invalid command line argument `%s'\n"), args[0]);
331 return;
332 }
333 if (! print_hellos &&
336 {
337 fprintf (stderr, "%s", _ ("No argument given.\n"));
338 ret = 1;
340 return;
341 }
343 if (GNUNET_OK !=
345 "PEER",
346 "PRIVATE_KEY",
347 &keyfile))
348 {
349 GNUNET_log (
351 _ ("Core service is lacking HOSTKEY configuration setting. Exiting.\n"));
353 ret = 1;
354 return;
355 }
359 GNUNET_assert (NULL != pils_handle);
360 hello_validity_rel = GNUNET_TIME_UNIT_DAYS;
361 if (NULL != expirationstring)
362 {
364 &hello_validity_rel)
365 )
366 {
367 fprintf (stderr, "Invalid expiration time `%s'", expirationstring);
369 return;
370 }
371 }
374 {
375 char buffer[GNUNET_MAX_MESSAGE_SIZE - 1];
376 char *write_ptr;
377 ssize_t nread;
378 size_t read_total = 0;
379
380 write_ptr = buffer;
381 while (0 < (nread = fread (write_ptr, 1,
382 sizeof buffer - read_total, stdin)))
383 {
384 read_total += nread;
385 write_ptr += nread;
386 }
387 buffer[read_total] = '\0';
388 if (strlen ("gnunet://hello/") > read_total)
389 {
390 fprintf (stderr, "HELLO malformed\n");
392 return;
393 }
394 if (0 == strncasecmp ("gnunet://hello/",
395 buffer, strlen ("gnunet://hello/")))
396 {
397 // Remove newline
398 buffer[read_total - 1] = '\0';
399 hp = GNUNET_HELLO_parser_from_url (buffer);
400 if (NULL == hp)
401 {
402 fprintf (stderr, "Unable to parse URI `%s'\n", buffer);
404 return;
405 }
409 &hello_store_success, NULL);
412 }
413 else if (read_total > sizeof (struct GNUNET_MessageHeader))
414 {
416 (const struct GNUNET_MessageHeader*)
417 buffer,
418 &hello_store_success, NULL);
419 }
420 else
421 {
422 fprintf (stderr, "HELLO malformed\n");
424 }
425 return;
426 }
427
428 if (print_hellos)
429 {
431 "peerstore",
432 NULL,
434 &hello_iter,
435 NULL);
436 }
437}
438
439
447int
448main (int argc, char *const *argv)
449{
450 int res;
453 "export-hello",
455 "Print a HELLO for our peer identity"),
458 "binary",
460 "Output HELLO in binary format. Use with `--export'."),
463 "import-hello",
464 gettext_noop ("Import a HELLO"),
465 &import_hello),
467 "expiration",
468 "TIME",
470 "Expiration time to set for exported hello. (Default: 1 day)"),
473 "dump-hellos",
475 "List all known HELLOs in peerstore"),
476 &print_hellos),
478 };
479
481 argc,
482 argv,
483 "gnunet-hello",
485 "Import/export/print HELLOs."),
486 options,
487 &run,
488 NULL);
489
490 if (GNUNET_OK == res)
491 return ret;
492 return 1;
493}
494
495
496/* end of gnunet-hello.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
int main()
Program to simulate results from GCP_get_desirability_of_path() for various plausible inputs.
#define gettext_noop(String)
Definition gettext.h:74
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition gnunet-arm.c:108
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static struct HostSet * builder
NULL if we are not currently iterating over peer information.
static void print_hello_addrs(void *cls, const struct GNUNET_PeerIdentity *pid, const char *uri)
Callback function used to extract URIs from a builder.
static int export_own_hello
HELLO export option -H.
static void env_resign_cb(void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig)
static void hello_iter(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
static void output_parser(const struct GNUNET_HELLO_Parser *parser)
static void url_resign_cb(void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig)
static struct GNUNET_PILS_Handle * pils_handle
static enum GNUNET_GenericReturnValue import_hello
HELLO import option -I.
static int print_hellos
Hello list option -D.
static int ret
Return code.
static struct GNUNET_TIME_Absolute hello_validity
Expiration time for exported hello.
static struct GNUNET_PEERSTORE_IterateContext * iter_ctx
PEERSTORE iteration context.
struct GNUNET_PILS_Operation * op
PILS op.
static void output_env(const struct GNUNET_MQ_Envelope *env)
static enum GNUNET_GenericReturnValue binary_output
HELLO export/import format option.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Main function that will be run by the scheduler.
static char * expirationstring
Optional expiration string -E.
static struct GNUNET_PEERSTORE_Handle * peerstore_handle
static void pid_changed_cb(void *cls, const struct GNUNET_HELLO_Parser *parser, const struct GNUNET_HashCode *addr_hash)
static struct GNUNET_PEERSTORE_StoreHelloContext * shc
HELLO store context handle.
static void hello_store_success(void *cls, int success)
struct GNUNET_SCHEDULER_Task * shutdown_task
static char * res
Currently read line or NULL on EOF.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Helper library for handling HELLO URIs.
API to the peerstore service.
struct GNUNET_PILS_Handle * GNUNET_PILS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_PILS_PidChangeCallback pid_change_cb, void *cls)
Connect to the PILS service.
Definition pils_api.c:465
void GNUNET_PILS_disconnect(struct GNUNET_PILS_Handle *handle)
Disconnect from the PILS service.
Definition pils_api.c:488
struct GNUNET_PILS_Operation * GNUNET_PILS_sign_hello(struct GNUNET_PILS_Handle *handle, const struct GNUNET_HELLO_Builder *builder, struct GNUNET_TIME_Absolute et, GNUNET_PILS_SignResultCallback cb, void *cb_cls)
Create HELLO signature.
Definition pils_api.c:703
void GNUNET_PILS_cancel(struct GNUNET_PILS_Operation *op)
Cancel request.
Definition pils_api.c:623
Functions related to time.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
#define GNUNET_GETOPT_OPTION_END
Marker for the end of the list of options.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_flag(char shortName, const char *name, const char *description, int *val)
Allow user to specify a flag (which internally means setting an integer to 1/GNUNET_YES/GNUNET_OK.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition hello-uri.c:380
void GNUNET_HELLO_builder_free(struct GNUNET_HELLO_Builder *builder)
Release resources of a builder.
Definition hello-uri.c:398
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
Definition hello-uri.c:839
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_from_parser(const struct GNUNET_HELLO_Parser *parser, struct GNUNET_PeerIdentity *pid)
Allocate builder from parser.
Definition hello-uri.c:361
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_iterate(const struct GNUNET_HELLO_Parser *parser, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a parser.
Definition hello-uri.c:1011
struct GNUNET_MQ_Envelope * GNUNET_HELLO_parser_to_env(const struct GNUNET_HELLO_Parser *parser)
Generate envelope with GNUnet HELLO message (including peer ID) from a parser.
Definition hello-uri.c:939
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_expiration_time_from_msg(const struct GNUNET_MessageHeader *msg)
Get the expiration time for this HELLO.
Definition hello-uri.c:633
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_get_id(const struct GNUNET_HELLO_Parser *parser)
Get the PeerIdentity for this builder.
Definition hello-uri.c:354
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid)
Parse msg.
Definition hello-uri.c:416
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_url(const char *url)
Parse GNUnet HELLO url.
Definition hello-uri.c:699
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_to_url2(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig, struct GNUNET_TIME_Absolute validity, char **result)
Generate GNUnet HELLO URI from a builder.
Definition hello-uri.c:1315
struct GNUNET_MQ_Envelope * GNUNET_HELLO_builder_to_env(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig, struct GNUNET_TIME_Absolute expiration_time)
Generate envelope with GNUnet HELLO message (including peer ID) from a builder.
Definition hello-uri.c:1178
#define GNUNET_log(kind,...)
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
const struct GNUNET_MessageHeader * GNUNET_MQ_env_get_msg(const struct GNUNET_MQ_Envelope *env)
Obtain message contained in envelope.
Definition mq.c:896
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iteration_start(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Iterate over peerstore entries.
void GNUNET_PEERSTORE_iteration_next(struct GNUNET_PEERSTORE_IterateContext *ic, uint64_t limit)
Continue an iteration.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
void GNUNET_PEERSTORE_hello_add_cancel(struct GNUNET_PEERSTORE_StoreHelloContext *huc)
Cancel the request to add a hello.
void GNUNET_PEERSTORE_iteration_stop(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iteration.
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
struct GNUNET_PEERSTORE_StoreHelloContext * GNUNET_PEERSTORE_hello_add(struct GNUNET_PEERSTORE_Handle *h, const struct GNUNET_MessageHeader *msg, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Add hello to peerstore.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition program.c:407
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
enum GNUNET_GenericReturnValue GNUNET_STRINGS_fancy_time_to_relative(const char *fancy_time, struct GNUNET_TIME_Relative *rtime)
Convert a given fancy human-readable time to our internal representation.
Definition strings.c:259
#define GNUNET_TIME_UNIT_DAYS
One day.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition strings.c:665
#define _(String)
GNU gettext support macro.
Definition platform.h:179
an ECC signature using EdDSA.
Definition of a command line option.
Context for building (or parsing) HELLO URIs.
Definition hello-uri.c:185
Context for parsing HELLOs.
Definition hello-uri.c:233
A 512-bit hashcode.
Header for all communications.
Handle to the PEERSTORE service.
Context for a iterate request.
Context for a add hello uri request.
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.