/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
/*
261 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
246 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() */
317 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
33
#ifndef _LARGEFILE_SOURCE
13 by Björn Påhlsson
Added following support:
34
#define _LARGEFILE_SOURCE
317 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
35
#endif
36
#ifndef _FILE_OFFSET_BITS
13 by Björn Påhlsson
Added following support:
37
#define _FILE_OFFSET_BITS 64
317 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
38
#endif
13 by Björn Påhlsson
Added following support:
39
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
40
#define _GNU_SOURCE		/* TEMP_FAILURE_RETRY(), asprintf() */
24.1.10 by Björn Påhlsson
merge commit
41
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
42
#include <stdio.h>		/* fprintf(), stderr, fwrite(),
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
43
				   stdout, ferror(), remove() */
24.1.26 by Björn Påhlsson
tally count of used symbols
44
#include <stdint.h> 		/* uint16_t, uint32_t */
45
#include <stddef.h>		/* NULL, size_t, ssize_t */
24.1.29 by Björn Påhlsson
Added more header file comments
46
#include <stdlib.h> 		/* free(), EXIT_SUCCESS, EXIT_FAILURE,
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
47
				   srand(), strtof(), abort() */
304 by Teddy Hogeborn
Four new interrelated features:
48
#include <stdbool.h>		/* bool, false, true */
24.1.29 by Björn Påhlsson
Added more header file comments
49
#include <string.h>		/* memset(), strcmp(), strlen(),
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
50
				   strerror(), asprintf(), strcpy() */
304 by Teddy Hogeborn
Four new interrelated features:
51
#include <sys/ioctl.h>		/* ioctl */
24.1.26 by Björn Påhlsson
tally count of used symbols
52
#include <sys/types.h>		/* socket(), inet_pton(), sockaddr,
24.1.29 by Björn Påhlsson
Added more header file comments
53
				   sockaddr_in6, PF_INET6,
304 by Teddy Hogeborn
Four new interrelated features:
54
				   SOCK_STREAM, uid_t, gid_t, open(),
55
				   opendir(), DIR */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
56
#include <sys/stat.h>		/* open() */
24.1.26 by Björn Påhlsson
tally count of used symbols
57
#include <sys/socket.h>		/* socket(), struct sockaddr_in6,
304 by Teddy Hogeborn
Four new interrelated features:
58
				   inet_pton(), connect() */
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
59
#include <fcntl.h>		/* open() */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
60
#include <dirent.h>		/* opendir(), struct dirent, readdir()
61
				 */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
62
#include <inttypes.h>		/* PRIu16, PRIdMAX, intmax_t,
63
				   strtoimax() */
24.1.29 by Björn Påhlsson
Added more header file comments
64
#include <assert.h>		/* assert() */
65
#include <errno.h>		/* perror(), errno */
291 by Teddy Hogeborn
Merge from Björn:
66
#include <time.h>		/* nanosleep(), time() */
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
67
#include <net/if.h>		/* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
24.1.26 by Björn Påhlsson
tally count of used symbols
68
				   SIOCSIFFLAGS, if_indextoname(),
69
				   if_nametoindex(), IF_NAMESIZE */
304 by Teddy Hogeborn
Four new interrelated features:
70
#include <netinet/in.h>		/* IN6_IS_ADDR_LINKLOCAL,
71
				   INET_ADDRSTRLEN, INET6_ADDRSTRLEN
72
				*/
24.1.29 by Björn Påhlsson
Added more header file comments
73
#include <unistd.h>		/* close(), SEEK_SET, off_t, write(),
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
74
				   getuid(), getgid(), seteuid(),
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
75
				   setgid(), pause() */
24.1.26 by Björn Påhlsson
tally count of used symbols
76
#include <arpa/inet.h>		/* inet_pton(), htons */
304 by Teddy Hogeborn
Four new interrelated features:
77
#include <iso646.h>		/* not, or, and */
24.1.29 by Björn Påhlsson
Added more header file comments
78
#include <argp.h>		/* struct argp_option, error_t, struct
79
				   argp_state, struct argp,
80
				   argp_parse(), ARGP_KEY_ARG,
81
				   ARGP_KEY_END, ARGP_ERR_UNKNOWN */
307 by Teddy Hogeborn
Merge from Björn:
82
#include <signal.h>		/* sigemptyset(), sigaddset(),
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
83
				   sigaction(), SIGTERM, sig_atomic_t,
84
				   raise() */
307 by Teddy Hogeborn
Merge from Björn:
85
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
86
#ifdef __linux__
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
87
#include <sys/klog.h> 		/* klogctl() */
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
88
#endif	/* __linux__ */
24.1.26 by Björn Påhlsson
tally count of used symbols
89
90
/* Avahi */
24.1.29 by Björn Påhlsson
Added more header file comments
91
/* All Avahi types, constants and functions
92
 Avahi*, avahi_*,
93
 AVAHI_* */
94
#include <avahi-core/core.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
95
#include <avahi-core/lookup.h>
24.1.29 by Björn Påhlsson
Added more header file comments
96
#include <avahi-core/log.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
97
#include <avahi-common/simple-watch.h>
98
#include <avahi-common/malloc.h>
99
#include <avahi-common/error.h>
100
101
/* GnuTLS */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
102
#include <gnutls/gnutls.h>	/* All GnuTLS types, constants and
103
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
104
				   gnutls_*
24.1.26 by Björn Påhlsson
tally count of used symbols
105
				   init_gnutls_session(),
24.1.29 by Björn Påhlsson
Added more header file comments
106
				   GNUTLS_* */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
107
#include <gnutls/openpgp.h>
108
			  /* gnutls_certificate_set_openpgp_key_file(),
24.1.29 by Björn Påhlsson
Added more header file comments
109
				   GNUTLS_OPENPGP_FMT_BASE64 */
24.1.26 by Björn Påhlsson
tally count of used symbols
110
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
111
/* GPGME */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
112
#include <gpgme.h> 		/* All GPGME types, constants and
113
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
114
				   gpgme_*
24.1.26 by Björn Påhlsson
tally count of used symbols
115
				   GPGME_PROTOCOL_OpenPGP,
24.1.29 by Björn Påhlsson
Added more header file comments
116
				   GPG_ERR_NO_* */
13 by Björn Påhlsson
Added following support:
117
118
#define BUFFER_SIZE 256
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
119
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
120
#define PATHDIR "/conf/conf.d/mandos"
121
#define SECKEY "seckey.txt"
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
122
#define PUBKEY "pubkey.txt"
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
123
15.1.2 by Björn Påhlsson
Added debug options from passprompt as --debug and --debug=passprompt
124
bool debug = false;
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
125
static const char mandos_protocol_version[] = "1";
217 by Teddy Hogeborn
* .bzrignore: Added "man" directory (created by "make install-html").
126
const char *argp_program_version = "mandos-client " VERSION;
24.1.14 by Björn Påhlsson
mandosclient
127
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
128
static const char sys_class_net[] = "/sys/class/net";
129
char *connect_to = NULL;
24.1.10 by Björn Påhlsson
merge commit
130
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
131
/* Used for passing in values through the Avahi callback functions */
13 by Björn Påhlsson
Added following support:
132
typedef struct {
24.1.9 by Björn Påhlsson
not working midwork...
133
  AvahiSimplePoll *simple_poll;
134
  AvahiServer *server;
13 by Björn Påhlsson
Added following support:
135
  gnutls_certificate_credentials_t cred;
24.1.9 by Björn Påhlsson
not working midwork...
136
  unsigned int dh_bits;
24.1.13 by Björn Påhlsson
mandosclient
137
  gnutls_dh_params_t dh_params;
24.1.9 by Björn Påhlsson
not working midwork...
138
  const char *priority;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
139
  gpgme_ctx_t ctx;
24.1.9 by Björn Påhlsson
not working midwork...
140
} mandos_context;
13 by Björn Påhlsson
Added following support:
141
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
142
/* global context so signal handler can reach it*/
24.1.135 by Björn Påhlsson
Earlier signal handling
143
mandos_context mc = { .simple_poll = NULL, .server = NULL,
144
		      .dh_bits = 1024, .priority = "SECURE256"
145
		      ":!CTYPE-X.509:+CTYPE-OPENPGP" };
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
146
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
147
sig_atomic_t quit_now = 0;
148
int signal_received = 0;
149
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
150
/*
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
151
 * Make additional room in "buffer" for at least BUFFER_SIZE more
152
 * bytes. "buffer_capacity" is how much is currently allocated,
153
 * "buffer_length" is how much is already used.
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
154
 */
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
155
size_t incbuffer(char **buffer, size_t buffer_length,
24.1.10 by Björn Påhlsson
merge commit
156
		  size_t buffer_capacity){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
157
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
24.1.12 by Björn Påhlsson
merge +
158
    *buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
159
    if(buffer == NULL){
24.1.10 by Björn Påhlsson
merge commit
160
      return 0;
161
    }
162
    buffer_capacity += BUFFER_SIZE;
163
  }
