/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1
/*  -*- coding: utf-8 -*- */
2
/*
3
 * Mandos client - get and decrypt data from a Mandos server
4
 *
5
 * This program is partly derived from an example program for an Avahi
6
 * service browser, downloaded from
7
 * <http://avahi.org/browser/examples/core-browse-services.c>.  This
8
 * includes the following functions: "resolve_callback",
9
 * "browse_callback", and parts of "main".
10
 * 
28 by Teddy Hogeborn
* server.conf: New file.
11
 * Everything else is
12
 * Copyright © 2007-2008 Teddy Hogeborn & Björn Påhlsson
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
13
 * 
14
 * This program is free software: you can redistribute it and/or
15
 * modify it under the terms of the GNU General Public License as
16
 * published by the Free Software Foundation, either version 3 of the
17
 * License, or (at your option) any later version.
18
 * 
19
 * This program is distributed in the hope that it will be useful, but
20
 * WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
 * General Public License for more details.
23
 * 
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program.  If not, see
26
 * <http://www.gnu.org/licenses/>.
27
 * 
31 by Teddy Hogeborn
* plugins.d/plugbasedclient.c: Update include file comments.
28
 * Contact the authors at <mandos@fukt.bsnet.se>.
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
29
 */
30
28 by Teddy Hogeborn
* server.conf: New file.
31
/* Needed by GPGME, specifically gpgme_data_seek() */
13 by Björn Påhlsson
Added following support:
32
#define _LARGEFILE_SOURCE
33
#define _FILE_OFFSET_BITS 64
34
24.1.10 by Björn Påhlsson
merge commit
35
#define _GNU_SOURCE		/* TEMP_FAILURE_RETRY() */
36
13 by Björn Påhlsson
Added following support:
37
#include <stdio.h>
38
#include <assert.h>
39
#include <stdlib.h>
40
#include <time.h>
41
#include <net/if.h>		/* if_nametoindex */
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
42
#include <sys/ioctl.h>          /* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
43
				   SIOCSIFFLAGS */
44
#include <net/if.h>		/* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
45
				   SIOCSIFFLAGS */
13 by Björn Påhlsson
Added following support:
46
47
#include <avahi-core/core.h>
48
#include <avahi-core/lookup.h>
49
#include <avahi-core/log.h>
50
#include <avahi-common/simple-watch.h>
51
#include <avahi-common/malloc.h>
52
#include <avahi-common/error.h>
53
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
54
/* Mandos client part */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
55
#include <sys/types.h>		/* socket(), inet_pton() */
56
#include <sys/socket.h>		/* socket(), struct sockaddr_in6,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
57
				   struct in6_addr, inet_pton() */
58
#include <gnutls/gnutls.h>	/* All GnuTLS stuff */
59
#include <gnutls/openpgp.h>	/* GnuTLS with openpgp stuff */
13 by Björn Påhlsson
Added following support:
60
61
#include <unistd.h>		/* close() */
62
#include <netinet/in.h>
63
#include <stdbool.h>		/* true */
64
#include <string.h>		/* memset */
65
#include <arpa/inet.h>		/* inet_pton() */
66
#include <iso646.h>		/* not */
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
67
#include <net/if.h>		/* IF_NAMESIZE */
24.1.14 by Björn Påhlsson
mandosclient
68
#include <argp.h>		/* struct argp_option,
69
				   struct argp_state, struct argp,
70
				   argp_parse() */
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
71
/* GPGME */
13 by Björn Påhlsson
Added following support:
72
#include <errno.h>		/* perror() */
73
#include <gpgme.h>
74
75
#define BUFFER_SIZE 256
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
76
15.1.2 by Björn Påhlsson
Added debug options from passprompt as --debug and --debug=passprompt
77
bool debug = false;
24.1.14 by Björn Påhlsson
mandosclient
78
const char *keydir = "/conf/conf.d/mandos";
79
const char *argp_program_version = "mandosclient 0.9";
80
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
24.1.10 by Björn Påhlsson
merge commit
81
const char mandos_protocol_version[] = "1";
82
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
83
/* Used for passing in values through all the callback functions */
13 by Björn Påhlsson
Added following support:
84
typedef struct {
24.1.9 by Björn Påhlsson
not working midwork...
85
  AvahiSimplePoll *simple_poll;
86
  AvahiServer *server;
13 by Björn Påhlsson
Added following support:
87
  gnutls_certificate_credentials_t cred;
24.1.9 by Björn Påhlsson
not working midwork...
88
  unsigned int dh_bits;
24.1.13 by Björn Påhlsson
mandosclient
89
  gnutls_dh_params_t dh_params;
24.1.9 by Björn Påhlsson
not working midwork...
90
  const char *priority;
91
} mandos_context;
13 by Björn Påhlsson
Added following support:
92
24.1.12 by Björn Påhlsson
merge +
93
size_t adjustbuffer(char **buffer, size_t buffer_length,
24.1.10 by Björn Påhlsson
merge commit
94
		  size_t buffer_capacity){
95
  if (buffer_length + BUFFER_SIZE > buffer_capacity){
24.1.12 by Björn Påhlsson
merge +
96
    *buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
24.1.10 by Björn Påhlsson
merge commit
97
    if (buffer == NULL){
98
      return 0;
99
    }
100
    buffer_capacity += BUFFER_SIZE;
101
  }
102
  return buffer_capacity;
103
}
104
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
105
/* 
106
 * Decrypt OpenPGP data using keyrings in HOMEDIR.
107
 * Returns -1 on error
108
 */
