8
8
* includes the following functions: "resolve_callback",
9
9
* "browse_callback", and parts of "main".
12
* Copyright © 2007-2008 Teddy Hogeborn & Björn Påhlsson
11
* Everything else is Copyright © 2007-2008 Teddy Hogeborn and Björn
14
14
* This program is free software: you can redistribute it and/or
15
15
* modify it under the terms of the GNU General Public License as
25
25
* along with this program. If not, see
26
26
* <http://www.gnu.org/licenses/>.
28
* Contact the authors at <mandos@fukt.bsnet.se>.
28
* Contact the authors at <https://www.fukt.bsnet.se/~belorn/> and
29
* <https://www.fukt.bsnet.se/~teddy/>.
31
/* Needed by GPGME, specifically gpgme_data_seek() */
32
#define _FORTIFY_SOURCE 2
32
34
#define _LARGEFILE_SOURCE
33
35
#define _FILE_OFFSET_BITS 64
67
69
#include <getopt.h>
72
#define CERT_ROOT "/conf/conf.d/cryptkeyreq/"
74
#define CERTFILE CERT_ROOT "openpgp-client.txt"
75
#define KEYFILE CERT_ROOT "openpgp-client-key.txt"
69
76
#define BUFFER_SIZE 256
70
77
#define DH_BITS 1024
72
const char *certdir = "/conf/conf.d/cryptkeyreq/";
73
const char *certfile = "openpgp-client.txt";
74
const char *certkey = "openpgp-client-key.txt";
76
79
bool debug = false;
100
103
gpgme_check_version(NULL);
101
rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
102
if (rc != GPG_ERR_NO_ERROR){
103
fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
104
gpgme_strsource(rc), gpgme_strerror(rc));
104
gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
108
106
/* Set GPGME home directory */
109
107
rc = gpgme_get_engine_info (&engine_info);
195
193
gpgme_data_release(dh_crypto);
197
195
/* Seek back to the beginning of the GPGME plaintext data buffer */
198
if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){
199
perror("pgpme_data_seek");
196
gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET);
204
200
if (new_packet_length + BUFFER_SIZE > new_packet_capacity){
258
254
fprintf(stderr, "Initializing GnuTLS\n");
261
257
if ((ret = gnutls_global_init ())
262
258
!= GNUTLS_E_SUCCESS) {
263
259
fprintf (stderr, "global_init: %s\n", safer_gnutls_strerror(ret));
281
277
fprintf(stderr, "Attempting to use OpenPGP certificate %s"
282
" and keyfile %s as GnuTLS credentials\n", certfile,
278
" and keyfile %s as GnuTLS credentials\n", CERTFILE,
286
282
ret = gnutls_certificate_set_openpgp_key_file
287
(es->cred, certfile, certkey, GNUTLS_OPENPGP_FMT_BASE64);
283
(es->cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
288
284
if (ret != GNUTLS_E_SUCCESS) {
290
286
(stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
292
ret, certfile, certkey);
288
ret, CERTFILE, KEYFILE);
293
289
fprintf(stdout, "The Error is: %s\n",
294
290
safer_gnutls_strerror(ret));
362
358
char interface[IF_NAMESIZE];
365
fprintf(stderr, "Setting up a tcp connection to %s, port %d\n",
361
fprintf(stderr, "Setting up a tcp connection to %s\n", ip);
369
364
tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
399
394
to.sin6_scope_id = (uint32_t)if_index;
402
fprintf(stderr, "Connection to: %s, port %d\n", ip, port);
403
/* char addrstr[INET6_ADDRSTRLEN]; */
404
/* if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr, */
405
/* sizeof(addrstr)) == NULL){ */
406
/* perror("inet_ntop"); */
408
/* fprintf(stderr, "Really connecting to: %s, port %d\n", */
409
/* addrstr, ntohs(to.sin6_port)); */
397
fprintf(stderr, "Connection to: %s\n", ip);
413
400
ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
492
479
decrypted_buffer_size = pgp_packet_decrypt(buffer,
494
481
&decrypted_buffer,
496
483
if (decrypted_buffer_size >= 0){
497
while(written < (size_t) decrypted_buffer_size){
484
while(written < decrypted_buffer_size){
498
485
ret = (int)fwrite (decrypted_buffer + written, 1,
499
486
(size_t)decrypted_buffer_size - written,
569
556
fprintf(stderr, "Mandos server \"%s\" found on %s (%s) on"
570
557
" port %d\n", name, host_name, ip, port);
572
int ret = start_mandos_communication(ip, port, interface);
559
int ret = start_mandos_communication(ip, port,
560
(unsigned int) interface);
574
562
exit(EXIT_SUCCESS);
630
/* combinds file name and path and returns the malloced new string. som sane checks could/should be added */
631
const char *combinepath(const char *first, const char *second){
633
tmp = malloc(strlen(first) + strlen(second) + 2);
639
if (first[0] != '\0' and first[strlen(first) - 1] != '/'){
647
618
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
648
619
AvahiServerConfig config;
649
620
AvahiSServiceBrowser *sb = NULL;
652
623
int returncode = EXIT_SUCCESS;
653
const char *interface = NULL;
654
AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
655
char *connect_to = NULL;
624
const char *interface = "eth0";
658
627
static struct option long_options[] = {
659
628
{"debug", no_argument, (int *)&debug, 1},
660
{"connect", required_argument, 0, 'C'},
661
629
{"interface", required_argument, 0, 'i'},
662
{"certdir", required_argument, 0, 'd'},
663
{"certkey", required_argument, 0, 'c'},
664
{"certfile", required_argument, 0, 'k'},
667
632
int option_index = 0;
679
644
interface = optarg;
694
647
exit(EXIT_FAILURE);
698
certfile = combinepath(certdir, certfile);
699
if (certfile == NULL){
703
if(interface != NULL){
704
if_index = (AvahiIfIndex) if_nametoindex(interface);
706
fprintf(stderr, "No such interface: \"%s\"\n", interface);
711
if(connect_to != NULL){
712
/* Connect directly, do not use Zeroconf */
713
/* (Mainly meant for debugging) */
714
char *address = strrchr(connect_to, ':');
716
fprintf(stderr, "No colon in address\n");
720
uint16_t port = (uint16_t) strtol(address+1, NULL, 10);
722
perror("Bad port number");
726
address = connect_to;
727
ret = start_mandos_communication(address, port, if_index);
735
certkey = combinepath(certdir, certkey);
736
if (certkey == NULL){
741
652
avahi_set_log_function(empty_log);
776
687
/* Create the service browser */
777
sb = avahi_s_service_browser_new(server, if_index,
688
sb = avahi_s_service_browser_new(server,
690
if_nametoindex(interface),
778
691
AVAHI_PROTO_INET6,
779
692
"_mandos._tcp", NULL, 0,
780
693
browse_callback, server);