164
  return buffer_capacity;
165
}
166
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
167
/* 
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
168
 * Initialize GPGME.
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
169
 */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
170
static bool init_gpgme(const char *seckey,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
171
		       const char *pubkey, const char *tempdir){
13 by Björn Påhlsson
Added following support:
172
  gpgme_error_t rc;
173
  gpgme_engine_info_t engine_info;
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
174
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
175
  
176
  /*
288 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Use separate bool variable instead
177
   * 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.
178
   */
179
  bool import_key(const char *filename){
361 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
180
    int ret;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
181
    int fd;
182
    gpgme_data_t pgp_data;
183
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
184
    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.
185
    if(fd == -1){
186
      perror("open");
187
      return false;
188
    }
189
    
190
    rc = gpgme_data_new_from_fd(&pgp_data, fd);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
191
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
192
      fprintf(stderr, "bad gpgme_data_new_from_fd: %s: %s\n",
193
	      gpgme_strsource(rc), gpgme_strerror(rc));
194
      return false;
195
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
196
    
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
197
    rc = gpgme_op_import(mc.ctx, pgp_data);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
198
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
199
      fprintf(stderr, "bad gpgme_op_import: %s: %s\n",
200
	      gpgme_strsource(rc), gpgme_strerror(rc));
201
      return false;
202
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
203
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
204
    ret = (int)TEMP_FAILURE_RETRY(close(fd));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
205
    if(ret == -1){
206
      perror("close");
207
    }
208
    gpgme_data_release(pgp_data);
209
    return true;
210
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
211
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
212
  if(debug){
307 by Teddy Hogeborn
Merge from Björn:
213
    fprintf(stderr, "Initializing GPGME\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
214
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
215
  
13 by Björn Påhlsson
Added following support:
216
  /* Init GPGME */
217
  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.
218
  rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
219
  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.
220
    fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
221
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
222
    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.
223
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
224
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
225
    /* Set GPGME home directory for the OpenPGP engine only */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
226
  rc = gpgme_get_engine_info(&engine_info);
227
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
228
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
229
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
230
    return false;
13 by Björn Påhlsson
Added following support:
231
  }
232
  while(engine_info != NULL){
233
    if(engine_info->protocol == GPGME_PROTOCOL_OpenPGP){
234
      gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
235
			    engine_info->file_name, tempdir);
13 by Björn Påhlsson
Added following support:
236
      break;
237
    }
238
    engine_info = engine_info->next;
239
  }
240
  if(engine_info == NULL){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
241
    fprintf(stderr, "Could not set GPGME home dir to %s\n", tempdir);
242
    return false;
243
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
244
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
245
  /* Create new GPGME "context" */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
246
  rc = gpgme_new(&(mc.ctx));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
247
  if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
248
    fprintf(stderr, "bad gpgme_new: %s: %s\n",
249
	    gpgme_strsource(rc), gpgme_strerror(rc));
250
    return false;
251
  }
252
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
253
  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.
254
    return false;
255
  }
256
  
355 by Teddy Hogeborn
* mandos: White-space fixes only.
257
  return true;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
258
}
259
260
/* 
261
 * Decrypt OpenPGP data.
262
 * Returns -1 on error
263
 */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
264
static ssize_t pgp_packet_decrypt(const char *cryptotext,
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
265
				  size_t crypto_size,
266
				  char **plaintext){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
267
  gpgme_data_t dh_crypto, dh_plain;
268
  gpgme_error_t rc;
269
  ssize_t ret;
270
  size_t plaintext_capacity = 0;
271
  ssize_t plaintext_length = 0;
272
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
273
  if(debug){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
274
    fprintf(stderr, "Trying to decrypt OpenPGP data\n");
13 by Björn Påhlsson
Added following support:
275
  }
276
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
277
  /* Create new GPGME data buffer from memory cryptotext */
278
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
279
			       0);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
280
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
281
    fprintf(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
282
	    gpgme_strsource(rc), gpgme_strerror(rc));
283
    return -1;
284
  }
285
  
286
  /* Create new empty GPGME data buffer for the plaintext */
287
  rc = gpgme_data_new(&dh_plain);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
288
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
289
    fprintf(stderr, "bad gpgme_data_new: %s: %s\n",
290
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
291
    gpgme_data_release(dh_crypto);
13 by Björn Påhlsson
Added following support:
292
    return -1;
293
  }
294
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
295
  /* Decrypt data from the cryptotext data buffer to the plaintext
296
     data buffer */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
297
  rc = gpgme_op_decrypt(mc.ctx, dh_crypto, dh_plain);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