109
static ssize_t pgp_packet_decrypt (const char *cryptotext,
110
				   size_t crypto_size,
111
				   char **plaintext,
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
112
				   const char *homedir){
13 by Björn Påhlsson
Added following support:
113
  gpgme_data_t dh_crypto, dh_plain;
114
  gpgme_ctx_t ctx;
115
  gpgme_error_t rc;
116
  ssize_t ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
117
  size_t plaintext_capacity = 0;
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
118
  ssize_t plaintext_length = 0;
13 by Björn Påhlsson
Added following support:
119
  gpgme_engine_info_t engine_info;
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
120
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
121
  if (debug){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
122
    fprintf(stderr, "Trying to decrypt OpenPGP data\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
123
  }
124
  
13 by Björn Påhlsson
Added following support:
125
  /* Init GPGME */
126
  gpgme_check_version(NULL);
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
127
  rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
128
  if (rc != GPG_ERR_NO_ERROR){
129
    fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
130
	    gpgme_strsource(rc), gpgme_strerror(rc));
131
    return -1;
132
  }
13 by Björn Påhlsson
Added following support:
133
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
134
  /* Set GPGME home directory for the OpenPGP engine only */
13 by Björn Påhlsson
Added following support:
135
  rc = gpgme_get_engine_info (&engine_info);
136
  if (rc != GPG_ERR_NO_ERROR){
137
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
138
	    gpgme_strsource(rc), gpgme_strerror(rc));
139
    return -1;
140
  }
141
  while(engine_info != NULL){
142
    if(engine_info->protocol == GPGME_PROTOCOL_OpenPGP){
143
      gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
144
			    engine_info->file_name, homedir);
145
      break;
146
    }
147
    engine_info = engine_info->next;
148
  }
149
  if(engine_info == NULL){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
150
    fprintf(stderr, "Could not set GPGME home dir to %s\n", homedir);
13 by Björn Påhlsson
Added following support:
151
    return -1;
152
  }
153
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
154
  /* Create new GPGME data buffer from memory cryptotext */
155
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
156
			       0);
13 by Björn Påhlsson
Added following support:
157
  if (rc != GPG_ERR_NO_ERROR){
158
    fprintf(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
159
	    gpgme_strsource(rc), gpgme_strerror(rc));
160
    return -1;
161
  }
162
  
163
  /* Create new empty GPGME data buffer for the plaintext */
164
  rc = gpgme_data_new(&dh_plain);
