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() */
63
64
#include <errno.h> /* perror() */
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
71
static int dh_bits = 1024;
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;
81
81
gnutls_session_t session;
82
82
gnutls_certificate_credentials_t cred;
84
84
} encrypted_session;
87
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){
90
89
gpgme_data_t dh_crypto, dh_plain;
103
102
gpgme_check_version(NULL);
104
rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
105
if (rc != GPG_ERR_NO_ERROR){
106
fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
107
gpgme_strsource(rc), gpgme_strerror(rc));
103
gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
111
105
/* Set GPGME home directory */
112
106
rc = gpgme_get_engine_info (&engine_info);
198
192
gpgme_data_release(dh_crypto);
200
194
/* Seek back to the beginning of the GPGME plaintext data buffer */
201
if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){
202
perror("pgpme_data_seek");
195
gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET);
207
199
if (new_packet_length + BUFFER_SIZE > new_packet_capacity){
251
static void debuggnutls(__attribute__((unused)) int level,
243
void debuggnutls(__attribute__((unused)) int level,
253
245
fprintf(stderr, "%s", string);
256
static int initgnutls(encrypted_session *es){
248
int initgnutls(encrypted_session *es){
261
253
fprintf(stderr, "Initializing GnuTLS\n");
264
256
if ((ret = gnutls_global_init ())
265
257
!= GNUTLS_E_SUCCESS) {
266
258
fprintf (stderr, "global_init: %s\n", safer_gnutls_strerror(ret));
284
276
fprintf(stderr, "Attempting to use OpenPGP certificate %s"
285
" and keyfile %s as GnuTLS credentials\n", pubkeyfile,
277
" and keyfile %s as GnuTLS credentials\n", CERTFILE,
289
281
ret = gnutls_certificate_set_openpgp_key_file
290
(es->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
282
(es->cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
291
283
if (ret != GNUTLS_E_SUCCESS) {
293
285
(stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
295
ret, pubkeyfile, seckeyfile);
287
ret, CERTFILE, KEYFILE);
296
288
fprintf(stdout, "The Error is: %s\n",
297
289
safer_gnutls_strerror(ret));
342
334
gnutls_certificate_server_set_request (es->session,
343
335
GNUTLS_CERT_IGNORE);
345
gnutls_dh_set_prime_bits (es->session, dh_bits);
337
gnutls_dh_set_prime_bits (es->session, DH_BITS);
350
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
351
__attribute__((unused)) const char *txt){}
342
void empty_log(__attribute__((unused)) AvahiLogLevel level,
343
__attribute__((unused)) const char *txt){}
353
static int start_mandos_communication(const char *ip, uint16_t port,
354
AvahiIfIndex if_index){
345
int start_mandos_communication(const char *ip, uint16_t port,
346
AvahiIfIndex if_index){
356
348
struct sockaddr_in6 to;
357
349
encrypted_session es;
405
397
fprintf(stderr, "Connection to: %s, port %d\n", ip, port);
406
char addrstr[INET6_ADDRSTRLEN] = "";
407
if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr,
408
sizeof(addrstr)) == NULL){
411
if(strcmp(addrstr, ip) != 0){
412
fprintf(stderr, "Canonical address form: %s\n",
413
addrstr, ntohs(to.sin6_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)); */
418
408
ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
635
/* Combines file name and path and returns the malloced new
636
string. some sane checks could/should be added */
637
static const char *combinepath(const char *first, const char *second){
638
size_t f_len = strlen(first);
639
size_t s_len = strlen(second);
640
char *tmp = malloc(f_len + s_len + 2);
645
memcpy(tmp, first, f_len);
649
memcpy(tmp + f_len + 1, second, s_len);
651
tmp[f_len + 1 + s_len] = '\0';
656
625
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
657
626
AvahiServerConfig config;
658
627
AvahiSServiceBrowser *sb = NULL;
662
630
int returncode = EXIT_SUCCESS;
663
631
const char *interface = NULL;
664
632
AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
665
633
char *connect_to = NULL;
667
debug_int = debug ? 1 : 0;
669
636
static struct option long_options[] = {
670
{"debug", no_argument, &debug_int, 1},
671
{"connect", required_argument, NULL, 'C'},
672
{"interface", required_argument, NULL, 'i'},
673
{"keydir", required_argument, NULL, 'd'},
674
{"seckey", required_argument, NULL, 'c'},
675
{"pubkey", required_argument, NULL, 'k'},
676
{"dh-bits", required_argument, NULL, 'D'},
637
{"debug", no_argument, (int *)&debug, 1},
638
{"connect", required_argument, 0, 'c'},
639
{"interface", required_argument, 0, 'i'},
679
642
int option_index = 0;