65
64
#include <errno.h> /* perror() */
69
68
#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"
71
75
#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";
77
78
bool debug = false;
79
/* Used for passing in values through all the callback functions */
81
AvahiSimplePoll *simple_poll;
81
gnutls_session_t session;
83
82
gnutls_certificate_credentials_t cred;
88
static ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
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){
91
89
gpgme_data_t dh_crypto, dh_plain;
252
static void debuggnutls(__attribute__((unused)) int level,
243
void debuggnutls(__attribute__((unused)) int level,
254
245
fprintf(stderr, "%s", string);
257
static int initgnutls(mandos_context *mc, gnutls_session_t *session,
258
gnutls_dh_params_t *dh_params){
248
int initgnutls(encrypted_session *es){
263
253
fprintf(stderr, "Initializing GnuTLS\n");
266
256
if ((ret = gnutls_global_init ())
267
257
!= GNUTLS_E_SUCCESS) {
268
258
fprintf (stderr, "global_init: %s\n", safer_gnutls_strerror(ret));
273
263
gnutls_global_set_log_level(11);
274
264
gnutls_global_set_log_function(debuggnutls);
277
267
/* openpgp credentials */
278
if ((ret = gnutls_certificate_allocate_credentials (&mc->cred))
268
if ((ret = gnutls_certificate_allocate_credentials (&es->cred))
279
269
!= GNUTLS_E_SUCCESS) {
280
270
fprintf (stderr, "memory error: %s\n",
281
271
safer_gnutls_strerror(ret));
286
276
fprintf(stderr, "Attempting to use OpenPGP certificate %s"
287
" and keyfile %s as GnuTLS credentials\n", pubkeyfile,
277
" and keyfile %s as GnuTLS credentials\n", CERTFILE,
291
281
ret = gnutls_certificate_set_openpgp_key_file
292
(mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
282
(es->cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
293
283
if (ret != GNUTLS_E_SUCCESS) {
295
285
(stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
297
ret, pubkeyfile, seckeyfile);
287
ret, CERTFILE, KEYFILE);
298
288
fprintf(stdout, "The Error is: %s\n",
299
289
safer_gnutls_strerror(ret));
303
293
//GnuTLS server initialization
304
if ((ret = gnutls_dh_params_init(dh_params))
294
if ((ret = gnutls_dh_params_init (&es->dh_params))
305
295
!= GNUTLS_E_SUCCESS) {
306
296
fprintf (stderr, "Error in dh parameter initialization: %s\n",
307
297
safer_gnutls_strerror(ret));
311
if ((ret = gnutls_dh_params_generate2(*dh_params, mc->dh_bits))
301
if ((ret = gnutls_dh_params_generate2 (es->dh_params, DH_BITS))
312
302
!= GNUTLS_E_SUCCESS) {
313
303
fprintf (stderr, "Error in prime generation: %s\n",
314
304
safer_gnutls_strerror(ret));
318
gnutls_certificate_set_dh_params(mc->cred, *dh_params);
308
gnutls_certificate_set_dh_params (es->cred, es->dh_params);
320
310
// GnuTLS session creation
321
if ((ret = gnutls_init(session, GNUTLS_SERVER))
311
if ((ret = gnutls_init (&es->session, GNUTLS_SERVER))
322
312
!= GNUTLS_E_SUCCESS){
323
313
fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
324
314
safer_gnutls_strerror(ret));
327
if ((ret = gnutls_priority_set_direct(*session, mc->priority, &err))
317
if ((ret = gnutls_priority_set_direct (es->session, "NORMAL", &err))
328
318
!= GNUTLS_E_SUCCESS) {
329
319
fprintf(stderr, "Syntax error at: %s\n", err);
330
320
fprintf(stderr, "GnuTLS error: %s\n",
406
397
fprintf(stderr, "Connection to: %s, port %d\n", ip, 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);
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)); */
418
408
ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
528
gnutls_bye (session, GNUTLS_SHUT_RDWR);
519
gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
531
gnutls_deinit (session);
532
gnutls_certificate_free_credentials (mc->cred);
522
gnutls_deinit (es.session);
523
gnutls_certificate_free_credentials (es.cred);
533
524
gnutls_global_deinit ();
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;
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) {
551
546
assert(r); /* Spurious warning */
553
548
/* Called whenever a service has been resolved successfully or
578
574
avahi_s_service_resolver_free(r);
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';
577
static void browse_callback(
578
AvahiSServiceBrowser *b,
579
AvahiIfIndex interface,
580
AvahiProtocol protocol,
581
AvahiBrowserEvent event,
585
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
588
AvahiServer *s = userdata;
589
assert(b); /* Spurious warning */
591
/* Called whenever a new services becomes available on the LAN or
592
is removed from the LAN */
596
case AVAHI_BROWSER_FAILURE:
598
fprintf(stderr, "(Browser) %s\n",
599
avahi_strerror(avahi_server_errno(server)));
600
avahi_simple_poll_quit(simple_poll);
603
case AVAHI_BROWSER_NEW:
604
/* We ignore the returned resolver object. In the callback
605
function we free it. If the server is terminated before
606
the callback function is called the server will free
607
the resolver for us. */
609
if (!(avahi_s_service_resolver_new(s, interface, protocol, name,
611
AVAHI_PROTO_INET6, 0,
612
resolve_callback, s)))
613
fprintf(stderr, "Failed to resolve service '%s': %s\n", name,
614
avahi_strerror(avahi_server_errno(s)));
617
case AVAHI_BROWSER_REMOVE:
620
case AVAHI_BROWSER_ALL_FOR_NOW:
621
case AVAHI_BROWSER_CACHE_EXHAUSTED:
649
626
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
650
627
AvahiServerConfig config;
651
628
AvahiSServiceBrowser *sb = NULL;
655
631
int returncode = EXIT_SUCCESS;
656
632
const char *interface = "eth0";
657
struct ifreq network;
633
unsigned int if_index;
659
634
char *connect_to = NULL;
660
AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
661
mandos_context mc = { .simple_poll = NULL, .server = NULL,
662
.dh_bits = 1024, .priority = "SECURE256"};
664
debug_int = debug ? 1 : 0;
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'},
637
static struct option long_options[] = {
638
{"debug", no_argument, (int *)&debug, 1},
639
{"connect", required_argument, 0, 'c'},
640
{"interface", required_argument, 0, 'i'},
677
643
int option_index = 0;