298
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
299
    fprintf(stderr, "bad gpgme_op_decrypt: %s: %s\n",
300
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
301
    plaintext_length = -1;
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
302
    if(debug){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
303
      gpgme_decrypt_result_t result;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
304
      result = gpgme_op_decrypt_result(mc.ctx);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
305
      if(result == NULL){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
306
	fprintf(stderr, "gpgme_op_decrypt_result failed\n");
307
      } else {
308
	fprintf(stderr, "Unsupported algorithm: %s\n",
309
		result->unsupported_algorithm);
310
	fprintf(stderr, "Wrong key usage: %u\n",
311
		result->wrong_key_usage);
312
	if(result->file_name != NULL){
313
	  fprintf(stderr, "File name: %s\n", result->file_name);
314
	}
315
	gpgme_recipient_t recipient;
316
	recipient = result->recipients;
349 by Teddy Hogeborn
* plugins.d/mandos-client.c (pgp_packet_decrypt): Remove redundant
317
	while(recipient != NULL){
318
	  fprintf(stderr, "Public key algorithm: %s\n",
319
		  gpgme_pubkey_algo_name(recipient->pubkey_algo));
320
	  fprintf(stderr, "Key ID: %s\n", recipient->keyid);
321
	  fprintf(stderr, "Secret key available: %s\n",
322
		  recipient->status == GPG_ERR_NO_SECKEY
323
		  ? "No" : "Yes");
324
	  recipient = recipient->next;
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
325
	}
326
      }
327
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
328
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
329
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
330
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
331
  if(debug){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
332
    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
333
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
334
  
13 by Björn Påhlsson
Added following support:
335
  /* Seek back to the beginning of the GPGME plaintext data buffer */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
336
  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
337
    perror("gpgme_data_seek");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
338
    plaintext_length = -1;
339
    goto decrypt_end;
24.1.5 by Björn Påhlsson
plugbasedclient:
340
  }
341
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
342
  *plaintext = NULL;
13 by Björn Påhlsson
Added following support:
343
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
344
    plaintext_capacity = incbuffer(plaintext,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
345
				      (size_t)plaintext_length,
24.1.12 by Björn Påhlsson
merge +
346
				      plaintext_capacity);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
347
    if(plaintext_capacity == 0){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
348
	perror("incbuffer");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
349
	plaintext_length = -1;
350
	goto decrypt_end;
13 by Björn Påhlsson
Added following support:
351
    }
352
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
353
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
354
			  BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
355
    /* Print the data, if any */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
356
    if(ret == 0){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
357
      /* EOF */
13 by Björn Påhlsson
Added following support:
358
      break;
359
    }
360
    if(ret < 0){
361
      perror("gpgme_data_read");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
362
      plaintext_length = -1;
363
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
364
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
365
    plaintext_length += ret;
13 by Björn Påhlsson
Added following support:
366
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
367
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
368
  if(debug){
369
    fprintf(stderr, "Decrypted password is: ");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
370
    for(ssize_t i = 0; i < plaintext_length; i++){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
371
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
372
    }
373
    fprintf(stderr, "\n");
374
  }
375
  
376
 decrypt_end:
377
  
378
  /* Delete the GPGME cryptotext data buffer */
379
  gpgme_data_release(dh_crypto);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
380
  
381
  /* Delete the GPGME plaintext data buffer */
13 by Björn Påhlsson
Added following support:
382
  gpgme_data_release(dh_plain);
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
383
  return plaintext_length;
13 by Björn Påhlsson
Added following support:
384
}
385
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
386
static const char * safer_gnutls_strerror(int value){
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
387
  const char *ret = gnutls_strerror(value); /* Spurious warning from
388
					       -Wunreachable-code */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
389
  if(ret == NULL)
13 by Björn Påhlsson
Added following support:
390
    ret = "(unknown)";
391
  return ret;
392
}
393
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
394
/* GnuTLS log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
395
static void debuggnutls(__attribute__((unused)) int level,
396
			const char* string){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
397
  fprintf(stderr, "GnuTLS: %s", string);
13 by Björn Påhlsson
Added following support:
398
}
399
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
400
static int init_gnutls_global(const char *pubkeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
401
			      const char *seckeyfilename){
13 by Björn Påhlsson
Added following support:
402
  int ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
403
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
404
  if(debug){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
405
    fprintf(stderr, "Initializing GnuTLS\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
406
  }
24.1.29 by Björn Påhlsson
Added more header file comments
407
  
408
  ret = gnutls_global_init();
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
409
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
410
    fprintf(stderr, "GnuTLS global_init: %s\n",
411
	    safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
412
    return -1;
413
  }
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
414
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
415
  if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
416
    /* "Use a log level over 10 to enable all debugging options."
417
     * - GnuTLS manual
418
     */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
419
    gnutls_global_set_log_level(11);
420
    gnutls_global_set_log_function(debuggnutls);
421
  }
422
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
423
  /* OpenPGP credentials */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
424
  gnutls_certificate_allocate_credentials(&mc.cred);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
425
  if(ret != GNUTLS_E_SUCCESS){
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
426
    fprintf(stderr, "GnuTLS memory error: %s\n", /* Spurious warning
304 by Teddy Hogeborn
Four new interrelated features:
427
						    from
428
						    -Wunreachable-code
429
						 */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
430
	    safer_gnutls_strerror(ret));
431
    gnutls_global_deinit();
13 by Björn Påhlsson
Added following support:
432
    return -1;
433
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
434
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
435
  if(debug){
147 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Improved wording
436
    fprintf(stderr, "Attempting to use OpenPGP public key %s and"
437
	    " secret key %s as GnuTLS credentials\n", pubkeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
438
	    seckeyfilename);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
439
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
440
  
13 by Björn Påhlsson
Added following support:
441
  ret = gnutls_certificate_set_openpgp_key_file
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
442
    (mc.cred, pubkeyfilename, seckeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
443
     GNUTLS_OPENPGP_FMT_BASE64);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
444
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
445
    fprintf(stderr,
446
	    "Error[%d] while reading the OpenPGP key pair ('%s',"
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
447
	    " '%s')\n", ret, pubkeyfilename, seckeyfilename);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
448
    fprintf(stderr, "The GnuTLS error is: %s\n",
13 by Björn Påhlsson
Added following support:
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
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
453
  /* GnuTLS server initialization */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
454
  ret = gnutls_dh_params_init(&mc.dh_params);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
455
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
456
    fprintf(stderr, "Error in GnuTLS DH parameter initialization:"
457
	    " %s\n", safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
458
    goto globalfail;
13 by Björn Påhlsson
Added following support:
459
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
460
  ret = gnutls_dh_params_generate2(mc.dh_params, mc.dh_bits);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
461
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
462
    fprintf(stderr, "Error in GnuTLS prime generation: %s\n",
463
	    safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
464
    goto globalfail;
13 by Björn Påhlsson
Added following support:
465
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
466
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
467
  gnutls_certificate_set_dh_params(mc.cred, mc.dh_params);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
468
  
24.1.13 by Björn Påhlsson
mandosclient
469
  return 0;
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
470
  
24.1.20 by Björn Påhlsson
mandosclient
471
 globalfail:
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
472
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
473
  gnutls_certificate_free_credentials(mc.cred);
24.1.26 by Björn Påhlsson
tally count of used symbols
474
  gnutls_global_deinit();
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
475
  gnutls_dh_params_deinit(mc.dh_params);
24.1.20 by Björn Påhlsson
mandosclient
476
  return -1;
24.1.13 by Björn Påhlsson
mandosclient
477
}
478
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
479
static int init_gnutls_session(gnutls_session_t *session){
24.1.13 by Björn Påhlsson
mandosclient
480
  int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
481
  /* GnuTLS session creation */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
482
  do {
483
    ret = gnutls_init(session, GNUTLS_SERVER);
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
484
    if(quit_now){
485
      return -1;
486
    }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
487
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
488
  if(ret != GNUTLS_E_SUCCESS){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
489
    fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
13 by Björn Påhlsson
Added following support:
490
	    safer_gnutls_strerror(ret));
491
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
492
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
493
  {
494
    const char *err;
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
495
    do {
496
      ret = gnutls_priority_set_direct(*session, mc.priority, &err);
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
497
      if(quit_now){
498
	gnutls_deinit(*session);
499
	return -1;
500
      }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
501
    } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
502
    if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
503
      fprintf(stderr, "Syntax error at: %s\n", err);
504
      fprintf(stderr, "GnuTLS error: %s\n",
505
	      safer_gnutls_strerror(ret));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
506
      gnutls_deinit(*session);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
507
      return -1;
508
    }
13 by Björn Påhlsson
Added following support:
509
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
510
  
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
511
  do {
512
    ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
513
				 mc.cred);
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
514
    if(quit_now){
515
      gnutls_deinit(*session);
516
      return -1;
517
    }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
518
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
519
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
520
    fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
13 by Björn Påhlsson
Added following support:
521
	    safer_gnutls_strerror(ret));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
522
    gnutls_deinit(*session);
13 by Björn Påhlsson
Added following support:
523
    return -1;
524
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
525
  
13 by Björn Påhlsson
Added following support:
526
  /* ignore client certificate if any. */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
527
  gnutls_certificate_server_set_request(*session, GNUTLS_CERT_IGNORE);
13 by Björn Påhlsson
Added following support:
528
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
529
  gnutls_dh_set_prime_bits(*session, mc.dh_bits);
13 by Björn Påhlsson
Added following support:
530
  
531
  return 0;
532
}
533
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
534
/* Avahi log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
535
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
536
		      __attribute__((unused)) const char *txt){}
13 by Björn Påhlsson
Added following support:
537
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
538
/* Called when a Mandos server is found */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
539
static int start_mandos_communication(const char *ip, uint16_t port,
24.1.9 by Björn Påhlsson
not working midwork...
540
				      AvahiIfIndex if_index,
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
541
				      int af){
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
542
  int ret, tcp_sd = -1;
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
543
  ssize_t sret;
304 by Teddy Hogeborn
Four new interrelated features:
544
  union {
545
    struct sockaddr_in in;
546
    struct sockaddr_in6 in6;
547
  } to;
13 by Björn Påhlsson
Added following support:
548
  char *buffer = NULL;
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
549
  char *decrypted_buffer = NULL;
13 by Björn Påhlsson
Added following support:
550
  size_t buffer_length = 0;
551
  size_t buffer_capacity = 0;
24.1.10 by Björn Påhlsson
merge commit
552
  size_t written;
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
553
  int retval = -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
554
  gnutls_session_t session;
304 by Teddy Hogeborn
Four new interrelated features:
555
  int pf;			/* Protocol family */
556
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
557
  if(quit_now){
558
    return -1;
559
  }
560
  
304 by Teddy Hogeborn
Four new interrelated features:
561
  switch(af){
562
  case AF_INET6:
563
    pf = PF_INET6;
564
    break;
565
  case AF_INET:
566
    pf = PF_INET;
567
    break;
568
  default:
569
    fprintf(stderr, "Bad address family: %d\n", af);
570
    return -1;
571
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
572
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
573
  ret = init_gnutls_session(&session);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
574
  if(ret != 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
575
    return -1;
576
  }
577
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
578
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
579
    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.
580
	    "\n", ip, port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
581
  }
13 by Björn Påhlsson
Added following support:
582
  
304 by Teddy Hogeborn
Four new interrelated features:
583
  tcp_sd = socket(pf, SOCK_STREAM, 0);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
584
  if(tcp_sd < 0){
13 by Björn Påhlsson
Added following support:
585
    perror("socket");
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
586
    goto mandos_end;
587
  }
588
  
589
  if(quit_now){
590
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
591
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
592
  
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
593
  memset(&to, 0, sizeof(to));
304 by Teddy Hogeborn
Four new interrelated features:
594
  if(af == AF_INET6){
325 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): "sin6_family"
595
    to.in6.sin6_family = (sa_family_t)af;
304 by Teddy Hogeborn
Four new interrelated features:
596
    ret = inet_pton(af, ip, &to.in6.sin6_addr);
597
  } else {			/* IPv4 */
598
    to.in.sin_family = (sa_family_t)af;
599
    ret = inet_pton(af, ip, &to.in.sin_addr);
600
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
601
  if(ret < 0 ){
13 by Björn Påhlsson
Added following support:
602
    perror("inet_pton");
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
603
    goto mandos_end;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
604
  }
13 by Björn Påhlsson
Added following support:
605
  if(ret == 0){
606
    fprintf(stderr, "Bad address: %s\n", ip);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
607
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
608
  }
304 by Teddy Hogeborn
Four new interrelated features:
609
  if(af == AF_INET6){
610
    to.in6.sin6_port = htons(port); /* Spurious warnings from
611
				       -Wconversion and
612
				       -Wunreachable-code */
613
    
614
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
615
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
616
			      -Wunreachable-code*/
617
      if(if_index == AVAHI_IF_UNSPEC){
618
	fprintf(stderr, "An IPv6 link-local address is incomplete"
619
		" without a network interface\n");
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
620
	goto mandos_end;
304 by Teddy Hogeborn
Four new interrelated features:
621
      }
622
      /* Set the network interface number as scope */
623
      to.in6.sin6_scope_id = (uint32_t)if_index;
624
    }
625
  } else {
626
    to.in.sin_port = htons(port); /* Spurious warnings from
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
627
				     -Wconversion and
628
				     -Wunreachable-code */
304 by Teddy Hogeborn
Four new interrelated features:
629
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
630
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
631
  if(quit_now){
632
    goto mandos_end;
633
  }
634
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
635
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
636
    if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){
637
      char interface[IF_NAMESIZE];
638
      if(if_indextoname((unsigned int)if_index, interface) == NULL){
639
	perror("if_indextoname");
640
      } else {
641
	fprintf(stderr, "Connection to: %s%%%s, port %" PRIu16 "\n",
642
		ip, interface, port);
643
      }
644
    } else {
645
      fprintf(stderr, "Connection to: %s, port %" PRIu16 "\n", ip,
646
	      port);
647
    }
648
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
649
		 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
650
    const char *pcret;
651
    if(af == AF_INET6){
652
      pcret = inet_ntop(af, &(to.in6.sin6_addr), addrstr,
653
			sizeof(addrstr));
654
    } else {
655
      pcret = inet_ntop(af, &(to.in.sin_addr), addrstr,
656
			sizeof(addrstr));
657
    }
658
    if(pcret == NULL){
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
659
      perror("inet_ntop");
660
    } else {
661
      if(strcmp(addrstr, ip) != 0){
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
662
	fprintf(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
663
      }
664
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
665
  }
13 by Björn Påhlsson
Added following support:
666
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
667
  if(quit_now){
668
    goto mandos_end;
669
  }
670
  
304 by Teddy Hogeborn
Four new interrelated features:
671
  if(af == AF_INET6){
672
    ret = connect(tcp_sd, &to.in6, sizeof(to));
673
  } else {
674
    ret = connect(tcp_sd, &to.in, sizeof(to)); /* IPv4 */
675
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
676
  if(ret < 0){
13 by Björn Påhlsson
Added following support:
677
    perror("connect");
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
678
    goto mandos_end;
679
  }
680
  
681
  if(quit_now){
682
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
683
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
684
  
24.1.12 by Björn Påhlsson
merge +
685
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
686
  written = 0;
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
687
  while(true){
24.1.10 by Björn Påhlsson
merge commit
688
    size_t out_size = strlen(out);
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
689
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
24.1.10 by Björn Påhlsson
merge commit
690
				   out_size - written));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
691
    if(ret == -1){
24.1.10 by Björn Påhlsson
merge commit
692
      perror("write");
24.1.12 by Björn Påhlsson
merge +
693
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
694
    }
24.1.12 by Björn Påhlsson
merge +
695
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
696
    if(written < out_size){
697
      continue;
698
    } else {
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
699
      if(out == mandos_protocol_version){
24.1.10 by Björn Påhlsson
merge commit
700
	written = 0;
701
	out = "\r\n";
702
      } else {
703
	break;
704
      }
705
    }
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
706
  
707
    if(quit_now){
708
      goto mandos_end;
709
    }
24.1.10 by Björn Påhlsson
merge commit
710
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
711
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
712
  if(debug){
713
    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
714
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
715
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
716
  if(quit_now){
717
    goto mandos_end;
718
  }
719
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
720
  gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) tcp_sd);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
721
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
722
  if(quit_now){
723
    goto mandos_end;
724
  }
725
  
363 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
726
  do {
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
727
    ret = gnutls_handshake(session);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
728
    if(quit_now){
729
      goto mandos_end;
730
    }
24.1.29 by Björn Påhlsson
Added more header file comments
731
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
13 by Björn Påhlsson
Added following support:
732
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
733
  if(ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
734
    if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
735
      fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
736
      gnutls_perror(ret);
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
737
    }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
738
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
739
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
740
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
741
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
742
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
743
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
744
    fprintf(stderr, "Retrieving OpenPGP encrypted password from %s\n",
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
745
	    ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
746
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
747
  
13 by Björn Påhlsson
Added following support:
748
  while(true){
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
749
    
750
    if(quit_now){
751
      goto mandos_end;
752
    }
753
    
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
754
    buffer_capacity = incbuffer(&buffer, buffer_length,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
755
				   buffer_capacity);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
756
    if(buffer_capacity == 0){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
757
      perror("incbuffer");
24.1.12 by Björn Påhlsson
merge +
758
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
759
    }
760
    
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
761
    if(quit_now){
762
      goto mandos_end;
763
    }
764
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
765
    sret = gnutls_record_recv(session, buffer+buffer_length,
766
			      BUFFER_SIZE);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
767
    if(sret == 0){
13 by Björn Påhlsson
Added following support:
768
      break;
769
    }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
770
    if(sret < 0){
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
771
      switch(sret){
13 by Björn Påhlsson
Added following support:
772
      case GNUTLS_E_INTERRUPTED:
773
      case GNUTLS_E_AGAIN:
774
	break;
775
      case GNUTLS_E_REHANDSHAKE:
363 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
776
	do {
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
777
	  ret = gnutls_handshake(session);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
778
	  
779
	  if(quit_now){
780
	    goto mandos_end;
781
	  }
24.1.29 by Björn Påhlsson
Added more header file comments
782
	} while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
783
	if(ret < 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
784
	  fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
785
	  gnutls_perror(ret);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
786
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
787
	}
788
	break;
789
      default:
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
790
	fprintf(stderr, "Unknown error while reading data from"
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
791
		" encrypted session with Mandos server\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
792
	gnutls_bye(session, GNUTLS_SHUT_RDWR);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
793
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
794
      }
795
    } else {
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
796
      buffer_length += (size_t) sret;
13 by Björn Påhlsson
Added following support:
797
    }
798
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
799
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
800
  if(debug){
801
    fprintf(stderr, "Closing TLS session\n");
802
  }
803
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
804
  if(quit_now){
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
805
    goto mandos_end;
806
  }
807
  
808
  do {
809
    ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
810
    if(quit_now){
811
      goto mandos_end;
812
    }
813
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
814
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
815
  if(buffer_length > 0){
362 by Teddy Hogeborn
* plugin-runner.c (getplugin, add_environment, main): Handle EINTR
816
    ssize_t decrypted_buffer_size;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
817
    decrypted_buffer_size = pgp_packet_decrypt(buffer,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
818
					       buffer_length,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
819
					       &decrypted_buffer);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
820
    if(decrypted_buffer_size >= 0){
361 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
821
      
24.1.10 by Björn Påhlsson
merge commit
822
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
823
      while(written < (size_t) decrypted_buffer_size){
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
824
	if(quit_now){
825
	  goto mandos_end;
826
	}
827
	
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
828
	ret = (int)fwrite(decrypted_buffer + written, 1,
829
			  (size_t)decrypted_buffer_size - written,
830
			  stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
831
	if(ret == 0 and ferror(stdout)){
832
	  if(debug){
833
	    fprintf(stderr, "Error writing encrypted data: %s\n",
834
		    strerror(errno));
835
	  }
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
836
	  goto mandos_end;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
837
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
838
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
839
      }
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
840
      retval = 0;
13 by Björn Påhlsson
Added following support:
841
    }
842
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
843
  
844
  /* Shutdown procedure */
845
  
846
 mandos_end:
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
847
  free(decrypted_buffer);
13 by Björn Påhlsson
Added following support:
848
  free(buffer);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
849
  if(tcp_sd >= 0){
850
    ret = (int)TEMP_FAILURE_RETRY(close(tcp_sd));
851
  }
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
852
  if(ret == -1){
853
    perror("close");
854
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
855
  gnutls_deinit(session);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
856
  if(quit_now){
857
    retval = -1;
858
  }
13 by Björn Påhlsson
Added following support:
859
  return retval;
860
}
861
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
862
static void resolve_callback(AvahiSServiceResolver *r,
863
			     AvahiIfIndex interface,
304 by Teddy Hogeborn
Four new interrelated features:
864
			     AvahiProtocol proto,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
865
			     AvahiResolverEvent event,
866
			     const char *name,
867
			     const char *type,
868
			     const char *domain,
869
			     const char *host_name,
870
			     const AvahiAddress *address,
871
			     uint16_t port,
872
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
873
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
874
			     flags,
307 by Teddy Hogeborn
Merge from Björn:
875
			     AVAHI_GCC_UNUSED void* userdata){
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
876
  assert(r);
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
877
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
878
  /* Called whenever a service has been resolved successfully or
879
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
880
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
881
  if(quit_now){
882
    return;
883
  }
884
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
885
  switch(event){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
886
  default:
887
  case AVAHI_RESOLVER_FAILURE:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
888
    fprintf(stderr, "(Avahi Resolver) Failed to resolve service '%s'"
889
	    " of type '%s' in domain '%s': %s\n", name, type, domain,
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
890
	    avahi_strerror(avahi_server_errno(mc.server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
891
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
892
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
893
  case AVAHI_RESOLVER_FOUND:
894
    {
895
      char ip[AVAHI_ADDRESS_STR_MAX];
896
      avahi_address_snprint(ip, sizeof(ip), address);
897
      if(debug){
60 by Teddy Hogeborn
* mandos-client.c (main): Cast pid_t to unsigned int before printing.
898
	fprintf(stderr, "Mandos server \"%s\" found on %s (%s, %"
268 by Teddy Hogeborn
Fixes for sscanf usage:
899
		PRIdMAX ") on port %" PRIu16 "\n", name, host_name,
900
		ip, (intmax_t)interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
901
      }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
902
      int ret = start_mandos_communication(ip, port, interface,
304 by Teddy Hogeborn
Four new interrelated features:
903
					   avahi_proto_to_af(proto));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
904
      if(ret == 0){
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
905
	avahi_simple_poll_quit(mc.simple_poll);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
906
      }
13 by Björn Påhlsson
Added following support:
907
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
908
  }
909
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
910
}
911
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
912
static void browse_callback(AvahiSServiceBrowser *b,
913
			    AvahiIfIndex interface,
914
			    AvahiProtocol protocol,
915
			    AvahiBrowserEvent event,
916
			    const char *name,
917
			    const char *type,
918
			    const char *domain,
919
			    AVAHI_GCC_UNUSED AvahiLookupResultFlags
920
			    flags,
307 by Teddy Hogeborn
Merge from Björn:
921
			    AVAHI_GCC_UNUSED void* userdata){
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
922
  assert(b);
24.1.9 by Björn Påhlsson
not working midwork...
923
  
924
  /* Called whenever a new services becomes available on the LAN or
925
     is removed from the LAN */
926
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
927
  if(quit_now){
928
    return;
929
  }
930
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
931
  switch(event){
24.1.9 by Björn Påhlsson
not working midwork...
932
  default:
933
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
934
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
935
    fprintf(stderr, "(Avahi browser) %s\n",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
936
	    avahi_strerror(avahi_server_errno(mc.server)));
937
    avahi_simple_poll_quit(mc.simple_poll);
24.1.9 by Björn Påhlsson
not working midwork...
938
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
939
    
24.1.9 by Björn Påhlsson
not working midwork...
940
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
941
    /* We ignore the returned Avahi resolver object. In the callback
942
       function we free it. If the Avahi server is terminated before
943
       the callback function is called the Avahi server will free the
944
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
945
    
313 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
946
    if(avahi_s_service_resolver_new(mc.server, interface, protocol,
947
				    name, type, domain, protocol, 0,
948
				    resolve_callback, NULL) == NULL)
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
949
      fprintf(stderr, "Avahi: Failed to resolve service '%s': %s\n",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
950
	      name, avahi_strerror(avahi_server_errno(mc.server)));
24.1.9 by Björn Påhlsson
not working midwork...
951
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
952
    
24.1.9 by Björn Påhlsson
not working midwork...
953
  case AVAHI_BROWSER_REMOVE:
954
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
955
    
24.1.9 by Björn Påhlsson
not working midwork...
956
  case AVAHI_BROWSER_ALL_FOR_NOW:
957
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
958
    if(debug){
959
      fprintf(stderr, "No Mandos server found, still searching...\n");
960
    }
24.1.9 by Björn Påhlsson
not working midwork...
961
    break;
962
  }
13 by Björn Påhlsson
Added following support:
963
}
964
24.1.135 by Björn Påhlsson
Earlier signal handling
965
/* stop main loop after sigterm has been called */
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
966
static void handle_sigterm(int sig){
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
967
  if(quit_now){
968
    return;
969
  }
970
  quit_now = 1;
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
971
  signal_received = sig;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
972
  int old_errno = errno;
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
973
  if(mc.simple_poll != NULL){
974
    avahi_simple_poll_quit(mc.simple_poll);
975
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
976
  errno = old_errno;
977
}
978
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
979
/* 
980
 * This function determines if a directory entry in /sys/class/net
981
 * corresponds to an acceptable network device.
982
 * (This function is passed to scandir(3) as a filter function.)
983
 */
984
int good_interface(const struct dirent *if_entry){
985
  ssize_t ssret;
986
  char *flagname = NULL;
987
  int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net,
988
		     if_entry->d_name);
989
  if(ret < 0){
990
    perror("asprintf");
991
    return 0;
992
  }
993
  if(if_entry->d_name[0] == '.'){
994
    return 0;
995
  }
996
  int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY));
997
  if(flags_fd == -1){
998
    perror("open");
999
    return 0;
1000
  }
1001
  typedef short ifreq_flags;	/* ifreq.ifr_flags in netdevice(7) */
1002
  /* read line from flags_fd */
1003
  ssize_t to_read = (sizeof(ifreq_flags)*2)+3; /* "0x1003\n" */
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1004
  char *flagstring = malloc((size_t)to_read+1); /* +1 for final \0 */
1005
  flagstring[(size_t)to_read] = '\0';
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1006
  if(flagstring == NULL){
1007
    perror("malloc");
1008
    close(flags_fd);
1009
    return 0;
1010
  }
1011
  while(to_read > 0){
1012
    ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring,
1013
					     (size_t)to_read));
1014
    if(ssret == -1){
1015
      perror("read");
1016
      free(flagstring);
1017
      close(flags_fd);
1018
      return 0;
1019
    }
1020
    to_read -= ssret;
1021
    if(ssret == 0){
1022
      break;
1023
    }
1024
  }
1025
  close(flags_fd);
1026
  intmax_t tmpmax;
1027
  char *tmp;
1028
  errno = 0;
1029
  tmpmax = strtoimax(flagstring, &tmp, 0);
1030
  if(errno != 0 or tmp == flagstring or (*tmp != '\0'
1031
					 and not (isspace(*tmp)))
1032
     or tmpmax != (ifreq_flags)tmpmax){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1033
    if(debug){
1034
      fprintf(stderr, "Invalid flags \"%s\" for interface \"%s\"\n",
1035
	      flagstring, if_entry->d_name);
1036
    }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1037
    free(flagstring);
1038
    return 0;
1039
  }
1040
  free(flagstring);
1041
  ifreq_flags flags = (ifreq_flags)tmpmax;
1042
  /* Reject the loopback device */
1043
  if(flags & IFF_LOOPBACK){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1044
    if(debug){
1045
      fprintf(stderr, "Rejecting loopback interface \"%s\"\n",
1046
	      if_entry->d_name);
1047
    }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1048
    return 0;
1049
  }
1050
  /* Accept point-to-point devices only if connect_to is specified */
1051
  if(connect_to != NULL and (flags & IFF_POINTOPOINT)){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1052
    if(debug){
1053
      fprintf(stderr, "Accepting point-to-point interface \"%s\"\n",
1054
	      if_entry->d_name);
1055
    }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1056
    return 1;
1057
  }
1058
  /* Otherwise, reject non-broadcast-capable devices */
1059
  if(not (flags & IFF_BROADCAST)){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1060
    if(debug){
1061
      fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n",
1062
	      if_entry->d_name);
1063
    }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1064
    return 0;
1065
  }
1066
  /* Accept this device */
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1067
  if(debug){
1068
    fprintf(stderr, "Interface \"%s\" is acceptable\n",
1069
	    if_entry->d_name);
1070
  }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1071
  return 1;
1072
}
1073
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1074
int main(int argc, char *argv[]){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1075
  AvahiSServiceBrowser *sb = NULL;
1076
  int error;
1077
  int ret;
1078
  intmax_t tmpmax;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1079
  char *tmp;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1080
  int exitcode = EXIT_SUCCESS;
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1081
  const char *interface = "";
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1082
  struct ifreq network;
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1083
  int sd = -1;
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1084
  bool take_down_interface = false;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1085
  uid_t uid;
1086
  gid_t gid;
1087
  char tempdir[] = "/tmp/mandosXXXXXX";
1088
  bool tempdir_created = false;
1089
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
1090
  const char *seckey = PATHDIR "/" SECKEY;
1091
  const char *pubkey = PATHDIR "/" PUBKEY;
1092
  
1093
  bool gnutls_initialized = false;
1094
  bool gpgme_initialized = false;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1095
  float delay = 2.5f;
1096
  
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
1097
  struct sigaction old_sigterm_action = { .sa_handler = SIG_DFL };
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1098
  struct sigaction sigterm_action = { .sa_handler = handle_sigterm };
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1099
  
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1100
  uid = getuid();
1101
  gid = getgid();
1102
  
1103
  /* Lower any group privileges we might have, just to be safe */
1104
  errno = 0;
1105
  ret = setgid(gid);
1106
  if(ret == -1){
1107
    perror("setgid");
1108
  }
1109
  
1110
  /* Lower user privileges (temporarily) */
1111
  errno = 0;
1112
  ret = seteuid(uid);
1113
  if(ret == -1){
1114
    perror("seteuid");
1115
  }
1116
  
1117
  if(quit_now){
1118
    goto end;
1119
  }
1120
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1121
  {
1122
    struct argp_option options[] = {
1123
      { .name = "debug", .key = 128,
1124
	.doc = "Debug mode", .group = 3 },
1125
      { .name = "connect", .key = 'c',
1126
	.arg = "ADDRESS:PORT",
1127
	.doc = "Connect directly to a specific Mandos server",
1128
	.group = 1 },
1129
      { .name = "interface", .key = 'i',
1130
	.arg = "NAME",
304 by Teddy Hogeborn
Four new interrelated features:
1131
	.doc = "Network interface that will be used to search for"
1132
	" Mandos servers",
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1133
	.group = 1 },
1134
      { .name = "seckey", .key = 's',
1135
	.arg = "FILE",
1136
	.doc = "OpenPGP secret key file base name",
1137
	.group = 1 },
1138
      { .name = "pubkey", .key = 'p',
1139
	.arg = "FILE",
1140
	.doc = "OpenPGP public key file base name",
1141
	.group = 2 },
1142
      { .name = "dh-bits", .key = 129,
1143
	.arg = "BITS",
1144
	.doc = "Bit length of the prime number used in the"
1145
	" Diffie-Hellman key exchange",
1146
	.group = 2 },
1147
      { .name = "priority", .key = 130,
1148
	.arg = "STRING",
1149
	.doc = "GnuTLS priority string for the TLS handshake",
1150
	.group = 1 },
1151
      { .name = "delay", .key = 131,
1152
	.arg = "SECONDS",
1153
	.doc = "Maximum delay to wait for interface startup",
1154
	.group = 2 },
1155
      { .name = NULL }
1156
    };
1157
    
1158
    error_t parse_opt(int key, char *arg,
1159
		      struct argp_state *state){
1160
      switch(key){
1161
      case 128:			/* --debug */
1162
	debug = true;
1163
	break;
1164
      case 'c':			/* --connect */
1165
	connect_to = arg;
1166
	break;
1167
      case 'i':			/* --interface */
1168
	interface = arg;
1169
	break;
1170
      case 's':			/* --seckey */
1171
	seckey = arg;
1172
	break;
1173
      case 'p':			/* --pubkey */
1174
	pubkey = arg;
1175
	break;
1176
      case 129:			/* --dh-bits */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1177
	errno = 0;
1178
	tmpmax = strtoimax(arg, &tmp, 10);
1179
	if(errno != 0 or tmp == arg or *tmp != '\0'
1180
	   or tmpmax != (typeof(mc.dh_bits))tmpmax){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1181
	  fprintf(stderr, "Bad number of DH bits\n");
1182
	  exit(EXIT_FAILURE);
1183
	}
1184
	mc.dh_bits = (typeof(mc.dh_bits))tmpmax;
1185
	break;
1186
      case 130:			/* --priority */
1187
	mc.priority = arg;
1188
	break;
1189
      case 131:			/* --delay */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1190
	errno = 0;
1191
	delay = strtof(arg, &tmp);
1192
	if(errno != 0 or tmp == arg or *tmp != '\0'){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1193
	  fprintf(stderr, "Bad delay\n");
1194
	  exit(EXIT_FAILURE);
1195
	}
1196
	break;
1197
      case ARGP_KEY_ARG:
1198
	argp_usage(state);
1199
      case ARGP_KEY_END:
1200
	break;
1201
      default:
1202
	return ARGP_ERR_UNKNOWN;
1203
      }
1204
      return 0;
1205
    }
1206
    
1207
    struct argp argp = { .options = options, .parser = parse_opt,
1208
			 .args_doc = "",
1209
			 .doc = "Mandos client -- Get and decrypt"
1210
			 " passwords from a Mandos server" };
1211
    ret = argp_parse(&argp, argc, argv, 0, 0, NULL);
1212
    if(ret == ARGP_ERR_UNKNOWN){
1213
      fprintf(stderr, "Unknown error while parsing arguments\n");
1214
      exitcode = EXIT_FAILURE;
1215
      goto end;
1216
    }
1217
  }
1218
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1219
  if(not debug){
1220
    avahi_set_log_function(empty_log);
1221
  }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1222
1223
  if(interface[0] == '\0'){
1224
    struct dirent **direntries;
1225
    ret = scandir(sys_class_net, &direntries, good_interface,
1226
		  alphasort);
1227
    if(ret >= 1){
1228
      /* Pick the first good interface */
1229
      interface = strdup(direntries[0]->d_name);
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1230
      if(debug){
1231
	fprintf(stderr, "Using interface \"%s\"\n", interface);
1232
      }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1233
      if(interface == NULL){
1234
	perror("malloc");
1235
	free(direntries);
1236
	exitcode = EXIT_FAILURE;
1237
	goto end;
1238
      }
1239
      free(direntries);
1240
    } else {
1241
      free(direntries);
1242
      fprintf(stderr, "Could not find a network interface\n");
1243
      exitcode = EXIT_FAILURE;
1244
      goto end;
1245
    }
1246
  }
309 by Teddy Hogeborn
Merge from Björn:
1247
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1248
  /* Initialize Avahi early so avahi_simple_poll_quit() can be called
1249
     from the signal handler */
1250
  /* Initialize the pseudo-RNG for Avahi */
1251
  srand((unsigned int) time(NULL));
1252
  mc.simple_poll = avahi_simple_poll_new();
1253
  if(mc.simple_poll == NULL){
1254
    fprintf(stderr, "Avahi: Failed to create simple poll object.\n");
1255
    exitcode = EXIT_FAILURE;
1256
    goto end;
1257
  }
309 by Teddy Hogeborn
Merge from Björn:
1258
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1259
  sigemptyset(&sigterm_action.sa_mask);
309 by Teddy Hogeborn
Merge from Björn:
1260
  ret = sigaddset(&sigterm_action.sa_mask, SIGINT);
1261
  if(ret == -1){
1262
    perror("sigaddset");
1263
    exitcode = EXIT_FAILURE;
1264
    goto end;
1265
  }
1266
  ret = sigaddset(&sigterm_action.sa_mask, SIGHUP);
1267
  if(ret == -1){
1268
    perror("sigaddset");
1269
    exitcode = EXIT_FAILURE;
1270
    goto end;
1271
  }
24.1.135 by Björn Påhlsson
Earlier signal handling
1272
  ret = sigaddset(&sigterm_action.sa_mask, SIGTERM);
1273
  if(ret == -1){
1274
    perror("sigaddset");
1275
    exitcode = EXIT_FAILURE;
1276
    goto end;
1277
  }
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1278
  /* Need to check if the handler is SIG_IGN before handling:
1279
     | [[info:libc:Initial Signal Actions]] |
1280
     | [[info:libc:Basic Signal Handling]]  |
1281
  */
1282
  ret = sigaction(SIGINT, NULL, &old_sigterm_action);
1283
  if(ret == -1){
1284
    perror("sigaction");
1285
    return EXIT_FAILURE;
1286
  }
1287
  if(old_sigterm_action.sa_handler != SIG_IGN){
1288
    ret = sigaction(SIGINT, &sigterm_action, NULL);
1289
    if(ret == -1){
1290
      perror("sigaction");
1291
      exitcode = EXIT_FAILURE;
1292
      goto end;
1293
    }
1294
  }
1295
  ret = sigaction(SIGHUP, NULL, &old_sigterm_action);
1296
  if(ret == -1){
1297
    perror("sigaction");
1298
    return EXIT_FAILURE;
1299
  }
1300
  if(old_sigterm_action.sa_handler != SIG_IGN){
1301
    ret = sigaction(SIGHUP, &sigterm_action, NULL);
1302
    if(ret == -1){
1303
      perror("sigaction");
1304
      exitcode = EXIT_FAILURE;
1305
      goto end;
1306
    }
1307
  }
1308
  ret = sigaction(SIGTERM, NULL, &old_sigterm_action);
1309
  if(ret == -1){
1310
    perror("sigaction");
1311
    return EXIT_FAILURE;
1312
  }
1313
  if(old_sigterm_action.sa_handler != SIG_IGN){
1314
    ret = sigaction(SIGTERM, &sigterm_action, NULL);
1315
    if(ret == -1){
1316
      perror("sigaction");
1317
      exitcode = EXIT_FAILURE;
1318
      goto end;
1319
    }
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1320
  }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1321
  
1322
  /* If the interface is down, bring it up */
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1323
  if(strcmp(interface, "none") != 0){
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1324
    if_index = (AvahiIfIndex) if_nametoindex(interface);
1325
    if(if_index == 0){
1326
      fprintf(stderr, "No such interface: \"%s\"\n", interface);
1327
      exitcode = EXIT_FAILURE;
1328
      goto end;
1329
    }
1330
    
1331
    if(quit_now){
1332
      goto end;
1333
    }
1334
    
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1335
    /* Re-raise priviliges */
1336
    errno = 0;
1337
    ret = seteuid(0);
1338
    if(ret == -1){
1339
      perror("seteuid");
1340
    }
1341
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1342
#ifdef __linux__
1343
    /* Lower kernel loglevel to KERN_NOTICE to avoid KERN_INFO
1344
       messages to mess up the prompt */
1345
    ret = klogctl(8, NULL, 5);
304 by Teddy Hogeborn
Four new interrelated features:
1346
    bool restore_loglevel = true;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1347
    if(ret == -1){
304 by Teddy Hogeborn
Four new interrelated features:
1348
      restore_loglevel = false;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1349
      perror("klogctl");
1350
    }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1351
#endif	/* __linux__ */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1352
    
1353
    sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1354
    if(sd < 0){
1355
      perror("socket");
1356
      exitcode = EXIT_FAILURE;
1357
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1358
      if(restore_loglevel){
1359
	ret = klogctl(7, NULL, 0);
1360
	if(ret == -1){
1361
	  perror("klogctl");
1362
	}
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1363
      }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1364
#endif	/* __linux__ */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1365
      /* Lower privileges */
1366
      errno = 0;
1367
      ret = seteuid(uid);
1368
      if(ret == -1){
1369
	perror("seteuid");
1370
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1371
      goto end;
1372
    }
1373
    strcpy(network.ifr_name, interface);
1374
    ret = ioctl(sd, SIOCGIFFLAGS, &network);
1375
    if(ret == -1){
1376
      perror("ioctl SIOCGIFFLAGS");
1377
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1378
      if(restore_loglevel){
1379
	ret = klogctl(7, NULL, 0);
1380
	if(ret == -1){
1381
	  perror("klogctl");
1382
	}
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1383
      }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1384
#endif	/* __linux__ */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1385
      exitcode = EXIT_FAILURE;
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1386
      /* Lower privileges */
1387
      errno = 0;
1388
      ret = seteuid(uid);
1389
      if(ret == -1){
1390
	perror("seteuid");
1391
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1392
      goto end;
1393
    }
1394
    if((network.ifr_flags & IFF_UP) == 0){
1395
      network.ifr_flags |= IFF_UP;
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1396
      take_down_interface = true;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1397
      ret = ioctl(sd, SIOCSIFFLAGS, &network);
1398
      if(ret == -1){
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1399
	take_down_interface = false;
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1400
	perror("ioctl SIOCSIFFLAGS +IFF_UP");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1401
	exitcode = EXIT_FAILURE;
1402
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1403
	if(restore_loglevel){
1404
	  ret = klogctl(7, NULL, 0);
1405
	  if(ret == -1){
1406
	    perror("klogctl");
1407
	  }
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
1408
	}
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1409
#endif	/* __linux__ */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1410
	/* Lower privileges */
1411
	errno = 0;
1412
	ret = seteuid(uid);
1413
	if(ret == -1){
1414
	  perror("seteuid");
1415
	}
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1416
	goto end;
1417
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1418
    }
1419
    /* sleep checking until interface is running */
1420
    for(int i=0; i < delay * 4; i++){
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1421
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
1422
      if(ret == -1){
1423
	perror("ioctl SIOCGIFFLAGS");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1424
      } else if(network.ifr_flags & IFF_RUNNING){
1425
	break;
1426
      }
1427
      struct timespec sleeptime = { .tv_nsec = 250000000 };
1428
      ret = nanosleep(&sleeptime, NULL);
1429
      if(ret == -1 and errno != EINTR){
1430
	perror("nanosleep");
1431
      }
1432
    }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1433
    if(not take_down_interface){
1434
      /* We won't need the socket anymore */
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1435
      ret = (int)TEMP_FAILURE_RETRY(close(sd));
1436
      if(ret == -1){
1437
	perror("close");
1438
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1439
    }
1440
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1441
    if(restore_loglevel){
1442
      /* Restores kernel loglevel to default */
1443
      ret = klogctl(7, NULL, 0);
1444
      if(ret == -1){
1445
	perror("klogctl");
1446
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1447
    }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1448
#endif	/* __linux__ */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1449
    /* Lower privileges */
1450
    errno = 0;
1451
    if(take_down_interface){
1452
      /* Lower privileges */
1453
      ret = seteuid(uid);
1454
      if(ret == -1){
1455
	perror("seteuid");
1456
      }
1457
    } else {
1458
      /* Lower privileges permanently */
1459
      ret = setuid(uid);
1460
      if(ret == -1){
1461
	perror("setuid");
1462
      }
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
1463
    }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1464
  }
1465
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1466
  if(quit_now){
1467
    goto end;
1468
  }
1469
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1470
  ret = init_gnutls_global(pubkey, seckey);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1471
  if(ret == -1){
1472
    fprintf(stderr, "init_gnutls_global failed\n");
1473
    exitcode = EXIT_FAILURE;
1474
    goto end;
1475
  } else {
1476
    gnutls_initialized = true;
1477
  }
1478
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1479
  if(quit_now){
1480
    goto end;
1481
  }
1482
  
1483
  tempdir_created = true;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1484
  if(mkdtemp(tempdir) == NULL){
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1485
    tempdir_created = false;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1486
    perror("mkdtemp");
1487
    goto end;
1488
  }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1489
  
1490
  if(quit_now){
1491
    goto end;
1492
  }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1493
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1494
  if(not init_gpgme(pubkey, seckey, tempdir)){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1495
    fprintf(stderr, "init_gpgme failed\n");
1496
    exitcode = EXIT_FAILURE;
1497
    goto end;
1498
  } else {
1499
    gpgme_initialized = true;
1500
  }
1501
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1502
  if(quit_now){
1503
    goto end;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1504
  }
1505
  
1506
  if(connect_to != NULL){
1507
    /* Connect directly, do not use Zeroconf */
1508
    /* (Mainly meant for debugging) */
1509
    char *address = strrchr(connect_to, ':');
1510
    if(address == NULL){
1511
      fprintf(stderr, "No colon in address\n");
1512
      exitcode = EXIT_FAILURE;
1513
      goto end;
1514
    }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1515
    
1516
    if(quit_now){
1517
      goto end;
1518
    }
1519
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1520
    uint16_t port;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1521
    errno = 0;
1522
    tmpmax = strtoimax(address+1, &tmp, 10);
1523
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
1524
       or tmpmax != (uint16_t)tmpmax){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1525
      fprintf(stderr, "Bad port number\n");
1526
      exitcode = EXIT_FAILURE;
1527
      goto end;
1528
    }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1529
  
1530
    if(quit_now){
1531
      goto end;
1532
    }
1533
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1534
    port = (uint16_t)tmpmax;
1535
    *address = '\0';
1536
    address = connect_to;
304 by Teddy Hogeborn
Four new interrelated features:
1537
    /* Colon in address indicates IPv6 */
1538
    int af;
1539
    if(strchr(address, ':') != NULL){
1540
      af = AF_INET6;
1541
    } else {
1542
      af = AF_INET;
1543
    }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1544
    
1545
    if(quit_now){
1546
      goto end;
1547
    }
1548
    
307 by Teddy Hogeborn
Merge from Björn:
1549
    ret = start_mandos_communication(address, port, if_index, af);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1550
    if(ret < 0){
1551
      exitcode = EXIT_FAILURE;
1552
    } else {
1553
      exitcode = EXIT_SUCCESS;
1554
    }
1555
    goto end;
1556
  }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1557
  
1558
  if(quit_now){
1559
    goto end;
1560
  }
1561
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1562
  {
1563
    AvahiServerConfig config;
1564
    /* Do not publish any local Zeroconf records */
1565
    avahi_server_config_init(&config);
1566
    config.publish_hinfo = 0;
1567
    config.publish_addresses = 0;
1568
    config.publish_workstation = 0;
1569
    config.publish_domain = 0;
1570
    
1571
    /* Allocate a new server */
1572
    mc.server = avahi_server_new(avahi_simple_poll_get
1573
				 (mc.simple_poll), &config, NULL,
1574
				 NULL, &error);
1575
    
1576
    /* Free the Avahi configuration data */
1577
    avahi_server_config_free(&config);
1578
  }
1579
  
1580
  /* Check if creating the Avahi server object succeeded */
1581
  if(mc.server == NULL){
1582
    fprintf(stderr, "Failed to create Avahi server: %s\n",
1583
	    avahi_strerror(error));
1584
    exitcode = EXIT_FAILURE;
1585
    goto end;
1586
  }
1587
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1588
  if(quit_now){
1589
    goto end;
1590
  }
1591
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1592
  /* Create the Avahi service browser */
1593
  sb = avahi_s_service_browser_new(mc.server, if_index,
313 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
1594
				   AVAHI_PROTO_UNSPEC, "_mandos._tcp",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1595
				   NULL, 0, browse_callback, NULL);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1596
  if(sb == NULL){
1597
    fprintf(stderr, "Failed to create service browser: %s\n",
1598
	    avahi_strerror(avahi_server_errno(mc.server)));
1599
    exitcode = EXIT_FAILURE;
1600
    goto end;
1601
  }
307 by Teddy Hogeborn
Merge from Björn:
1602
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1603
  if(quit_now){
1604
    goto end;
1605
  }
1606
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1607
  /* Run the main loop */
1608
  
1609
  if(debug){
1610
    fprintf(stderr, "Starting Avahi loop search\n");
1611
  }
1612
  
1613
  avahi_simple_poll_loop(mc.simple_poll);
1614
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1615
 end:
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1616
  
1617
  if(debug){
1618
    fprintf(stderr, "%s exiting\n", argv[0]);
1619
  }
1620
  
1621
  /* Cleanup things */
1622
  if(sb != NULL)
1623
    avahi_s_service_browser_free(sb);
1624
  
1625
  if(mc.server != NULL)
1626
    avahi_server_free(mc.server);
1627
  
1628
  if(mc.simple_poll != NULL)
1629
    avahi_simple_poll_free(mc.simple_poll);
1630
  
1631
  if(gnutls_initialized){
1632
    gnutls_certificate_free_credentials(mc.cred);
1633
    gnutls_global_deinit();
1634
    gnutls_dh_params_deinit(mc.dh_params);
1635
  }
1636
  
1637
  if(gpgme_initialized){
1638
    gpgme_release(mc.ctx);
1639
  }
1640
  
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1641
  /* Take down the network interface */
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1642
  if(take_down_interface){
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
1643
    /* Re-raise priviliges */
1644
    errno = 0;
1645
    ret = seteuid(0);
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1646
    if(ret == -1){
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
1647
      perror("seteuid");
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1648
    }
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
1649
    if(geteuid() == 0){
1650
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
1651
      if(ret == -1){
1652
	perror("ioctl SIOCGIFFLAGS");
1653
      } else if(network.ifr_flags & IFF_UP) {
1654
	network.ifr_flags &= ~IFF_UP; /* clear flag */
1655
	ret = ioctl(sd, SIOCSIFFLAGS, &network);
1656
	if(ret == -1){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1657
	  perror("ioctl SIOCSIFFLAGS -IFF_UP");
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
1658
	}
1659
      }
1660
      ret = (int)TEMP_FAILURE_RETRY(close(sd));
1661
      if(ret == -1){
1662
	perror("close");
1663
      }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1664
      /* Lower privileges permanently */
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
1665
      errno = 0;
1666
      ret = setuid(uid);
1667
      if(ret == -1){
1668
	perror("setuid");
1669
      }
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1670
    }
1671
  }
1672
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1673
  /* Removes the temp directory used by GPGME */
1674
  if(tempdir_created){
1675
    DIR *d;
1676
    struct dirent *direntry;
1677
    d = opendir(tempdir);
1678
    if(d == NULL){
1679
      if(errno != ENOENT){
1680
	perror("opendir");
1681
      }
1682
    } else {
1683
      while(true){
1684
	direntry = readdir(d);
1685
	if(direntry == NULL){
1686
	  break;
1687
	}
1688
	/* Skip "." and ".." */
1689
	if(direntry->d_name[0] == '.'
1690
	   and (direntry->d_name[1] == '\0'
1691
		or (direntry->d_name[1] == '.'
1692
		    and direntry->d_name[2] == '\0'))){
1693
	  continue;
1694
	}
1695
	char *fullname = NULL;
1696
	ret = asprintf(&fullname, "%s/%s", tempdir,
1697
		       direntry->d_name);
1698
	if(ret < 0){
1699
	  perror("asprintf");
1700
	  continue;
1701
	}
1702
	ret = remove(fullname);
1703
	if(ret == -1){
1704
	  fprintf(stderr, "remove(\"%s\"): %s\n", fullname,
1705
		  strerror(errno));
1706
	}
1707
	free(fullname);
1708
      }
1709
      closedir(d);
1710
    }
1711
    ret = rmdir(tempdir);
1712
    if(ret == -1 and errno != ENOENT){
1713
      perror("rmdir");
1714
    }
1715
  }
1716
  
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1717
  if(quit_now){
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1718
    sigemptyset(&old_sigterm_action.sa_mask);
1719
    old_sigterm_action.sa_handler = SIG_DFL;
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
1720
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
1721
					    &old_sigterm_action,
1722
					    NULL));
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1723
    if(ret == -1){
1724
      perror("sigaction");
1725
    }
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
1726
    do {
1727
      ret = raise(signal_received);
1728
    } while(ret != 0 and errno == EINTR);
1729
    if(ret != 0){
1730
      perror("raise");
1731
      abort();
1732
    }
1733
    TEMP_FAILURE_RETRY(pause());
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1734
  }
1735
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1736
  return exitcode;
13 by Björn Påhlsson
Added following support:
1737
}