64
65
#include <errno.h> /* perror() */
68
69
#include <getopt.h>
71
#define CERT_ROOT "/conf/conf.d/cryptkeyreq/"
73
#define CERTFILE CERT_ROOT "openpgp-client.txt"
74
#define KEYFILE CERT_ROOT "openpgp-client-key.txt"
75
71
#define BUFFER_SIZE 256
73
static const char *keydir = "/conf/conf.d/mandos";
74
static const char *pubkeyfile = "pubkey.txt";
75
static const char *seckeyfile = "seckey.txt";
78
77
bool debug = false;
79
/* Used for passing in values through all the callback functions */
81
gnutls_session_t session;
81
AvahiSimplePoll *simple_poll;
82
83
gnutls_certificate_credentials_t cred;
83
gnutls_dh_params_t dh_params;
87
ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
88
char **new_packet, const char *homedir){
88
static ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
89
91
gpgme_data_t dh_crypto, dh_plain;
243
void debuggnutls(__attribute__((unused)) int level,
252
static void debuggnutls(__attribute__((unused)) int level,
245
254
fprintf(stderr, "%s", string);
248
int initgnutls(encrypted_session *es){
257
static int initgnutls(mandos_context *mc, gnutls_session_t *session,
258
gnutls_dh_params_t *dh_params){
253
263
fprintf(stderr, "Initializing GnuTLS\n");
256
266
if ((ret = gnutls_global_init ())
257
267
!= GNUTLS_E_SUCCESS) {
258
268
fprintf (stderr, "global_init: %s\n", safer_gnutls_strerror(ret));
263
273
gnutls_global_set_log_level(11);
264
274
gnutls_global_set_log_function(debuggnutls);
267
277
/* openpgp credentials */
268
if ((ret = gnutls_certificate_allocate_credentials (&es->cred))
278
if ((ret = gnutls_certificate_allocate_credentials (&mc->cred))
269
279
!= GNUTLS_E_SUCCESS) {
270
280
fprintf (stderr, "memory error: %s\n",
271
281
safer_gnutls_strerror(ret));
276
286
fprintf(stderr, "Attempting to use OpenPGP certificate %s"
277
" and keyfile %s as GnuTLS credentials\n", CERTFILE,
287
" and keyfile %s as GnuTLS credentials\n", pubkeyfile,
281
291
ret = gnutls_certificate_set_openpgp_key_file
282
(es->cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
292
(mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
283
293
if (ret != GNUTLS_E_SUCCESS) {
285
295
(stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
287
ret, CERTFILE, KEYFILE);
297
ret, pubkeyfile, seckeyfile);
288
298
fprintf(stdout, "The Error is: %s\n",
289
299
safer_gnutls_strerror(ret));
293
303
//GnuTLS server initialization
294
if ((ret = gnutls_dh_params_init (&es->dh_params))
304
if ((ret = gnutls_dh_params_init(dh_params))
295
305
!= GNUTLS_E_SUCCESS) {
296
306
fprintf (stderr, "Error in dh parameter initialization: %s\n",
297
307
safer_gnutls_strerror(ret));
301
if ((ret = gnutls_dh_params_generate2 (es->dh_params, DH_BITS))
311
if ((ret = gnutls_dh_params_generate2(*dh_params, mc->dh_bits))
302
312
!= GNUTLS_E_SUCCESS) {
303
313
fprintf (stderr, "Error in prime generation: %s\n",
304
314
safer_gnutls_strerror(ret));
308
gnutls_certificate_set_dh_params (es->cred, es->dh_params);
318
gnutls_certificate_set_dh_params(mc->cred, *dh_params);
310
320
// GnuTLS session creation
311
if ((ret = gnutls_init (&es->session, GNUTLS_SERVER))
321
if ((ret = gnutls_init(session, GNUTLS_SERVER))
312
322
!= GNUTLS_E_SUCCESS){
313
323
fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
314
324
safer_gnutls_strerror(ret));
317
if ((ret = gnutls_priority_set_direct (es->session, "NORMAL", &err))
327
if ((ret = gnutls_priority_set_direct(*session, mc->priority, &err))
318
328
!= GNUTLS_E_SUCCESS) {
319
329
fprintf(stderr, "Syntax error at: %s\n", err);
320
330
fprintf(stderr, "GnuTLS error: %s\n",
397
406
fprintf(stderr, "Connection to: %s, port %d\n", ip, port);
398
/* char addrstr[INET6_ADDRSTRLEN]; */
399
/* if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr, */
400
/* sizeof(addrstr)) == NULL){ */
401
/* perror("inet_ntop"); */
403
/* fprintf(stderr, "Really connecting to: %s, port %d\n", */
404
/* addrstr, ntohs(to.sin6_port)); */
407
char addrstr[INET6_ADDRSTRLEN] = "";
408
if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr,
409
sizeof(addrstr)) == NULL){
412
if(strcmp(addrstr, ip) != 0){
413
fprintf(stderr, "Canonical address form: %s\n", addrstr);
408
418
ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
519
gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
528
gnutls_bye (session, GNUTLS_SHUT_RDWR);
522
gnutls_deinit (es.session);
523
gnutls_certificate_free_credentials (es.cred);
531
gnutls_deinit (session);
532
gnutls_certificate_free_credentials (mc->cred);
524
533
gnutls_global_deinit ();
528
static AvahiSimplePoll *simple_poll = NULL;
529
static AvahiServer *server = NULL;
531
static void resolve_callback(
532
AvahiSServiceResolver *r,
533
AvahiIfIndex interface,
534
AVAHI_GCC_UNUSED AvahiProtocol protocol,
535
AvahiResolverEvent event,
539
const char *host_name,
540
const AvahiAddress *address,
542
AVAHI_GCC_UNUSED AvahiStringList *txt,
543
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
544
AVAHI_GCC_UNUSED void* userdata) {
537
static void resolve_callback( AvahiSServiceResolver *r,
538
AvahiIfIndex interface,
539
AVAHI_GCC_UNUSED AvahiProtocol protocol,
540
AvahiResolverEvent event,
544
const char *host_name,
545
const AvahiAddress *address,
547
AVAHI_GCC_UNUSED AvahiStringList *txt,
548
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
550
mandos_context *mc = userdata;
546
551
assert(r); /* Spurious warning */
548
553
/* Called whenever a service has been resolved successfully or
573
578
avahi_s_service_resolver_free(r);
576
static void browse_callback(
577
AvahiSServiceBrowser *b,
578
AvahiIfIndex interface,
579
AvahiProtocol protocol,
580
AvahiBrowserEvent event,
584
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
587
AvahiServer *s = userdata;
588
assert(b); /* Spurious warning */
590
/* Called whenever a new services becomes available on the LAN or
591
is removed from the LAN */
595
case AVAHI_BROWSER_FAILURE:
597
fprintf(stderr, "(Browser) %s\n",
598
avahi_strerror(avahi_server_errno(server)));
599
avahi_simple_poll_quit(simple_poll);
602
case AVAHI_BROWSER_NEW:
603
/* We ignore the returned resolver object. In the callback
604
function we free it. If the server is terminated before
605
the callback function is called the server will free
606
the resolver for us. */
608
if (!(avahi_s_service_resolver_new(s, interface, protocol, name,
610
AVAHI_PROTO_INET6, 0,
611
resolve_callback, s)))
612
fprintf(stderr, "Failed to resolve service '%s': %s\n", name,
613
avahi_strerror(avahi_server_errno(s)));
616
case AVAHI_BROWSER_REMOVE:
619
case AVAHI_BROWSER_ALL_FOR_NOW:
620
case AVAHI_BROWSER_CACHE_EXHAUSTED:
581
static void browse_callback( AvahiSServiceBrowser *b,
582
AvahiIfIndex interface,
583
AvahiProtocol protocol,
584
AvahiBrowserEvent event,
588
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
590
mandos_context *mc = userdata;
591
assert(b); /* Spurious warning */
593
/* Called whenever a new services becomes available on the LAN or
594
is removed from the LAN */
598
case AVAHI_BROWSER_FAILURE:
600
fprintf(stderr, "(Browser) %s\n",
601
avahi_strerror(avahi_server_errno(mc->server)));
602
avahi_simple_poll_quit(mc->simple_poll);
605
case AVAHI_BROWSER_NEW:
606
/* We ignore the returned resolver object. In the callback
607
function we free it. If the server is terminated before
608
the callback function is called the server will free
609
the resolver for us. */
611
if (!(avahi_s_service_resolver_new(mc->server, interface, protocol, name,
613
AVAHI_PROTO_INET6, 0,
614
resolve_callback, mc)))
615
fprintf(stderr, "Failed to resolve service '%s': %s\n", name,
616
avahi_strerror(avahi_server_errno(mc->server)));
619
case AVAHI_BROWSER_REMOVE:
622
case AVAHI_BROWSER_ALL_FOR_NOW:
623
case AVAHI_BROWSER_CACHE_EXHAUSTED:
628
/* Combines file name and path and returns the malloced new
629
string. some sane checks could/should be added */
630
static const char *combinepath(const char *first, const char *second){
631
size_t f_len = strlen(first);
632
size_t s_len = strlen(second);
633
char *tmp = malloc(f_len + s_len + 2);
638
memcpy(tmp, first, f_len); /* Spurious warning */
642
memcpy(tmp + f_len + 1, second, s_len); /* Spurious warning */
644
tmp[f_len + 1 + s_len] = '\0';
625
649
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
626
650
AvahiServerConfig config;
627
651
AvahiSServiceBrowser *sb = NULL;
630
655
int returncode = EXIT_SUCCESS;
631
const char *interface = NULL;
656
const char *interface = "eth0";
657
struct ifreq network;
659
char *connect_to = NULL;
632
660
AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
633
char *connect_to = NULL;
661
mandos_context mc = { .simple_poll = NULL, .server = NULL,
662
.dh_bits = 1024, .priority = "SECURE256"};
664
debug_int = debug ? 1 : 0;
636
static struct option long_options[] = {
637
{"debug", no_argument, (int *)&debug, 1},
638
{"connect", required_argument, 0, 'c'},
639
{"interface", required_argument, 0, 'i'},
666
struct option long_options[] = {
667
{"debug", no_argument, &debug_int, 1},
668
{"connect", required_argument, NULL, 'c'},
669
{"interface", required_argument, NULL, 'i'},
670
{"keydir", required_argument, NULL, 'd'},
671
{"seckey", required_argument, NULL, 's'},
672
{"pubkey", required_argument, NULL, 'p'},
673
{"dh-bits", required_argument, NULL, 'D'},
674
{"priority", required_argument, NULL, 'P'},
642
677
int option_index = 0;