/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1
/*  -*- coding: utf-8 -*- */
2
/*
237.2.24 by Teddy Hogeborn
* plugins.d/askpass-fifo.c: Fix name in header.
3
 * Mandos-client - get and decrypt data from a Mandos server
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
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
237.2.9 by Teddy Hogeborn
* README: Update copyright year; add "2009".
12
 * Copyright © 2008,2009 Teddy Hogeborn
13
 * Copyright © 2008,2009 Björn Påhlsson
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
14
 * 
15
 * This program is free software: you can redistribute it and/or
16
 * modify it under the terms of the GNU General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 * 
20
 * This program is distributed in the hope that it will be useful, but
21
 * WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23
 * General Public License for more details.
24
 * 
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program.  If not, see
27
 * <http://www.gnu.org/licenses/>.
28
 * 
31 by Teddy Hogeborn
* plugins.d/plugbasedclient.c: Update include file comments.
29
 * Contact the authors at <mandos@fukt.bsnet.se>.
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
30
 */
31
28 by Teddy Hogeborn
* server.conf: New file.
32
/* Needed by GPGME, specifically gpgme_data_seek() */
13 by Björn Påhlsson
Added following support:
33
#define _LARGEFILE_SOURCE
34
#define _FILE_OFFSET_BITS 64
35
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
36
#define _GNU_SOURCE		/* TEMP_FAILURE_RETRY(), asprintf() */
24.1.10 by Björn Påhlsson
merge commit
37
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
38
#include <stdio.h>		/* fprintf(), stderr, fwrite(),
237.2.48 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Use remove() instead of unlink(),
39
				   stdout, ferror(), sscanf(),
40
				   remove() */
24.1.26 by Björn Påhlsson
tally count of used symbols
41
#include <stdint.h> 		/* uint16_t, uint32_t */
42
#include <stddef.h>		/* NULL, size_t, ssize_t */
24.1.29 by Björn Påhlsson
Added more header file comments
43
#include <stdlib.h> 		/* free(), EXIT_SUCCESS, EXIT_FAILURE,
44
				   srand() */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
45
#include <stdbool.h>		/* bool, false, true */
24.1.29 by Björn Påhlsson
Added more header file comments
46
#include <string.h>		/* memset(), strcmp(), strlen(),
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
47
				   strerror(), asprintf(), strcpy() */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
48
#include <sys/ioctl.h>		/* ioctl */
24.1.26 by Björn Påhlsson
tally count of used symbols
49
#include <sys/types.h>		/* socket(), inet_pton(), sockaddr,
24.1.29 by Björn Påhlsson
Added more header file comments
50
				   sockaddr_in6, PF_INET6,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
51
				   SOCK_STREAM, uid_t, gid_t, open(),
52
				   opendir(), DIR */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
53
#include <sys/stat.h>		/* open() */
24.1.26 by Björn Påhlsson
tally count of used symbols
54
#include <sys/socket.h>		/* socket(), struct sockaddr_in6,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
55
				   inet_pton(), connect() */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
56
#include <fcntl.h>		/* open() */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
57
#include <dirent.h>		/* opendir(), struct dirent, readdir()
58
				 */
237.2.31 by Teddy Hogeborn
Fixes for sscanf usage:
59
#include <inttypes.h>		/* PRIu16, intmax_t, SCNdMAX */
24.1.29 by Björn Påhlsson
Added more header file comments
60
#include <assert.h>		/* assert() */
61
#include <errno.h>		/* perror(), errno */
237.2.54 by Teddy Hogeborn
Merge from Björn:
62
#include <time.h>		/* nanosleep(), time() */
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
63
#include <net/if.h>		/* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
24.1.26 by Björn Påhlsson
tally count of used symbols
64
				   SIOCSIFFLAGS, if_indextoname(),
65
				   if_nametoindex(), IF_NAMESIZE */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
66
#include <netinet/in.h>		/* IN6_IS_ADDR_LINKLOCAL,
67
				   INET_ADDRSTRLEN, INET6_ADDRSTRLEN
68
				*/
24.1.29 by Björn Påhlsson
Added more header file comments
69
#include <unistd.h>		/* close(), SEEK_SET, off_t, write(),
70
				   getuid(), getgid(), setuid(),
71
				   setgid() */
24.1.26 by Björn Påhlsson
tally count of used symbols
72
#include <arpa/inet.h>		/* inet_pton(), htons */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
73
#include <iso646.h>		/* not, or, and */
24.1.29 by Björn Påhlsson
Added more header file comments
74
#include <argp.h>		/* struct argp_option, error_t, struct
75
				   argp_state, struct argp,
76
				   argp_parse(), ARGP_KEY_ARG,
77
				   ARGP_KEY_END, ARGP_ERR_UNKNOWN */
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
78
#ifdef __linux__
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
79
#include <sys/klog.h> 		/* klogctl() */
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
80
#endif
24.1.26 by Björn Påhlsson
tally count of used symbols
81
82
/* Avahi */
24.1.29 by Björn Påhlsson
Added more header file comments
83
/* All Avahi types, constants and functions
84
 Avahi*, avahi_*,
85
 AVAHI_* */
86
#include <avahi-core/core.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
87
#include <avahi-core/lookup.h>
24.1.29 by Björn Påhlsson
Added more header file comments
88
#include <avahi-core/log.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
89
#include <avahi-common/simple-watch.h>
90
#include <avahi-common/malloc.h>
91
#include <avahi-common/error.h>
92
93
/* GnuTLS */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
94
#include <gnutls/gnutls.h>	/* All GnuTLS types, constants and
95
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
96
				   gnutls_*
24.1.26 by Björn Påhlsson
tally count of used symbols
97
				   init_gnutls_session(),
24.1.29 by Björn Påhlsson
Added more header file comments
98
				   GNUTLS_* */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
99
#include <gnutls/openpgp.h>
100
			  /* gnutls_certificate_set_openpgp_key_file(),
24.1.29 by Björn Påhlsson
Added more header file comments
101
				   GNUTLS_OPENPGP_FMT_BASE64 */
24.1.26 by Björn Påhlsson
tally count of used symbols
102
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
103
/* GPGME */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
104
#include <gpgme.h> 		/* All GPGME types, constants and
105
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
106
				   gpgme_*
24.1.26 by Björn Påhlsson
tally count of used symbols
107
				   GPGME_PROTOCOL_OpenPGP,
24.1.29 by Björn Påhlsson
Added more header file comments
108
				   GPG_ERR_NO_* */
