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
32
/* Needed by GPGME, specifically gpgme_data_seek() */
67
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"
69
75
#define BUFFER_SIZE 256
70
76
#define DH_BITS 1024
72
static const char *certdir = "/conf/conf.d/mandos";
73
static const char *certfile = "openpgp-client.txt";
74
static const char *certkey = "openpgp-client-key.txt";
76
78
bool debug = false;
82
84
} encrypted_session;
85
static ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
87
ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
88
char **new_packet, const char *homedir){
88
89
gpgme_data_t dh_crypto, dh_plain;
101
102
gpgme_check_version(NULL);
102
rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
103
if (rc != GPG_ERR_NO_ERROR){
104
fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
105
gpgme_strsource(rc), gpgme_strerror(rc));
103
gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
109
105
/* Set GPGME home directory */
110
106
rc = gpgme_get_engine_info (&engine_info);
196
192
gpgme_data_release(dh_crypto);
198
194
/* Seek back to the beginning of the GPGME plaintext data buffer */
199
if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){
200
perror("pgpme_data_seek");
195
gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET);
205
199
if (new_packet_length + BUFFER_SIZE > new_packet_capacity){
249
static void debuggnutls(__attribute__((unused)) int level,
243
void debuggnutls(__attribute__((unused)) int level,
251
245
fprintf(stderr, "%s", string);
254
static int initgnutls(encrypted_session *es){
248
int initgnutls(encrypted_session *es){
259
253
fprintf(stderr, "Initializing GnuTLS\n");
262
256
if ((ret = gnutls_global_init ())
263
257
!= GNUTLS_E_SUCCESS) {
264
258
fprintf (stderr, "global_init: %s\n", safer_gnutls_strerror(ret));
282
276
fprintf(stderr, "Attempting to use OpenPGP certificate %s"
283
" and keyfile %s as GnuTLS credentials\n", certfile,
277
" and keyfile %s as GnuTLS credentials\n", CERTFILE,
287
281
ret = gnutls_certificate_set_openpgp_key_file
288
(es->cred, certfile, certkey, GNUTLS_OPENPGP_FMT_BASE64);
282
(es->cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
289
283
if (ret != GNUTLS_E_SUCCESS) {
291
285
(stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
293
ret, certfile, certkey);
287
ret, CERTFILE, KEYFILE);
294
288
fprintf(stdout, "The Error is: %s\n",
295
289
safer_gnutls_strerror(ret));
348
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
349
__attribute__((unused)) const char *txt){}
342
void empty_log(__attribute__((unused)) AvahiLogLevel level,
343
__attribute__((unused)) const char *txt){}
351
static int start_mandos_communication(const char *ip, uint16_t port,
352
AvahiIfIndex if_index){
345
int start_mandos_communication(const char *ip, uint16_t port,
346
unsigned int if_index){
354
348
struct sockaddr_in6 to;
355
349
encrypted_session es;
493
487
decrypted_buffer_size = pgp_packet_decrypt(buffer,
495
489
&decrypted_buffer,
497
491
if (decrypted_buffer_size >= 0){
498
492
while(written < (size_t) decrypted_buffer_size){
499
493
ret = (int)fwrite (decrypted_buffer + written, 1,
570
564
fprintf(stderr, "Mandos server \"%s\" found on %s (%s) on"
571
565
" port %d\n", name, host_name, ip, port);
573
int ret = start_mandos_communication(ip, port, interface);
567
int ret = start_mandos_communication(ip, port,
568
(unsigned int) interface);
575
570
exit(EXIT_SUCCESS);
631
/* Combines file name and path and returns the malloced new
632
string. some sane checks could/should be added */
633
static const char *combinepath(const char *first, const char *second){
634
size_t f_len = strlen(first);
635
size_t s_len = strlen(second);
636
char *tmp = malloc(f_len + s_len + 2);
641
memcpy(tmp, first, f_len);
645
memcpy(tmp + f_len + 1, second, s_len);
647
tmp[f_len + 1 + s_len] = '\0';
652
626
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
653
627
AvahiServerConfig config;
654
628
AvahiSServiceBrowser *sb = NULL;
657
631
int returncode = EXIT_SUCCESS;
658
const char *interface = NULL;
659
AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
632
const char *interface = "eth0";
633
unsigned int if_index;
660
634
char *connect_to = NULL;
663
637
static struct option long_options[] = {
664
638
{"debug", no_argument, (int *)&debug, 1},
665
{"connect", required_argument, 0, 'C'},
639
{"connect", required_argument, 0, 'c'},
666
640
{"interface", required_argument, 0, 'i'},
667
{"certdir", required_argument, 0, 'd'},
668
{"certkey", required_argument, 0, 'c'},
669
{"certfile", required_argument, 0, 'k'},
672
643
int option_index = 0;
684
655
interface = optarg;
687
658
connect_to = optarg;
699
661
exit(EXIT_FAILURE);
703
certfile = combinepath(certdir, certfile);
704
if (certfile == NULL){
705
perror("combinepath");
709
if(interface != NULL){
710
if_index = (AvahiIfIndex) if_nametoindex(interface);
712
fprintf(stderr, "No such interface: \"%s\"\n", interface);
665
if_index = if_nametoindex(interface);
667
fprintf(stderr, "No such interface: \"%s\"\n", interface);
717
671
if(connect_to != NULL){
783
731
/* Create the service browser */
784
sb = avahi_s_service_browser_new(server, if_index,
732
sb = avahi_s_service_browser_new(server, (AvahiIfIndex)if_index,
785
733
AVAHI_PROTO_INET6,
786
734
"_mandos._tcp", NULL, 0,
787
735
browse_callback, server);