165
  if (rc != GPG_ERR_NO_ERROR){
166
    fprintf(stderr, "bad gpgme_data_new: %s: %s\n",
167
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
168
    gpgme_data_release(dh_crypto);
13 by Björn Påhlsson
Added following support:
169
    return -1;
170
  }
171
  
172
  /* Create new GPGME "context" */
173
  rc = gpgme_new(&ctx);
174
  if (rc != GPG_ERR_NO_ERROR){
175
    fprintf(stderr, "bad gpgme_new: %s: %s\n",
176
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
177
    plaintext_length = -1;
178
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
179
  }
180
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
181
  /* Decrypt data from the cryptotext data buffer to the plaintext
182
     data buffer */
13 by Björn Påhlsson
Added following support:
183
  rc = gpgme_op_decrypt(ctx, dh_crypto, dh_plain);
184
  if (rc != GPG_ERR_NO_ERROR){
185
    fprintf(stderr, "bad gpgme_op_decrypt: %s: %s\n",
186
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
187
    plaintext_length = -1;
188
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
189
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
190
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
191
  if(debug){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
192
    fprintf(stderr, "Decryption of OpenPGP data succeeded\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
193
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
194
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
195
  if (debug){
196
    gpgme_decrypt_result_t result;
197
    result = gpgme_op_decrypt_result(ctx);
198
    if (result == NULL){
199
      fprintf(stderr, "gpgme_op_decrypt_result failed\n");
200
    } else {
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
201
      fprintf(stderr, "Unsupported algorithm: %s\n",
202
	      result->unsupported_algorithm);
203
      fprintf(stderr, "Wrong key usage: %d\n",
204
	      result->wrong_key_usage);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
205
      if(result->file_name != NULL){
206
	fprintf(stderr, "File name: %s\n", result->file_name);
207
      }
208
      gpgme_recipient_t recipient;
209
      recipient = result->recipients;
210
      if(recipient){
211
	while(recipient != NULL){
212
	  fprintf(stderr, "Public key algorithm: %s\n",
213
		  gpgme_pubkey_algo_name(recipient->pubkey_algo));
214
	  fprintf(stderr, "Key ID: %s\n", recipient->keyid);
215
	  fprintf(stderr, "Secret key available: %s\n",
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
216
		  recipient->status == GPG_ERR_NO_SECKEY
217
		  ? "No" : "Yes");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
218
	  recipient = recipient->next;
219
	}
220
      }
221
    }
222
  }
13 by Björn Påhlsson
Added following support:
223
  
224
  /* Seek back to the beginning of the GPGME plaintext data buffer */
24.1.5 by Björn Påhlsson
plugbasedclient:
225
  if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){
226
    perror("pgpme_data_seek");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
227
    plaintext_length = -1;
228
    goto decrypt_end;
24.1.5 by Björn Påhlsson
plugbasedclient:
229
  }
230
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
231
  *plaintext = NULL;
13 by Björn Påhlsson
Added following support:
232
  while(true){
24.1.12 by Björn Påhlsson
merge +
233
    plaintext_capacity = adjustbuffer(plaintext, (size_t)plaintext_length,
234
				      plaintext_capacity);
235
    if (plaintext_capacity == 0){
24.1.10 by Björn Påhlsson
merge commit
236
	perror("adjustbuffer");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
237
	plaintext_length = -1;
238
	goto decrypt_end;
13 by Björn Påhlsson
Added following support:
239
    }
240
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
241
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
242
			  BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
243
    /* Print the data, if any */
244
    if (ret == 0){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
245
      /* EOF */
13 by Björn Påhlsson
Added following support:
246
      break;
247
    }
248
    if(ret < 0){
249
      perror("gpgme_data_read");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
250
      plaintext_length = -1;
251
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
252
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
253
    plaintext_length += ret;
13 by Björn Påhlsson
Added following support:
254
  }
255
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
256
  if(debug){
257
    fprintf(stderr, "Decrypted password is: ");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
258
    for(ssize_t i = 0; i < plaintext_length; i++){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
259
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
260
    }
261
    fprintf(stderr, "\n");
262
  }
263
  
264
 decrypt_end:
265
  
266
  /* Delete the GPGME cryptotext data buffer */
267
  gpgme_data_release(dh_crypto);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
268
  
269
  /* Delete the GPGME plaintext data buffer */
13 by Björn Påhlsson
Added following support:
270
  gpgme_data_release(dh_plain);
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
271
  return plaintext_length;
13 by Björn Påhlsson
Added following support:
272
}
273
274
static const char * safer_gnutls_strerror (int value) {
275
  const char *ret = gnutls_strerror (value);
276
  if (ret == NULL)
277
    ret = "(unknown)";
278
  return ret;
279
}
280
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
281
/* GnuTLS log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
282
static void debuggnutls(__attribute__((unused)) int level,
283
			const char* string){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
284
  fprintf(stderr, "GnuTLS: %s", string);
13 by Björn Påhlsson
Added following support:
285
}
286
24.1.14 by Björn Påhlsson
mandosclient
287
static int init_gnutls_global(mandos_context *mc,
288
			      const char *pubkeyfile,
289
			      const char *seckeyfile){
13 by Björn Påhlsson
Added following support:
290
  int ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
291
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
292
  if(debug){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
293
    fprintf(stderr, "Initializing GnuTLS\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
294
  }
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
295
13 by Björn Påhlsson
Added following support:
296
  if ((ret = gnutls_global_init ())
297
      != GNUTLS_E_SUCCESS) {
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
298
    fprintf (stderr, "GnuTLS global_init: %s\n",
299
	     safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
300
    return -1;
301
  }
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
302
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
303
  if (debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
304
    /* "Use a log level over 10 to enable all debugging options."
305
     * - GnuTLS manual
306
     */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
307
    gnutls_global_set_log_level(11);
308
    gnutls_global_set_log_function(debuggnutls);
309
  }
310
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
311
  /* OpenPGP credentials */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
312
  if ((ret = gnutls_certificate_allocate_credentials (&mc->cred))
13 by Björn Påhlsson
Added following support:
313
      != GNUTLS_E_SUCCESS) {
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
314
    fprintf (stderr, "GnuTLS memory error: %s\n",
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
315
	     safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
316
    return -1;
317
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
318
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
319
  if(debug){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
320
    fprintf(stderr, "Attempting to use OpenPGP certificate %s"
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
321
	    " and keyfile %s as GnuTLS credentials\n", pubkeyfile,
322
	    seckeyfile);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
323
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
324
  
13 by Björn Påhlsson
Added following support:
325
  ret = gnutls_certificate_set_openpgp_key_file
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
326
    (mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
13 by Björn Påhlsson
Added following support:
327
  if (ret != GNUTLS_E_SUCCESS) {
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
328
    fprintf(stderr,
329
	    "Error[%d] while reading the OpenPGP key pair ('%s',"
330
	    " '%s')\n", ret, pubkeyfile, seckeyfile);
331
    fprintf(stdout, "The GnuTLS error is: %s\n",
13 by Björn Påhlsson
Added following support:
332
	    safer_gnutls_strerror(ret));
333
    return -1;
334
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
335
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
336
  /* GnuTLS server initialization */
24.1.13 by Björn Påhlsson
mandosclient
337
  ret = gnutls_dh_params_init(&mc->dh_params);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
338
  if (ret != GNUTLS_E_SUCCESS) {
339
    fprintf (stderr, "Error in GnuTLS DH parameter initialization:"
340
	     " %s\n", safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
341
    return -1;
342
  }
24.1.13 by Björn Påhlsson
mandosclient
343
  ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
344
  if (ret != GNUTLS_E_SUCCESS) {
345
    fprintf (stderr, "Error in GnuTLS prime generation: %s\n",
13 by Björn Påhlsson
Added following support:
346
	     safer_gnutls_strerror(ret));
347
    return -1;
348
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
349
  
24.1.13 by Björn Påhlsson
mandosclient
350
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
351
352
  return 0;
353
}
354
355
static int init_gnutls_session(mandos_context *mc, gnutls_session_t *session){
356
  int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
357
  /* GnuTLS session creation */
358
  ret = gnutls_init(session, GNUTLS_SERVER);
359
  if (ret != GNUTLS_E_SUCCESS){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
360
    fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
13 by Björn Påhlsson
Added following support:
361
	    safer_gnutls_strerror(ret));
362
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
363
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
364
  {
365
    const char *err;
366
    ret = gnutls_priority_set_direct(*session, mc->priority, &err);
367
    if (ret != GNUTLS_E_SUCCESS) {
368
      fprintf(stderr, "Syntax error at: %s\n", err);
369
      fprintf(stderr, "GnuTLS error: %s\n",
370
	      safer_gnutls_strerror(ret));
371
      return -1;
372
    }
13 by Björn Påhlsson
Added following support:
373
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
374
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
375
  ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
376
			       mc->cred);
377
  if (ret != GNUTLS_E_SUCCESS) {
378
    fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
13 by Björn Påhlsson
Added following support:
379
	    safer_gnutls_strerror(ret));
380
    return -1;
381
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
382
  
13 by Björn Påhlsson
Added following support:
383
  /* ignore client certificate if any. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
384
  gnutls_certificate_server_set_request (*session,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
385
					 GNUTLS_CERT_IGNORE);
13 by Björn Påhlsson
Added following support:
386
  
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
387
  gnutls_dh_set_prime_bits (*session, mc->dh_bits);
13 by Björn Påhlsson
Added following support:
388
  
389
  return 0;
390
}
391
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
392
/* Avahi log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
393
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
394
		      __attribute__((unused)) const char *txt){}
13 by Björn Påhlsson
Added following support:
395
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
396
/* Called when a Mandos server is found */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
397
static int start_mandos_communication(const char *ip, uint16_t port,
24.1.9 by Björn Påhlsson
not working midwork...
398
				      AvahiIfIndex if_index,
399
				      mandos_context *mc){
13 by Björn Påhlsson
Added following support:
400
  int ret, tcp_sd;
401
  struct sockaddr_in6 to;
402
  char *buffer = NULL;
403
  char *decrypted_buffer;
404
  size_t buffer_length = 0;
405
  size_t buffer_capacity = 0;
406
  ssize_t decrypted_buffer_size;
24.1.10 by Björn Påhlsson
merge commit
407
  size_t written;
13 by Björn Påhlsson
Added following support:
408
  int retval = 0;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
409
  char interface[IF_NAMESIZE];
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
410
  gnutls_session_t session;
411
  gnutls_dh_params_t dh_params;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
412
  
24.1.13 by Björn Påhlsson
mandosclient
413
  ret = init_gnutls_session (mc, &session);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
414
  if (ret != 0){
415
    return -1;
416
  }
417
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
418
  if(debug){
28 by Teddy Hogeborn
* server.conf: New file.
419
    fprintf(stderr, "Setting up a tcp connection to %s, port %d\n",
420
	    ip, port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
421
  }
13 by Björn Påhlsson
Added following support:
422
  
423
  tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
424
  if(tcp_sd < 0) {
425
    perror("socket");
426
    return -1;
427
  }
24.1.6 by Björn Påhlsson
plugbasedclient
428
429
  if(debug){
24.1.7 by Björn Påhlsson
merge
430
    if(if_indextoname((unsigned int)if_index, interface) == NULL){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
431
      perror("if_indextoname");
24.1.6 by Björn Påhlsson
plugbasedclient
432
      return -1;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
433
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
434
    fprintf(stderr, "Binding to interface %s\n", interface);
435
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
436
  
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
437
  memset(&to,0,sizeof(to));	/* Spurious warning */
13 by Björn Påhlsson
Added following support:
438
  to.sin6_family = AF_INET6;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
439
  /* It would be nice to have a way to detect if we were passed an
440
     IPv4 address here.   Now we assume an IPv6 address. */
18 by Teddy Hogeborn
* plugins.d/Makefile: Removed
441
  ret = inet_pton(AF_INET6, ip, &to.sin6_addr);
13 by Björn Påhlsson
Added following support:
442
  if (ret < 0 ){
443
    perror("inet_pton");
444
    return -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
445
  }
13 by Björn Påhlsson
Added following support:
446
  if(ret == 0){
447
    fprintf(stderr, "Bad address: %s\n", ip);
448
    return -1;
449
  }
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
450
  to.sin6_port = htons(port);	/* Spurious warning */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
451
  
452
  to.sin6_scope_id = (uint32_t)if_index;
453
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
454
  if(debug){
28 by Teddy Hogeborn
* server.conf: New file.
455
    fprintf(stderr, "Connection to: %s, port %d\n", ip, port);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
456
    char addrstr[INET6_ADDRSTRLEN] = "";
457
    if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr,
458
		 sizeof(addrstr)) == NULL){
459
      perror("inet_ntop");
460
    } else {
461
      if(strcmp(addrstr, ip) != 0){
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
462
	fprintf(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
463
      }
464
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
465
  }
13 by Björn Påhlsson
Added following support:
466
  
467
  ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
468
  if (ret < 0){
469
    perror("connect");
470
    return -1;
471
  }
24.1.10 by Björn Påhlsson
merge commit
472
24.1.12 by Björn Påhlsson
merge +
473
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
474
  written = 0;
475
  while (true){
476
    size_t out_size = strlen(out);
477
    ret = TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
478
				   out_size - written));
479
    if (ret == -1){
480
      perror("write");
481
      retval = -1;
24.1.12 by Björn Påhlsson
merge +
482
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
483
    }
24.1.12 by Björn Påhlsson
merge +
484
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
485
    if(written < out_size){
486
      continue;
487
    } else {
488
      if (out == mandos_protocol_version){
489
	written = 0;
490
	out = "\r\n";
491
      } else {
492
	break;
493
      }
494
    }
495
  }
496
 
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
497
  if(debug){
498
    fprintf(stderr, "Establishing TLS session with %s\n", ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
499
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
500
  
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
501
  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) tcp_sd);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
502
  
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
503
  ret = gnutls_handshake (session);
13 by Björn Påhlsson
Added following support:
504
  
505
  if (ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
506
    if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
507
      fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
508
      gnutls_perror (ret);
509
    }
13 by Björn Påhlsson
Added following support:
510
    retval = -1;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
511
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
512
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
513
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
514
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
515
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
516
  if(debug){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
517
    fprintf(stderr, "Retrieving pgp encrypted password from %s\n",
518
	    ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
519
  }
520
13 by Björn Påhlsson
Added following support:
521
  while(true){
24.1.12 by Björn Påhlsson
merge +
522
    buffer_capacity = adjustbuffer(&buffer, buffer_length, buffer_capacity);
24.1.10 by Björn Påhlsson
merge commit
523
    if (buffer_capacity == 0){
524
      perror("adjustbuffer");
525
      retval = -1;
24.1.12 by Björn Påhlsson
merge +
526
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
527
    }
528
    
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
529
    ret = gnutls_record_recv(session, buffer+buffer_length,
530
			     BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
531
    if (ret == 0){
532
      break;
533
    }
534
    if (ret < 0){
535
      switch(ret){
536
      case GNUTLS_E_INTERRUPTED:
537
      case GNUTLS_E_AGAIN:
538
	break;
539
      case GNUTLS_E_REHANDSHAKE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
540
	ret = gnutls_handshake (session);
13 by Björn Påhlsson
Added following support:
541
	if (ret < 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
542
	  fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
13 by Björn Påhlsson
Added following support:
543
	  gnutls_perror (ret);
544
	  retval = -1;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
545
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
546
	}
547
	break;
548
      default:
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
549
	fprintf(stderr, "Unknown error while reading data from"
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
550
		" encrypted session with Mandos server\n");
13 by Björn Påhlsson
Added following support:
551
	retval = -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
552
	gnutls_bye (session, GNUTLS_SHUT_RDWR);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
553
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
554
      }
555
    } else {
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
556
      buffer_length += (size_t) ret;
13 by Björn Påhlsson
Added following support:
557
    }
558
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
559
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
560
  if(debug){
561
    fprintf(stderr, "Closing TLS session\n");
562
  }
563
  
564
  gnutls_bye (session, GNUTLS_SHUT_RDWR);
565
  
13 by Björn Påhlsson
Added following support:
566
  if (buffer_length > 0){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
567
    decrypted_buffer_size = pgp_packet_decrypt(buffer,
568
					       buffer_length,
569
					       &decrypted_buffer,
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
570
					       keydir);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
571
    if (decrypted_buffer_size >= 0){
24.1.10 by Björn Påhlsson
merge commit
572
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
573
      while(written < (size_t) decrypted_buffer_size){
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
574
	ret = (int)fwrite (decrypted_buffer + written, 1,
575
			   (size_t)decrypted_buffer_size - written,
576
			   stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
577
	if(ret == 0 and ferror(stdout)){
578
	  if(debug){
579
	    fprintf(stderr, "Error writing encrypted data: %s\n",
580
		    strerror(errno));
581
	  }
582
	  retval = -1;
583
	  break;
584
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
585
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
586
      }
13 by Björn Påhlsson
Added following support:
587
      free(decrypted_buffer);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
588
    } else {
589
      retval = -1;
13 by Björn Påhlsson
Added following support:
590
    }
591
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
592
  
593
  /* Shutdown procedure */
594
  
595
 mandos_end:
13 by Björn Påhlsson
Added following support:
596
  free(buffer);
597
  close(tcp_sd);
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
598
  gnutls_deinit (session);
599
  gnutls_certificate_free_credentials (mc->cred);
13 by Björn Påhlsson
Added following support:
600
  gnutls_global_deinit ();
601
  return retval;
602
}
603
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
604
static void resolve_callback(AvahiSServiceResolver *r,
605
			     AvahiIfIndex interface,
606
			     AVAHI_GCC_UNUSED AvahiProtocol protocol,
607
			     AvahiResolverEvent event,
608
			     const char *name,
609
			     const char *type,
610
			     const char *domain,
611
			     const char *host_name,
612
			     const AvahiAddress *address,
613
			     uint16_t port,
614
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
615
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
616
			     flags,
617
			     void* userdata) {
24.1.9 by Björn Påhlsson
not working midwork...
618
  mandos_context *mc = userdata;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
619
  assert(r);			/* Spurious warning */
620
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
621
  /* Called whenever a service has been resolved successfully or
622
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
623
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
624
  switch (event) {
625
  default:
626
  case AVAHI_RESOLVER_FAILURE:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
627
    fprintf(stderr, "(Avahi Resolver) Failed to resolve service '%s'"
628
	    " of type '%s' in domain '%s': %s\n", name, type, domain,
24.1.9 by Björn Påhlsson
not working midwork...
629
	    avahi_strerror(avahi_server_errno(mc->server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
630
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
631
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
632
  case AVAHI_RESOLVER_FOUND:
633
    {
634
      char ip[AVAHI_ADDRESS_STR_MAX];
635
      avahi_address_snprint(ip, sizeof(ip), address);
636
      if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
637
	fprintf(stderr, "Mandos server \"%s\" found on %s (%s, %d) on"
638
		" port %d\n", name, host_name, ip, interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
639
      }
24.1.9 by Björn Påhlsson
not working midwork...
640
      int ret = start_mandos_communication(ip, port, interface, mc);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
641
      if (ret == 0){
642
	exit(EXIT_SUCCESS);
643
      }
13 by Björn Påhlsson
Added following support:
644
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
645
  }
646
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
647
}
648
24.1.9 by Björn Påhlsson
not working midwork...
649
static void browse_callback( AvahiSServiceBrowser *b,
650
			     AvahiIfIndex interface,
651
			     AvahiProtocol protocol,
652
			     AvahiBrowserEvent event,
653
			     const char *name,
654
			     const char *type,
655
			     const char *domain,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
656
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
657
			     flags,
24.1.9 by Björn Påhlsson
not working midwork...
658
			     void* userdata) {
659
  mandos_context *mc = userdata;
660
  assert(b);			/* Spurious warning */
661
  
662
  /* Called whenever a new services becomes available on the LAN or
663
     is removed from the LAN */
664
  
665
  switch (event) {
666
  default:
667
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
668
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
669
    fprintf(stderr, "(Avahi browser) %s\n",
24.1.9 by Björn Påhlsson
not working midwork...
670
	    avahi_strerror(avahi_server_errno(mc->server)));
671
    avahi_simple_poll_quit(mc->simple_poll);
672
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
673
    
24.1.9 by Björn Påhlsson
not working midwork...
674
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
675
    /* We ignore the returned Avahi resolver object. In the callback
676
       function we free it. If the Avahi server is terminated before
677
       the callback function is called the Avahi server will free the
678
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
679
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
680
    if (!(avahi_s_service_resolver_new(mc->server, interface,
681
				       protocol, name, type, domain,
24.1.9 by Björn Påhlsson
not working midwork...
682
				       AVAHI_PROTO_INET6, 0,
683
				       resolve_callback, mc)))
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
684
      fprintf(stderr, "Avahi: Failed to resolve service '%s': %s\n",
685
	      name, avahi_strerror(avahi_server_errno(mc->server)));
24.1.9 by Björn Påhlsson
not working midwork...
686
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
687
    
24.1.9 by Björn Påhlsson
not working midwork...
688
  case AVAHI_BROWSER_REMOVE:
689
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
690
    
24.1.9 by Björn Påhlsson
not working midwork...
691
  case AVAHI_BROWSER_ALL_FOR_NOW:
692
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
693
    if(debug){
694
      fprintf(stderr, "No Mandos server found, still searching...\n");
695
    }
24.1.9 by Björn Påhlsson
not working midwork...
696
    break;
697
  }
13 by Björn Påhlsson
Added following support:
698
}
699
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
700
/* Combines file name and path and returns the malloced new
701
   string. some sane checks could/should be added */
702
static const char *combinepath(const char *first, const char *second){
703
  size_t f_len = strlen(first);
704
  size_t s_len = strlen(second);
705
  char *tmp = malloc(f_len + s_len + 2);
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
706
  if (tmp == NULL){
707
    return NULL;
708
  }
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
709
  if(f_len > 0){
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
710
    memcpy(tmp, first, f_len);	/* Spurious warning */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
711
  }
712
  tmp[f_len] = '/';
713
  if(s_len > 0){
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
714
    memcpy(tmp + f_len + 1, second, s_len); /* Spurious warning */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
715
  }
716
  tmp[f_len + 1 + s_len] = '\0';
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
717
  return tmp;
718
}
719
720
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
721
int main(int argc, char *argv[]){
13 by Björn Påhlsson
Added following support:
722
    AvahiSServiceBrowser *sb = NULL;
723
    int error;
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
724
    int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
725
    int exitcode = EXIT_SUCCESS;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
726
    const char *interface = "eth0";
24.1.6 by Björn Påhlsson
plugbasedclient
727
    struct ifreq network;
728
    int sd;
24.1.13 by Björn Påhlsson
mandosclient
729
    uid_t uid;
730
    gid_t gid;
24.1.7 by Björn Påhlsson
merge
731
    char *connect_to = NULL;
29 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Changed
732
    AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
24.1.14 by Björn Påhlsson
mandosclient
733
    const char *pubkeyfile = "pubkey.txt";
734
    const char *seckeyfile = "seckey.txt";
24.1.9 by Björn Påhlsson
not working midwork...
735
    mandos_context mc = { .simple_poll = NULL, .server = NULL,
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
736
			  .dh_bits = 1024, .priority = "SECURE256"};
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
737
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
738
    {
24.1.14 by Björn Påhlsson
mandosclient
739
      struct argp_option options[] = {
740
	{ .name = "debug", .key = 128,
741
	  .doc = "Debug mode", .group = 3 },
742
	{ .name = "connect", .key = 'c',
743
	  .arg = "IP",
744
	  .doc = "Connect directly to a sepcified mandos server", .group = 1 },
745
	{ .name = "interface", .key = 'i',
746
	  .arg = "INTERFACE",
747
	  .doc = "Interface that Avahi will conntect through", .group = 1 },
748
	{ .name = "keydir", .key = 'd',
749
	  .arg = "KEYDIR",
750
	  .doc = "Directory where the openpgp keyring is", .group = 1 },
751
	{ .name = "seckey", .key = 's',
752
	  .arg = "SECKEY",
753
	  .doc = "Secret openpgp key for gnutls authentication", .group = 1 },
754
	{ .name = "pubkey", .key = 'p',
755
	  .arg = "PUBKEY",
756
	  .doc = "Public openpgp key for gnutls authentication", .group = 2 },
757
	{ .name = "dh-bits", .key = 129,
758
	  .arg = "BITS",
759
	  .doc = "dh-bits to use in gnutls communication", .group = 2 },
760
	{ .name = "priority", .key = 130,
761
	  .arg = "PRIORITY",
762
	  .doc = "GNUTLS priority", .group = 1 },
763
	{ .name = NULL }
764
      };
765
766
      
767
      error_t parse_opt (int key, char *arg, struct argp_state *state) {
768
	/* Get the INPUT argument from `argp_parse', which we know is a
769
	   pointer to our plugin list pointer. */
770
	switch (key) {
771
	case 128:
772
	  debug = true;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
773
	  break;
24.1.14 by Björn Påhlsson
mandosclient
774
	case 'c':
775
	  connect_to = arg;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
776
	  break;
777
	case 'i':
24.1.14 by Björn Påhlsson
mandosclient
778
	  interface = arg;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
779
	  break;
780
	case 'd':
24.1.14 by Björn Påhlsson
mandosclient
781
	  keydir = arg;
782
	  break;
783
	case 's':
784
	  seckeyfile = arg;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
785
	  break;
786
	case 'p':
24.1.14 by Björn Påhlsson
mandosclient
787
	  pubkeyfile = arg;
788
	  break;
789
	case 129:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
790
	  errno = 0;
24.1.14 by Björn Påhlsson
mandosclient
791
	  mc.dh_bits = (unsigned int) strtol(arg, NULL, 10);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
792
	  if (errno){
793
	    perror("strtol");
794
	    exit(EXIT_FAILURE);
795
	  }
796
	  break;
24.1.14 by Björn Påhlsson
mandosclient
797
	case 130:
798
	  mc.priority = arg;
799
	  break;
800
	case ARGP_KEY_ARG:
801
	  argp_usage (state);
802
	  break;
803
	  case ARGP_KEY_END:
804
	    break;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
805
	default:
24.1.14 by Björn Påhlsson
mandosclient
806
	  return ARGP_ERR_UNKNOWN;
24.1.9 by Björn Påhlsson
not working midwork...
807
	}
24.1.14 by Björn Påhlsson
mandosclient
808
	return 0;
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
809
      }
24.1.14 by Björn Påhlsson
mandosclient
810
811
      struct argp argp = { .options = options, .parser = parse_opt,
812
			   .args_doc = "",
813
			   .doc = "Mandos client -- Get and decrypt passwords from mandos server" };
814
      argp_parse (&argp, argc, argv, 0, 0, NULL);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
815
    }
24.1.14 by Björn Påhlsson
mandosclient
816
      
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
817
    pubkeyfile = combinepath(keydir, pubkeyfile);
818
    if (pubkeyfile == NULL){
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
819
      perror("combinepath");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
820
      exitcode = EXIT_FAILURE;
821
      goto end;
24.1.4 by Björn Påhlsson
Added optional parameters certdir, certkey and certfile that can be iven at start in the command line.
822
    }
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
823
    
824
    seckeyfile = combinepath(keydir, seckeyfile);
825
    if (seckeyfile == NULL){
24.1.7 by Björn Påhlsson
merge
826
      perror("combinepath");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
827
      goto end;
24.1.6 by Björn Påhlsson
plugbasedclient
828
    }
24.1.13 by Björn Påhlsson
mandosclient
829
24.1.14 by Björn Påhlsson
mandosclient
830
    ret = init_gnutls_global(&mc, pubkeyfile, seckeyfile);
24.1.13 by Björn Påhlsson
mandosclient
831
    if (ret == -1){
832
      fprintf(stderr, "init_gnutls_global\n");
833
      goto end;
834
    }
835
836
    uid = getuid();
837
    gid = getgid();
838
839
    ret = setuid(uid);
840
    if (ret == -1){
841
      perror("setuid");
842
    }
843
    
844
    setgid(gid);
845
    if (ret == -1){
846
      perror("setgid");
847
    }
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
848
    
24.1.7 by Björn Påhlsson
merge
849
    if_index = (AvahiIfIndex) if_nametoindex(interface);
850
    if(if_index == 0){
851
      fprintf(stderr, "No such interface: \"%s\"\n", interface);
852
      exit(EXIT_FAILURE);
28 by Teddy Hogeborn
* server.conf: New file.
853
    }
854
    
855
    if(connect_to != NULL){
856
      /* Connect directly, do not use Zeroconf */
857
      /* (Mainly meant for debugging) */
858
      char *address = strrchr(connect_to, ':');
859
      if(address == NULL){
860
        fprintf(stderr, "No colon in address\n");
24.1.13 by Björn Påhlsson
mandosclient
861
	exitcode = EXIT_FAILURE;
862
	goto end;
28 by Teddy Hogeborn
* server.conf: New file.
863
      }
864
      errno = 0;
865
      uint16_t port = (uint16_t) strtol(address+1, NULL, 10);
866
      if(errno){
867
	perror("Bad port number");
24.1.13 by Björn Påhlsson
mandosclient
868
	exitcode = EXIT_FAILURE;
869
	goto end;
28 by Teddy Hogeborn
* server.conf: New file.
870
      }
871
      *address = '\0';
872
      address = connect_to;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
873
      ret = start_mandos_communication(address, port, if_index, &mc);
28 by Teddy Hogeborn
* server.conf: New file.
874
      if(ret < 0){
24.1.13 by Björn Påhlsson
mandosclient
875
	exitcode = EXIT_FAILURE;
28 by Teddy Hogeborn
* server.conf: New file.
876
      } else {
24.1.13 by Björn Påhlsson
mandosclient
877
	exitcode = EXIT_SUCCESS;
28 by Teddy Hogeborn
* server.conf: New file.
878
      }
24.1.13 by Björn Påhlsson
mandosclient
879
      goto end;
28 by Teddy Hogeborn
* server.conf: New file.
880
    }
881
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
882
    /* If the interface is down, bring it up */
883
    {
884
      sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
885
      if(sd < 0) {
886
	perror("socket");
887
	exitcode = EXIT_FAILURE;
888
	goto end;
889
      }
890
      strcpy(network.ifr_name, interface); /* Spurious warning */
891
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
24.1.6 by Björn Påhlsson
plugbasedclient
892
      if(ret == -1){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
893
	perror("ioctl SIOCGIFFLAGS");
894
	exitcode = EXIT_FAILURE;
895
	goto end;
896
      }
897
      if((network.ifr_flags & IFF_UP) == 0){
898
	network.ifr_flags |= IFF_UP;
899
	ret = ioctl(sd, SIOCSIFFLAGS, &network);
900
	if(ret == -1){
901
	  perror("ioctl SIOCSIFFLAGS");
902
	  exitcode = EXIT_FAILURE;
903
	  goto end;
904
	}
905
      }
906
      close(sd);
24.1.6 by Björn Påhlsson
plugbasedclient
907
    }
908
    
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
909
    if (not debug){
910
      avahi_set_log_function(empty_log);
911
    }
13 by Björn Påhlsson
Added following support:
912
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
913
    /* Initialize the pseudo-RNG for Avahi */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
914
    srand((unsigned int) time(NULL));
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
915
    
916
    /* Allocate main Avahi loop object */
917
    mc.simple_poll = avahi_simple_poll_new();
918
    if (mc.simple_poll == NULL) {
919
        fprintf(stderr, "Avahi: Failed to create simple poll"
920
		" object.\n");
921
	exitcode = EXIT_FAILURE;
922
        goto end;
923
    }
924
925
    {
926
      AvahiServerConfig config;
927
      /* Do not publish any local Zeroconf records */
928
      avahi_server_config_init(&config);
929
      config.publish_hinfo = 0;
930
      config.publish_addresses = 0;
931
      config.publish_workstation = 0;
932
      config.publish_domain = 0;
933
934
      /* Allocate a new server */
935
      mc.server = avahi_server_new(avahi_simple_poll_get
936
				   (mc.simple_poll), &config, NULL,
937
				   NULL, &error);
938
    
939
      /* Free the Avahi configuration data */
940
      avahi_server_config_free(&config);
941
    }
942
    
943
    /* Check if creating the Avahi server object succeeded */
944
    if (mc.server == NULL) {
945
        fprintf(stderr, "Failed to create Avahi server: %s\n",
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
946
		avahi_strerror(error));
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
947
	exitcode = EXIT_FAILURE;
948
        goto end;
13 by Björn Påhlsson
Added following support:
949
    }
950
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
951
    /* Create the Avahi service browser */
24.1.9 by Björn Påhlsson
not working midwork...
952
    sb = avahi_s_service_browser_new(mc.server, if_index,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
953
				     AVAHI_PROTO_INET6,
954
				     "_mandos._tcp", NULL, 0,
24.1.9 by Björn Påhlsson
not working midwork...
955
				     browse_callback, &mc);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
956
    if (sb == NULL) {
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
957
        fprintf(stderr, "Failed to create service browser: %s\n",
24.1.9 by Björn Påhlsson
not working midwork...
958
		avahi_strerror(avahi_server_errno(mc.server)));
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
959
	exitcode = EXIT_FAILURE;
960
        goto end;
13 by Björn Påhlsson
Added following support:
961
    }
962
    
963
    /* Run the main loop */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
964
965
    if (debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
966
      fprintf(stderr, "Starting Avahi loop search\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
967
    }
968
    
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
969
    avahi_simple_poll_loop(mc.simple_poll);
13 by Björn Påhlsson
Added following support:
970
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
971
 end:
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
972
973
    if (debug){
974
      fprintf(stderr, "%s exiting\n", argv[0]);
975
    }
13 by Björn Påhlsson
Added following support:
976
    
977
    /* Cleanup things */
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
978
    if (sb != NULL)
13 by Björn Påhlsson
Added following support:
979
        avahi_s_service_browser_free(sb);
980
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
981
    if (mc.server != NULL)
24.1.9 by Björn Påhlsson
not working midwork...
982
        avahi_server_free(mc.server);
13 by Björn Påhlsson
Added following support:
983
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
984
    if (mc.simple_poll != NULL)
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
985
        avahi_simple_poll_free(mc.simple_poll);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
986
    free(pubkeyfile);
987
    free(seckeyfile);
24.1.5 by Björn Påhlsson
plugbasedclient:
988
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
989
    return exitcode;
13 by Björn Påhlsson
Added following support:
990
}