13 by Björn Påhlsson
Added following support:
109
110
#define BUFFER_SIZE 256
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
111
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
112
#define PATHDIR "/conf/conf.d/mandos"
113
#define SECKEY "seckey.txt"
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
114
#define PUBKEY "pubkey.txt"
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
115
15.1.2 by Björn Påhlsson
Added debug options from passprompt as --debug and --debug=passprompt
116
bool debug = false;
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
117
static const char mandos_protocol_version[] = "1";
217 by Teddy Hogeborn
* .bzrignore: Added "man" directory (created by "make install-html").
118
const char *argp_program_version = "mandos-client " VERSION;
24.1.14 by Björn Påhlsson
mandosclient
119
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
24.1.10 by Björn Påhlsson
merge commit
120
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
121
/* Used for passing in values through the Avahi callback functions */
13 by Björn Påhlsson
Added following support:
122
typedef struct {
24.1.9 by Björn Påhlsson
not working midwork...
123
  AvahiSimplePoll *simple_poll;
124
  AvahiServer *server;
13 by Björn Påhlsson
Added following support:
125
  gnutls_certificate_credentials_t cred;
24.1.9 by Björn Påhlsson
not working midwork...
126
  unsigned int dh_bits;
24.1.13 by Björn Påhlsson
mandosclient
127
  gnutls_dh_params_t dh_params;
24.1.9 by Björn Påhlsson
not working midwork...
128
  const char *priority;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
129
  gpgme_ctx_t ctx;
24.1.9 by Björn Påhlsson
not working midwork...
130
} mandos_context;
13 by Björn Påhlsson
Added following support:
131
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
132
/*
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
133
 * Make additional room in "buffer" for at least BUFFER_SIZE
134
 * additional bytes. "buffer_capacity" is how much is currently
135
 * allocated, "buffer_length" is how much is already used.
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
136
 */
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
137
size_t incbuffer(char **buffer, size_t buffer_length,
24.1.10 by Björn Påhlsson
merge commit
138
		  size_t buffer_capacity){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
139
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
24.1.12 by Björn Påhlsson
merge +
140
    *buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
141
    if(buffer == NULL){
24.1.10 by Björn Påhlsson
merge commit
142
      return 0;
143
    }
144
    buffer_capacity += BUFFER_SIZE;
145
  }
146
  return buffer_capacity;
147
}
148
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
149
/* 
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
150
 * Initialize GPGME.
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
151
 */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
152
static bool init_gpgme(mandos_context *mc, const char *seckey,
153
		       const char *pubkey, const char *tempdir){
154
  int ret;
13 by Björn Påhlsson
Added following support:
155
  gpgme_error_t rc;
156
  gpgme_engine_info_t engine_info;
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
157
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
158
  
159
  /*
237.2.51 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Use separate bool variable instead
160
   * Helper function to insert pub and seckey to the engine keyring.
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
161
   */
162
  bool import_key(const char *filename){
163
    int fd;
164
    gpgme_data_t pgp_data;
165
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
166
    fd = (int)TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
167
    if(fd == -1){
168
      perror("open");
169
      return false;
170
    }
171
    
172
    rc = gpgme_data_new_from_fd(&pgp_data, fd);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
173
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
174
      fprintf(stderr, "bad gpgme_data_new_from_fd: %s: %s\n",
175
	      gpgme_strsource(rc), gpgme_strerror(rc));
176
      return false;
177
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
178
    
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
179
    rc = gpgme_op_import(mc->ctx, pgp_data);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
180
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
181
      fprintf(stderr, "bad gpgme_op_import: %s: %s\n",
182
	      gpgme_strsource(rc), gpgme_strerror(rc));
183
      return false;
184
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
185
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
186
    ret = (int)TEMP_FAILURE_RETRY(close(fd));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
187
    if(ret == -1){
188
      perror("close");
189
    }
190
    gpgme_data_release(pgp_data);
191
    return true;
192
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
193
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
194
  if(debug){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
195
    fprintf(stderr, "Initialize gpgme\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
196
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
197
  
13 by Björn Påhlsson
Added following support:
198
  /* Init GPGME */
199
  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.
200
  rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
201
  if(rc != GPG_ERR_NO_ERROR){
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.
202
    fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
203
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
204
    return false;
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.
205
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
206
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
207
    /* Set GPGME home directory for the OpenPGP engine only */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
208
  rc = gpgme_get_engine_info(&engine_info);
209
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
210
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
211
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
212
    return false;
13 by Björn Påhlsson
Added following support:
213
  }
214
  while(engine_info != NULL){
215
    if(engine_info->protocol == GPGME_PROTOCOL_OpenPGP){
216
      gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
217
			    engine_info->file_name, tempdir);
13 by Björn Påhlsson
Added following support:
218
      break;
219
    }
220
    engine_info = engine_info->next;
221
  }
222
  if(engine_info == NULL){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
223
    fprintf(stderr, "Could not set GPGME home dir to %s\n", tempdir);
224
    return false;
225
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
226
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
227
  /* Create new GPGME "context" */
228
  rc = gpgme_new(&(mc->ctx));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
229
  if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
230
    fprintf(stderr, "bad gpgme_new: %s: %s\n",
231
	    gpgme_strsource(rc), gpgme_strerror(rc));
232
    return false;
233
  }
234
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
235
  if(not import_key(pubkey) or not import_key(seckey)){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
236
    return false;
237
  }
238
  
239
  return true; 
240
}
241
242
/* 
243
 * Decrypt OpenPGP data.
244
 * Returns -1 on error
245
 */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
246
static ssize_t pgp_packet_decrypt(const mandos_context *mc,
247
				  const char *cryptotext,
248
				  size_t crypto_size,
249
				  char **plaintext){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
250
  gpgme_data_t dh_crypto, dh_plain;
251
  gpgme_error_t rc;
252
  ssize_t ret;
253
  size_t plaintext_capacity = 0;
254
  ssize_t plaintext_length = 0;
255
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
256
  if(debug){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
257
    fprintf(stderr, "Trying to decrypt OpenPGP data\n");
13 by Björn Påhlsson
Added following support:
258
  }
259
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
260
  /* Create new GPGME data buffer from memory cryptotext */
261
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
262
			       0);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
263
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
264
    fprintf(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
265
	    gpgme_strsource(rc), gpgme_strerror(rc));
266
    return -1;
267
  }
268
  
269
  /* Create new empty GPGME data buffer for the plaintext */
270
  rc = gpgme_data_new(&dh_plain);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
271
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
272
    fprintf(stderr, "bad gpgme_data_new: %s: %s\n",
273
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
274
    gpgme_data_release(dh_crypto);
13 by Björn Påhlsson
Added following support:
275
    return -1;
276
  }
277
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
278
  /* Decrypt data from the cryptotext data buffer to the plaintext
279
     data buffer */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
280
  rc = gpgme_op_decrypt(mc->ctx, dh_crypto, dh_plain);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
281
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
282
    fprintf(stderr, "bad gpgme_op_decrypt: %s: %s\n",
283
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
284
    plaintext_length = -1;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
285
    if(debug){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
286
      gpgme_decrypt_result_t result;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
287
      result = gpgme_op_decrypt_result(mc->ctx);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
288
      if(result == NULL){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
289
	fprintf(stderr, "gpgme_op_decrypt_result failed\n");
290
      } else {
291
	fprintf(stderr, "Unsupported algorithm: %s\n",
292
		result->unsupported_algorithm);
293
	fprintf(stderr, "Wrong key usage: %u\n",
294
		result->wrong_key_usage);
295
	if(result->file_name != NULL){
296
	  fprintf(stderr, "File name: %s\n", result->file_name);
297
	}
298
	gpgme_recipient_t recipient;
299
	recipient = result->recipients;
300
	if(recipient){
301
	  while(recipient != NULL){
302
	    fprintf(stderr, "Public key algorithm: %s\n",
303
		    gpgme_pubkey_algo_name(recipient->pubkey_algo));
304
	    fprintf(stderr, "Key ID: %s\n", recipient->keyid);
305
	    fprintf(stderr, "Secret key available: %s\n",
306
		    recipient->status == GPG_ERR_NO_SECKEY
307
		    ? "No" : "Yes");
308
	    recipient = recipient->next;
309
	  }
310
	}
311
      }
312
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
313
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
314
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
315
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
316
  if(debug){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
317
    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
318
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
319
  
13 by Björn Påhlsson
Added following support:
320
  /* Seek back to the beginning of the GPGME plaintext data buffer */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
321
  if(gpgme_data_seek(dh_plain, (off_t)0, SEEK_SET) == -1){
24.1.92 by Björn Påhlsson
Several memory leaks detected by valgrind fixed
322
    perror("gpgme_data_seek");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
323
    plaintext_length = -1;
324
    goto decrypt_end;
24.1.5 by Björn Påhlsson
plugbasedclient:
325
  }
326
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
327
  *plaintext = NULL;
13 by Björn Påhlsson
Added following support:
328
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
329
    plaintext_capacity = incbuffer(plaintext,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
330
				      (size_t)plaintext_length,
24.1.12 by Björn Påhlsson
merge +
331
				      plaintext_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
332
    if(plaintext_capacity == 0){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
333
	perror("incbuffer");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
334
	plaintext_length = -1;
335
	goto decrypt_end;
13 by Björn Påhlsson
Added following support:
336
    }
337
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
338
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
339
			  BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
340
    /* Print the data, if any */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
341
    if(ret == 0){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
342
      /* EOF */
13 by Björn Påhlsson
Added following support:
343
      break;
344
    }
345
    if(ret < 0){
346
      perror("gpgme_data_read");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
347
      plaintext_length = -1;
348
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
349
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
350
    plaintext_length += ret;
13 by Björn Påhlsson
Added following support:
351
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
352
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
353
  if(debug){
354
    fprintf(stderr, "Decrypted password is: ");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
355
    for(ssize_t i = 0; i < plaintext_length; i++){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
356
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
357
    }
358
    fprintf(stderr, "\n");
359
  }
360
  
361
 decrypt_end:
362
  
363
  /* Delete the GPGME cryptotext data buffer */
364
  gpgme_data_release(dh_crypto);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
365
  
366
  /* Delete the GPGME plaintext data buffer */
13 by Björn Påhlsson
Added following support:
367
  gpgme_data_release(dh_plain);
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
368
  return plaintext_length;
13 by Björn Påhlsson
Added following support:
369
}
370
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
371
static const char * safer_gnutls_strerror(int value){
237.2.30 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
372
  const char *ret = gnutls_strerror(value); /* Spurious warning from
373
					       -Wunreachable-code */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
374
  if(ret == NULL)
13 by Björn Påhlsson
Added following support:
375
    ret = "(unknown)";
376
  return ret;
377
}
378
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
379
/* GnuTLS log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
380
static void debuggnutls(__attribute__((unused)) int level,
381
			const char* string){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
382
  fprintf(stderr, "GnuTLS: %s", string);
13 by Björn Påhlsson
Added following support:
383
}
384
24.1.14 by Björn Påhlsson
mandosclient
385
static int init_gnutls_global(mandos_context *mc,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
386
			      const char *pubkeyfilename,
387
			      const char *seckeyfilename){
13 by Björn Påhlsson
Added following support:
388
  int ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
389
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
390
  if(debug){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
391
    fprintf(stderr, "Initializing GnuTLS\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
392
  }
24.1.29 by Björn Påhlsson
Added more header file comments
393
  
394
  ret = gnutls_global_init();
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
395
  if(ret != GNUTLS_E_SUCCESS){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
396
    fprintf(stderr, "GnuTLS global_init: %s\n",
397
	    safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
398
    return -1;
399
  }
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
400
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
401
  if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
402
    /* "Use a log level over 10 to enable all debugging options."
403
     * - GnuTLS manual
404
     */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
405
    gnutls_global_set_log_level(11);
406
    gnutls_global_set_log_function(debuggnutls);
407
  }
408
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
409
  /* OpenPGP credentials */
24.1.29 by Björn Påhlsson
Added more header file comments
410
  gnutls_certificate_allocate_credentials(&mc->cred);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
411
  if(ret != GNUTLS_E_SUCCESS){
237.2.30 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
412
    fprintf(stderr, "GnuTLS memory error: %s\n", /* Spurious warning
237.2.67 by Teddy Hogeborn
Four new interrelated features:
413
						    from
414
						    -Wunreachable-code
415
						 */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
416
	    safer_gnutls_strerror(ret));
417
    gnutls_global_deinit();
13 by Björn Påhlsson
Added following support:
418
    return -1;
419
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
420
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
421
  if(debug){
147 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Improved wording
422
    fprintf(stderr, "Attempting to use OpenPGP public key %s and"
423
	    " secret key %s as GnuTLS credentials\n", pubkeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
424
	    seckeyfilename);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
425
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
426
  
13 by Björn Påhlsson
Added following support:
427
  ret = gnutls_certificate_set_openpgp_key_file
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
428
    (mc->cred, pubkeyfilename, seckeyfilename,
429
     GNUTLS_OPENPGP_FMT_BASE64);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
430
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
431
    fprintf(stderr,
432
	    "Error[%d] while reading the OpenPGP key pair ('%s',"
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
433
	    " '%s')\n", ret, pubkeyfilename, seckeyfilename);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
434
    fprintf(stderr, "The GnuTLS error is: %s\n",
13 by Björn Påhlsson
Added following support:
435
	    safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
436
    goto globalfail;
13 by Björn Påhlsson
Added following support:
437
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
438
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
439
  /* GnuTLS server initialization */
24.1.13 by Björn Påhlsson
mandosclient
440
  ret = gnutls_dh_params_init(&mc->dh_params);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
441
  if(ret != GNUTLS_E_SUCCESS){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
442
    fprintf(stderr, "Error in GnuTLS DH parameter initialization:"
443
	    " %s\n", safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
444
    goto globalfail;
13 by Björn Påhlsson
Added following support:
445
  }
24.1.13 by Björn Påhlsson
mandosclient
446
  ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
447
  if(ret != GNUTLS_E_SUCCESS){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
448
    fprintf(stderr, "Error in GnuTLS prime generation: %s\n",
449
	    safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
450
    goto globalfail;
13 by Björn Påhlsson
Added following support:
451
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
452
  
24.1.13 by Björn Påhlsson
mandosclient
453
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
454
  
24.1.13 by Björn Påhlsson
mandosclient
455
  return 0;
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
456
  
24.1.20 by Björn Påhlsson
mandosclient
457
 globalfail:
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
458
  
24.1.26 by Björn Påhlsson
tally count of used symbols
459
  gnutls_certificate_free_credentials(mc->cred);
460
  gnutls_global_deinit();
24.1.92 by Björn Påhlsson
Several memory leaks detected by valgrind fixed
461
  gnutls_dh_params_deinit(mc->dh_params);
24.1.20 by Björn Påhlsson
mandosclient
462
  return -1;
24.1.13 by Björn Påhlsson
mandosclient
463
}
464
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
465
static int init_gnutls_session(mandos_context *mc,
466
			       gnutls_session_t *session){
24.1.13 by Björn Påhlsson
mandosclient
467
  int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
468
  /* GnuTLS session creation */
469
  ret = gnutls_init(session, GNUTLS_SERVER);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
470
  if(ret != GNUTLS_E_SUCCESS){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
471
    fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
13 by Björn Påhlsson
Added following support:
472
	    safer_gnutls_strerror(ret));
473
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
474
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
475
  {
476
    const char *err;
477
    ret = gnutls_priority_set_direct(*session, mc->priority, &err);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
478
    if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
479
      fprintf(stderr, "Syntax error at: %s\n", err);
480
      fprintf(stderr, "GnuTLS error: %s\n",
481
	      safer_gnutls_strerror(ret));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
482
      gnutls_deinit(*session);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
483
      return -1;
484
    }
13 by Björn Påhlsson
Added following support:
485
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
486
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
487
  ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
488
			       mc->cred);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
489
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
490
    fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
13 by Björn Påhlsson
Added following support:
491
	    safer_gnutls_strerror(ret));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
492
    gnutls_deinit(*session);
13 by Björn Påhlsson
Added following support:
493
    return -1;
494
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
495
  
13 by Björn Påhlsson
Added following support:
496
  /* ignore client certificate if any. */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
497
  gnutls_certificate_server_set_request(*session,
498
					GNUTLS_CERT_IGNORE);
13 by Björn Påhlsson
Added following support:
499
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
500
  gnutls_dh_set_prime_bits(*session, mc->dh_bits);
13 by Björn Påhlsson
Added following support:
501
  
502
  return 0;
503
}
504
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
505
/* Avahi log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
506
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
507
		      __attribute__((unused)) const char *txt){}
13 by Björn Påhlsson
Added following support:
508
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
509
/* Called when a Mandos server is found */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
510
static int start_mandos_communication(const char *ip, uint16_t port,
24.1.9 by Björn Påhlsson
not working midwork...
511
				      AvahiIfIndex if_index,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
512
				      mandos_context *mc, int af){
13 by Björn Påhlsson
Added following support:
513
  int ret, tcp_sd;
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
514
  ssize_t sret;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
515
  union {
516
    struct sockaddr_in in;
517
    struct sockaddr_in6 in6;
518
  } to;
13 by Björn Påhlsson
Added following support:
519
  char *buffer = NULL;
520
  char *decrypted_buffer;
521
  size_t buffer_length = 0;
522
  size_t buffer_capacity = 0;
523
  ssize_t decrypted_buffer_size;
24.1.10 by Björn Påhlsson
merge commit
524
  size_t written;
13 by Björn Påhlsson
Added following support:
525
  int retval = 0;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
526
  gnutls_session_t session;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
527
  int pf;			/* Protocol family */
528
  
529
  switch(af){
530
  case AF_INET6:
531
    pf = PF_INET6;
532
    break;
533
  case AF_INET:
534
    pf = PF_INET;
535
    break;
536
  default:
537
    fprintf(stderr, "Bad address family: %d\n", af);
538
    return -1;
539
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
540
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
541
  ret = init_gnutls_session(mc, &session);
542
  if(ret != 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
543
    return -1;
544
  }
545
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
546
  if(debug){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
547
    fprintf(stderr, "Setting up a TCP connection to %s, port %" PRIu16
60 by Teddy Hogeborn
* mandos-client.c (main): Cast pid_t to unsigned int before printing.
548
	    "\n", ip, port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
549
  }
13 by Björn Påhlsson
Added following support:
550
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
551
  tcp_sd = socket(pf, SOCK_STREAM, 0);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
552
  if(tcp_sd < 0){
13 by Björn Påhlsson
Added following support:
553
    perror("socket");
554
    return -1;
555
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
556
  
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
557
  memset(&to, 0, sizeof(to));
237.2.67 by Teddy Hogeborn
Four new interrelated features:
558
  if(af == AF_INET6){
559
    to.in6.sin6_family = (uint16_t)af;
560
    ret = inet_pton(af, ip, &to.in6.sin6_addr);
561
  } else {			/* IPv4 */
562
    to.in.sin_family = (sa_family_t)af;
563
    ret = inet_pton(af, ip, &to.in.sin_addr);
564
  }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
565
  if(ret < 0 ){
13 by Björn Påhlsson
Added following support:
566
    perror("inet_pton");
567
    return -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
568
  }
13 by Björn Påhlsson
Added following support:
569
  if(ret == 0){
570
    fprintf(stderr, "Bad address: %s\n", ip);
571
    return -1;
572
  }
237.2.67 by Teddy Hogeborn
Four new interrelated features:
573
  if(af == AF_INET6){
574
    to.in6.sin6_port = htons(port); /* Spurious warnings from
575
				       -Wconversion and
576
				       -Wunreachable-code */
577
    
578
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
579
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
580
			      -Wunreachable-code*/
581
      if(if_index == AVAHI_IF_UNSPEC){
582
	fprintf(stderr, "An IPv6 link-local address is incomplete"
583
		" without a network interface\n");
584
	return -1;
585
      }
586
      /* Set the network interface number as scope */
587
      to.in6.sin6_scope_id = (uint32_t)if_index;
588
    }
589
  } else {
590
    to.in.sin_port = htons(port); /* Spurious warnings from
237.2.30 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
591
				     -Wconversion and
592
				     -Wunreachable-code */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
593
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
594
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
595
  if(debug){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
596
    if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){
597
      char interface[IF_NAMESIZE];
598
      if(if_indextoname((unsigned int)if_index, interface) == NULL){
599
	perror("if_indextoname");
600
      } else {
601
	fprintf(stderr, "Connection to: %s%%%s, port %" PRIu16 "\n",
602
		ip, interface, port);
603
      }
604
    } else {
605
      fprintf(stderr, "Connection to: %s, port %" PRIu16 "\n", ip,
606
	      port);
607
    }
608
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
609
		 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
610
    const char *pcret;
611
    if(af == AF_INET6){
612
      pcret = inet_ntop(af, &(to.in6.sin6_addr), addrstr,
613
			sizeof(addrstr));
614
    } else {
615
      pcret = inet_ntop(af, &(to.in.sin_addr), addrstr,
616
			sizeof(addrstr));
617
    }
618
    if(pcret == NULL){
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
619
      perror("inet_ntop");
620
    } else {
621
      if(strcmp(addrstr, ip) != 0){
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
622
	fprintf(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
623
      }
624
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
625
  }
13 by Björn Påhlsson
Added following support:
626
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
627
  if(af == AF_INET6){
628
    ret = connect(tcp_sd, &to.in6, sizeof(to));
629
  } else {
630
    ret = connect(tcp_sd, &to.in, sizeof(to)); /* IPv4 */
631
  }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
632
  if(ret < 0){
13 by Björn Påhlsson
Added following support:
633
    perror("connect");
634
    return -1;
635
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
636
  
24.1.12 by Björn Påhlsson
merge +
637
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
638
  written = 0;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
639
  while(true){
24.1.10 by Björn Påhlsson
merge commit
640
    size_t out_size = strlen(out);
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
641
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
24.1.10 by Björn Påhlsson
merge commit
642
				   out_size - written));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
643
    if(ret == -1){
24.1.10 by Björn Påhlsson
merge commit
644
      perror("write");
645
      retval = -1;
24.1.12 by Björn Påhlsson
merge +
646
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
647
    }
24.1.12 by Björn Påhlsson
merge +
648
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
649
    if(written < out_size){
650
      continue;
651
    } else {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
652
      if(out == mandos_protocol_version){
24.1.10 by Björn Påhlsson
merge commit
653
	written = 0;
654
	out = "\r\n";
655
      } else {
656
	break;
657
      }
658
    }
659
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
660
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
661
  if(debug){
662
    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
663
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
664
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
665
  gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) tcp_sd);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
666
  
24.1.29 by Björn Påhlsson
Added more header file comments
667
  do{
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
668
    ret = gnutls_handshake(session);
24.1.29 by Björn Påhlsson
Added more header file comments
669
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
13 by Björn Påhlsson
Added following support:
670
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
671
  if(ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
672
    if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
673
      fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
674
      gnutls_perror(ret);
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
675
    }
13 by Björn Påhlsson
Added following support:
676
    retval = -1;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
677
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
678
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
679
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
680
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
681
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
682
  if(debug){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
683
    fprintf(stderr, "Retrieving OpenPGP encrypted password from %s\n",
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
684
	    ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
685
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
686
  
13 by Björn Påhlsson
Added following support:
687
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
688
    buffer_capacity = incbuffer(&buffer, buffer_length,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
689
				   buffer_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
690
    if(buffer_capacity == 0){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
691
      perror("incbuffer");
24.1.10 by Björn Påhlsson
merge commit
692
      retval = -1;
24.1.12 by Björn Påhlsson
merge +
693
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
694
    }
695
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
696
    sret = gnutls_record_recv(session, buffer+buffer_length,
697
			      BUFFER_SIZE);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
698
    if(sret == 0){
13 by Björn Påhlsson
Added following support:
699
      break;
700
    }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
701
    if(sret < 0){
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
702
      switch(sret){
13 by Björn Påhlsson
Added following support:
703
      case GNUTLS_E_INTERRUPTED:
704
      case GNUTLS_E_AGAIN:
705
	break;
706
      case GNUTLS_E_REHANDSHAKE:
24.1.29 by Björn Påhlsson
Added more header file comments
707
	do{
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
708
	  ret = gnutls_handshake(session);
24.1.29 by Björn Påhlsson
Added more header file comments
709
	} while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
710
	if(ret < 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
711
	  fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
712
	  gnutls_perror(ret);
13 by Björn Påhlsson
Added following support:
713
	  retval = -1;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
714
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
715
	}
716
	break;
717
      default:
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
718
	fprintf(stderr, "Unknown error while reading data from"
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
719
		" encrypted session with Mandos server\n");
13 by Björn Påhlsson
Added following support:
720
	retval = -1;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
721
	gnutls_bye(session, GNUTLS_SHUT_RDWR);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
722
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
723
      }
724
    } else {
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
725
      buffer_length += (size_t) sret;
13 by Björn Påhlsson
Added following support:
726
    }
727
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
728
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
729
  if(debug){
730
    fprintf(stderr, "Closing TLS session\n");
731
  }
732
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
733
  gnutls_bye(session, GNUTLS_SHUT_RDWR);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
734
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
735
  if(buffer_length > 0){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
736
    decrypted_buffer_size = pgp_packet_decrypt(mc, buffer,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
737
					       buffer_length,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
738
					       &decrypted_buffer);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
739
    if(decrypted_buffer_size >= 0){
24.1.10 by Björn Påhlsson
merge commit
740
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
741
      while(written < (size_t) decrypted_buffer_size){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
742
	ret = (int)fwrite(decrypted_buffer + written, 1,
743
			  (size_t)decrypted_buffer_size - written,
744
			  stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
745
	if(ret == 0 and ferror(stdout)){
746
	  if(debug){
747
	    fprintf(stderr, "Error writing encrypted data: %s\n",
748
		    strerror(errno));
749
	  }
750
	  retval = -1;
751
	  break;
752
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
753
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
754
      }
13 by Björn Påhlsson
Added following support:
755
      free(decrypted_buffer);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
756
    } else {
757
      retval = -1;
13 by Björn Påhlsson
Added following support:
758
    }
24.1.63 by Björn Påhlsson
merge + fallback bugg
759
  } else {
760
    retval = -1;
13 by Björn Påhlsson
Added following support:
761
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
762
  
763
  /* Shutdown procedure */
764
  
765
 mandos_end:
13 by Björn Påhlsson
Added following support:
766
  free(buffer);
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
767
  ret = (int)TEMP_FAILURE_RETRY(close(tcp_sd));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
768
  if(ret == -1){
769
    perror("close");
770
  }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
771
  gnutls_deinit(session);
13 by Björn Påhlsson
Added following support:
772
  return retval;
773
}
774
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
775
static void resolve_callback(AvahiSServiceResolver *r,
776
			     AvahiIfIndex interface,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
777
			     AvahiProtocol proto,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
778
			     AvahiResolverEvent event,
779
			     const char *name,
780
			     const char *type,
781
			     const char *domain,
782
			     const char *host_name,
783
			     const AvahiAddress *address,
784
			     uint16_t port,
785
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
786
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
787
			     flags,
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
788
			     void* userdata){
24.1.9 by Björn Påhlsson
not working midwork...
789
  mandos_context *mc = userdata;
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
790
  assert(r);
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
791
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
792
  /* Called whenever a service has been resolved successfully or
793
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
794
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
795
  switch(event){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
796
  default:
797
  case AVAHI_RESOLVER_FAILURE:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
798
    fprintf(stderr, "(Avahi Resolver) Failed to resolve service '%s'"
799
	    " of type '%s' in domain '%s': %s\n", name, type, domain,
24.1.9 by Björn Påhlsson
not working midwork...
800
	    avahi_strerror(avahi_server_errno(mc->server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
801
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
802
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
803
  case AVAHI_RESOLVER_FOUND:
804
    {
805
      char ip[AVAHI_ADDRESS_STR_MAX];
806
      avahi_address_snprint(ip, sizeof(ip), address);
807
      if(debug){
60 by Teddy Hogeborn
* mandos-client.c (main): Cast pid_t to unsigned int before printing.
808
	fprintf(stderr, "Mandos server \"%s\" found on %s (%s, %"
237.2.31 by Teddy Hogeborn
Fixes for sscanf usage:
809
		PRIdMAX ") on port %" PRIu16 "\n", name, host_name,
810
		ip, (intmax_t)interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
811
      }
237.2.67 by Teddy Hogeborn
Four new interrelated features:
812
      int ret = start_mandos_communication(ip, port, interface, mc,
813
					   avahi_proto_to_af(proto));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
814
      if(ret == 0){
24.1.46 by Björn Påhlsson
mandos-client
815
	avahi_simple_poll_quit(mc->simple_poll);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
816
      }
13 by Björn Påhlsson
Added following support:
817
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
818
  }
819
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
820
}
821
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
822
static void browse_callback(AvahiSServiceBrowser *b,
823
			    AvahiIfIndex interface,
824
			    AvahiProtocol protocol,
825
			    AvahiBrowserEvent event,
826
			    const char *name,
827
			    const char *type,
828
			    const char *domain,
829
			    AVAHI_GCC_UNUSED AvahiLookupResultFlags
830
			    flags,
831
			    void* userdata){
24.1.9 by Björn Påhlsson
not working midwork...
832
  mandos_context *mc = userdata;
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
833
  assert(b);
24.1.9 by Björn Påhlsson
not working midwork...
834
  
835
  /* Called whenever a new services becomes available on the LAN or
836
     is removed from the LAN */
837
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
838
  switch(event){
24.1.9 by Björn Påhlsson
not working midwork...
839
  default:
840
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
841
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
842
    fprintf(stderr, "(Avahi browser) %s\n",
24.1.9 by Björn Påhlsson
not working midwork...
843
	    avahi_strerror(avahi_server_errno(mc->server)));
844
    avahi_simple_poll_quit(mc->simple_poll);
845
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
846
    
24.1.9 by Björn Påhlsson
not working midwork...
847
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
848
    /* We ignore the returned Avahi resolver object. In the callback
849
       function we free it. If the Avahi server is terminated before
850
       the callback function is called the Avahi server will free the
851
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
852
    
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
853
    if(!(avahi_s_service_resolver_new(mc->server, interface,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
854
				       protocol, name, type, domain,
24.1.9 by Björn Påhlsson
not working midwork...
855
				       AVAHI_PROTO_INET6, 0,
856
				       resolve_callback, mc)))
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
857
      fprintf(stderr, "Avahi: Failed to resolve service '%s': %s\n",
858
	      name, avahi_strerror(avahi_server_errno(mc->server)));
24.1.9 by Björn Påhlsson
not working midwork...
859
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
860
    
24.1.9 by Björn Påhlsson
not working midwork...
861
  case AVAHI_BROWSER_REMOVE:
862
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
863
    
24.1.9 by Björn Påhlsson
not working midwork...
864
  case AVAHI_BROWSER_ALL_FOR_NOW:
865
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
866
    if(debug){
867
      fprintf(stderr, "No Mandos server found, still searching...\n");
868
    }
24.1.9 by Björn Påhlsson
not working midwork...
869
    break;
870
  }
13 by Björn Påhlsson
Added following support:
871
}
872
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
873
int main(int argc, char *argv[]){
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
874
  AvahiSServiceBrowser *sb = NULL;
875
  int error;
876
  int ret;
877
  intmax_t tmpmax;
878
  int numchars;
879
  int exitcode = EXIT_SUCCESS;
880
  const char *interface = "eth0";
881
  struct ifreq network;
882
  int sd;
883
  uid_t uid;
884
  gid_t gid;
885
  char *connect_to = NULL;
886
  char tempdir[] = "/tmp/mandosXXXXXX";
887
  bool tempdir_created = false;
888
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
889
  const char *seckey = PATHDIR "/" SECKEY;
890
  const char *pubkey = PATHDIR "/" PUBKEY;
891
  
892
  mandos_context mc = { .simple_poll = NULL, .server = NULL,
893
			.dh_bits = 1024, .priority = "SECURE256"
894
			":!CTYPE-X.509:+CTYPE-OPENPGP" };
895
  bool gnutls_initialized = false;
896
  bool gpgme_initialized = false;
897
  double delay = 2.5;
898
  
899
  {
900
    struct argp_option options[] = {
901
      { .name = "debug", .key = 128,
902
	.doc = "Debug mode", .group = 3 },
903
      { .name = "connect", .key = 'c',
904
	.arg = "ADDRESS:PORT",
905
	.doc = "Connect directly to a specific Mandos server",
906
	.group = 1 },
907
      { .name = "interface", .key = 'i',
908
	.arg = "NAME",
237.2.67 by Teddy Hogeborn
Four new interrelated features:
909
	.doc = "Network interface that will be used to search for"
910
	" Mandos servers",
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
911
	.group = 1 },
912
      { .name = "seckey", .key = 's',
913
	.arg = "FILE",
914
	.doc = "OpenPGP secret key file base name",
915
	.group = 1 },
916
      { .name = "pubkey", .key = 'p',
917
	.arg = "FILE",
918
	.doc = "OpenPGP public key file base name",
919
	.group = 2 },
920
      { .name = "dh-bits", .key = 129,
921
	.arg = "BITS",
922
	.doc = "Bit length of the prime number used in the"
923
	" Diffie-Hellman key exchange",
924
	.group = 2 },
925
      { .name = "priority", .key = 130,
926
	.arg = "STRING",
927
	.doc = "GnuTLS priority string for the TLS handshake",
928
	.group = 1 },
929
      { .name = "delay", .key = 131,
930
	.arg = "SECONDS",
931
	.doc = "Maximum delay to wait for interface startup",
932
	.group = 2 },
933
      { .name = NULL }
934
    };
935
    
936
    error_t parse_opt(int key, char *arg,
937
		      struct argp_state *state){
938
      switch(key){
939
      case 128:			/* --debug */
940
	debug = true;
941
	break;
942
      case 'c':			/* --connect */
943
	connect_to = arg;
944
	break;
945
      case 'i':			/* --interface */
946
	interface = arg;
947
	break;
948
      case 's':			/* --seckey */
949
	seckey = arg;
950
	break;
951
      case 'p':			/* --pubkey */
952
	pubkey = arg;
953
	break;
954
      case 129:			/* --dh-bits */
955
	ret = sscanf(arg, "%" SCNdMAX "%n", &tmpmax, &numchars);
956
	if(ret < 1 or tmpmax != (typeof(mc.dh_bits))tmpmax
957
	   or arg[numchars] != '\0'){
958
	  fprintf(stderr, "Bad number of DH bits\n");
959
	  exit(EXIT_FAILURE);
960
	}
961
	mc.dh_bits = (typeof(mc.dh_bits))tmpmax;
962
	break;
963
      case 130:			/* --priority */
964
	mc.priority = arg;
965
	break;
966
      case 131:			/* --delay */
967
	ret = sscanf(arg, "%lf%n", &delay, &numchars);
968
	if(ret < 1 or arg[numchars] != '\0'){
969
	  fprintf(stderr, "Bad delay\n");
970
	  exit(EXIT_FAILURE);
971
	}
972
	break;
973
      case ARGP_KEY_ARG:
974
	argp_usage(state);
975
      case ARGP_KEY_END:
976
	break;
977
      default:
978
	return ARGP_ERR_UNKNOWN;
979
      }
980
      return 0;
981
    }
982
    
983
    struct argp argp = { .options = options, .parser = parse_opt,
984
			 .args_doc = "",
985
			 .doc = "Mandos client -- Get and decrypt"
986
			 " passwords from a Mandos server" };
987
    ret = argp_parse(&argp, argc, argv, 0, 0, NULL);
988
    if(ret == ARGP_ERR_UNKNOWN){
989
      fprintf(stderr, "Unknown error while parsing arguments\n");
990
      exitcode = EXIT_FAILURE;
991
      goto end;
992
    }
993
  }
994
  
995
  /* If the interface is down, bring it up */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
996
  if(interface[0] != '\0'){
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
997
#ifdef __linux__
998
    /* Lower kernel loglevel to KERN_NOTICE to avoid KERN_INFO
999
       messages to mess up the prompt */
1000
    ret = klogctl(8, NULL, 5);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1001
    bool restore_loglevel = true;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1002
    if(ret == -1){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1003
      restore_loglevel = false;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1004
      perror("klogctl");
1005
    }
1006
#endif
1007
    
1008
    sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1009
    if(sd < 0){
1010
      perror("socket");
1011
      exitcode = EXIT_FAILURE;
1012
#ifdef __linux__
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1013
      if(restore_loglevel){
1014
	ret = klogctl(7, NULL, 0);
1015
	if(ret == -1){
1016
	  perror("klogctl");
1017
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1018
      }
1019
#endif
1020
      goto end;
1021
    }
1022
    strcpy(network.ifr_name, interface);
1023
    ret = ioctl(sd, SIOCGIFFLAGS, &network);
1024
    if(ret == -1){
1025
      perror("ioctl SIOCGIFFLAGS");
1026
#ifdef __linux__
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1027
      if(restore_loglevel){
1028
	ret = klogctl(7, NULL, 0);
1029
	if(ret == -1){
1030
	  perror("klogctl");
1031
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1032
      }
1033
#endif
1034
      exitcode = EXIT_FAILURE;
1035
      goto end;
1036
    }
1037
    if((network.ifr_flags & IFF_UP) == 0){
1038
      network.ifr_flags |= IFF_UP;
1039
      ret = ioctl(sd, SIOCSIFFLAGS, &network);
1040
      if(ret == -1){
1041
	perror("ioctl SIOCSIFFLAGS");
1042
	exitcode = EXIT_FAILURE;
1043
#ifdef __linux__
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1044
	if(restore_loglevel){
1045
	  ret = klogctl(7, NULL, 0);
1046
	  if(ret == -1){
1047
	    perror("klogctl");
1048
	  }
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
1049
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1050
#endif
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1051
	goto end;
1052
      }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1053
    }
1054
    /* sleep checking until interface is running */
1055
    for(int i=0; i < delay * 4; i++){
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1056
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
1057
      if(ret == -1){
1058
	perror("ioctl SIOCGIFFLAGS");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1059
      } else if(network.ifr_flags & IFF_RUNNING){
1060
	break;
1061
      }
1062
      struct timespec sleeptime = { .tv_nsec = 250000000 };
1063
      ret = nanosleep(&sleeptime, NULL);
1064
      if(ret == -1 and errno != EINTR){
1065
	perror("nanosleep");
1066
      }
1067
    }
1068
    ret = (int)TEMP_FAILURE_RETRY(close(sd));
1069
    if(ret == -1){
1070
      perror("close");
1071
    }
1072
#ifdef __linux__
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1073
    if(restore_loglevel){
1074
      /* Restores kernel loglevel to default */
1075
      ret = klogctl(7, NULL, 0);
1076
      if(ret == -1){
1077
	perror("klogctl");
1078
      }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1079
    }
1080
#endif
1081
  }
1082
  
1083
  uid = getuid();
1084
  gid = getgid();
1085
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1086
  errno = 0;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1087
  setgid(gid);
1088
  if(ret == -1){
1089
    perror("setgid");
1090
  }
1091
  
1092
  ret = setuid(uid);
1093
  if(ret == -1){
1094
    perror("setuid");
1095
  }
1096
  
1097
  ret = init_gnutls_global(&mc, pubkey, seckey);
1098
  if(ret == -1){
1099
    fprintf(stderr, "init_gnutls_global failed\n");
1100
    exitcode = EXIT_FAILURE;
1101
    goto end;
1102
  } else {
1103
    gnutls_initialized = true;
1104
  }
1105
  
1106
  if(mkdtemp(tempdir) == NULL){
1107
    perror("mkdtemp");
1108
    goto end;
1109
  }
1110
  tempdir_created = true;
1111
  
1112
  if(not init_gpgme(&mc, pubkey, seckey, tempdir)){
1113
    fprintf(stderr, "init_gpgme failed\n");
1114
    exitcode = EXIT_FAILURE;
1115
    goto end;
1116
  } else {
1117
    gpgme_initialized = true;
1118
  }
1119
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1120
  if(interface[0] != '\0'){
1121
    if_index = (AvahiIfIndex) if_nametoindex(interface);
1122
    if(if_index == 0){
1123
      fprintf(stderr, "No such interface: \"%s\"\n", interface);
1124
      exitcode = EXIT_FAILURE;
1125
      goto end;
1126
    }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1127
  }
1128
  
1129
  if(connect_to != NULL){
1130
    /* Connect directly, do not use Zeroconf */
1131
    /* (Mainly meant for debugging) */
1132
    char *address = strrchr(connect_to, ':');
1133
    if(address == NULL){
1134
      fprintf(stderr, "No colon in address\n");
1135
      exitcode = EXIT_FAILURE;
1136
      goto end;
1137
    }
1138
    uint16_t port;
1139
    ret = sscanf(address+1, "%" SCNdMAX "%n", &tmpmax, &numchars);
1140
    if(ret < 1 or tmpmax != (uint16_t)tmpmax
1141
       or address[numchars+1] != '\0'){
1142
      fprintf(stderr, "Bad port number\n");
1143
      exitcode = EXIT_FAILURE;
1144
      goto end;
1145
    }
1146
    port = (uint16_t)tmpmax;
1147
    *address = '\0';
1148
    address = connect_to;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1149
    /* Colon in address indicates IPv6 */
1150
    int af;
1151
    if(strchr(address, ':') != NULL){
1152
      af = AF_INET6;
1153
    } else {
1154
      af = AF_INET;
1155
    }
1156
    ret = start_mandos_communication(address, port, if_index, &mc,
1157
				     af);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1158
    if(ret < 0){
1159
      exitcode = EXIT_FAILURE;
1160
    } else {
1161
      exitcode = EXIT_SUCCESS;
1162
    }
1163
    goto end;
1164
  }
1165
  
1166
  if(not debug){
1167
    avahi_set_log_function(empty_log);
1168
  }
1169
  
1170
  /* Initialize the pseudo-RNG for Avahi */
1171
  srand((unsigned int) time(NULL));
1172
  
1173
  /* Allocate main Avahi loop object */
1174
  mc.simple_poll = avahi_simple_poll_new();
1175
  if(mc.simple_poll == NULL){
1176
    fprintf(stderr, "Avahi: Failed to create simple poll object.\n");
1177
    exitcode = EXIT_FAILURE;
1178
    goto end;
1179
  }
1180
  
1181
  {
1182
    AvahiServerConfig config;
1183
    /* Do not publish any local Zeroconf records */
1184
    avahi_server_config_init(&config);
1185
    config.publish_hinfo = 0;
1186
    config.publish_addresses = 0;
1187
    config.publish_workstation = 0;
1188
    config.publish_domain = 0;
1189
    
1190
    /* Allocate a new server */
1191
    mc.server = avahi_server_new(avahi_simple_poll_get
1192
				 (mc.simple_poll), &config, NULL,
1193
				 NULL, &error);
1194
    
1195
    /* Free the Avahi configuration data */
1196
    avahi_server_config_free(&config);
1197
  }
1198
  
1199
  /* Check if creating the Avahi server object succeeded */
1200
  if(mc.server == NULL){
1201
    fprintf(stderr, "Failed to create Avahi server: %s\n",
1202
	    avahi_strerror(error));
1203
    exitcode = EXIT_FAILURE;
1204
    goto end;
1205
  }
1206
  
1207
  /* Create the Avahi service browser */
1208
  sb = avahi_s_service_browser_new(mc.server, if_index,
1209
				   AVAHI_PROTO_INET6, "_mandos._tcp",
1210
				   NULL, 0, browse_callback, &mc);
1211
  if(sb == NULL){
1212
    fprintf(stderr, "Failed to create service browser: %s\n",
1213
	    avahi_strerror(avahi_server_errno(mc.server)));
1214
    exitcode = EXIT_FAILURE;
1215
    goto end;
1216
  }
1217
  
1218
  /* Run the main loop */
1219
  
1220
  if(debug){
1221
    fprintf(stderr, "Starting Avahi loop search\n");
1222
  }
1223
  
1224
  avahi_simple_poll_loop(mc.simple_poll);
1225
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1226
 end:
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1227
  
1228
  if(debug){
1229
    fprintf(stderr, "%s exiting\n", argv[0]);
1230
  }
1231
  
1232
  /* Cleanup things */
1233
  if(sb != NULL)
1234
    avahi_s_service_browser_free(sb);
1235
  
1236
  if(mc.server != NULL)
1237
    avahi_server_free(mc.server);
1238
  
1239
  if(mc.simple_poll != NULL)
1240
    avahi_simple_poll_free(mc.simple_poll);
1241
  
1242
  if(gnutls_initialized){
1243
    gnutls_certificate_free_credentials(mc.cred);
1244
    gnutls_global_deinit();
1245
    gnutls_dh_params_deinit(mc.dh_params);
1246
  }
1247
  
1248
  if(gpgme_initialized){
1249
    gpgme_release(mc.ctx);
1250
  }
1251
  
1252
  /* Removes the temp directory used by GPGME */
1253
  if(tempdir_created){
1254
    DIR *d;
1255
    struct dirent *direntry;
1256
    d = opendir(tempdir);
1257
    if(d == NULL){
1258
      if(errno != ENOENT){
1259
	perror("opendir");
1260
      }
1261
    } else {
1262
      while(true){
1263
	direntry = readdir(d);
1264
	if(direntry == NULL){
1265
	  break;
1266
	}
1267
	/* Skip "." and ".." */
1268
	if(direntry->d_name[0] == '.'
1269
	   and (direntry->d_name[1] == '\0'
1270
		or (direntry->d_name[1] == '.'
1271
		    and direntry->d_name[2] == '\0'))){
1272
	  continue;
1273
	}
1274
	char *fullname = NULL;
1275
	ret = asprintf(&fullname, "%s/%s", tempdir,
1276
		       direntry->d_name);
1277
	if(ret < 0){
1278
	  perror("asprintf");
1279
	  continue;
1280
	}
1281
	ret = remove(fullname);
1282
	if(ret == -1){
1283
	  fprintf(stderr, "remove(\"%s\"): %s\n", fullname,
1284
		  strerror(errno));
1285
	}
1286
	free(fullname);
1287
      }
1288
      closedir(d);
1289
    }
1290
    ret = rmdir(tempdir);
1291
    if(ret == -1 and errno != ENOENT){
1292
      perror("rmdir");
1293
    }
1294
  }
1295
  
1296
  return exitcode;
13 by Björn Påhlsson
Added following support:
1297
}