/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
466 by Teddy Hogeborn
Update copyright year to "2011" wherever appropriate.
12
 * Copyright © 2008-2011 Teddy Hogeborn
13
 * Copyright © 2008-2011 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
 * 
505.1.2 by Teddy Hogeborn
Change "fukt.bsnet.se" to "recompile.se" throughout.
29
 * Contact the authors at <mandos@recompile.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 */
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
46
#include <stdlib.h> 		/* free(), EXIT_SUCCESS, srand(),
47
				   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() */
485 by Teddy Hogeborn
Merge from Björn.
65
#include <errno.h>		/* perror(), errno,
66
				   program_invocation_short_name */
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
67
#include <time.h>		/* nanosleep(), time(), sleep() */
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
68
#include <net/if.h>		/* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
24.1.26 by Björn Påhlsson
tally count of used symbols
69
				   SIOCSIFFLAGS, if_indextoname(),
70
				   if_nametoindex(), IF_NAMESIZE */
304 by Teddy Hogeborn
Four new interrelated features:
71
#include <netinet/in.h>		/* IN6_IS_ADDR_LINKLOCAL,
72
				   INET_ADDRSTRLEN, INET6_ADDRSTRLEN
73
				*/
24.1.29 by Björn Påhlsson
Added more header file comments
74
#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().
75
				   getuid(), getgid(), seteuid(),
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
76
				   setgid(), pause() */
484 by Teddy Hogeborn
* Makefile (plugins.d/mandos-client): Bug fix: Put $^ before all
77
#include <arpa/inet.h>		/* inet_pton(), htons, inet_ntop() */
304 by Teddy Hogeborn
Four new interrelated features:
78
#include <iso646.h>		/* not, or, and */
24.1.29 by Björn Påhlsson
Added more header file comments
79
#include <argp.h>		/* struct argp_option, error_t, struct
80
				   argp_state, struct argp,
81
				   argp_parse(), ARGP_KEY_ARG,
82
				   ARGP_KEY_END, ARGP_ERR_UNKNOWN */
307 by Teddy Hogeborn
Merge from Björn:
83
#include <signal.h>		/* sigemptyset(), sigaddset(),
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
84
				   sigaction(), SIGTERM, sig_atomic_t,
85
				   raise() */
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
86
#include <sysexits.h>		/* EX_OSERR, EX_USAGE, EX_UNAVAILABLE,
87
				   EX_NOHOST, EX_IOERR, EX_PROTOCOL */
307 by Teddy Hogeborn
Merge from Björn:
88
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
89
#ifdef __linux__
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
90
#include <sys/klog.h> 		/* klogctl() */
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
91
#endif	/* __linux__ */
24.1.26 by Björn Påhlsson
tally count of used symbols
92
93
/* Avahi */
24.1.29 by Björn Påhlsson
Added more header file comments
94
/* All Avahi types, constants and functions
95
 Avahi*, avahi_*,
96
 AVAHI_* */
97
#include <avahi-core/core.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
98
#include <avahi-core/lookup.h>
24.1.29 by Björn Påhlsson
Added more header file comments
99
#include <avahi-core/log.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
100
#include <avahi-common/simple-watch.h>
101
#include <avahi-common/malloc.h>
102
#include <avahi-common/error.h>
103
104
/* GnuTLS */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
105
#include <gnutls/gnutls.h>	/* All GnuTLS types, constants and
106
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
107
				   gnutls_*
24.1.26 by Björn Påhlsson
tally count of used symbols
108
				   init_gnutls_session(),
24.1.29 by Björn Påhlsson
Added more header file comments
109
				   GNUTLS_* */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
110
#include <gnutls/openpgp.h>
111
			  /* gnutls_certificate_set_openpgp_key_file(),
24.1.29 by Björn Påhlsson
Added more header file comments
112
				   GNUTLS_OPENPGP_FMT_BASE64 */
24.1.26 by Björn Påhlsson
tally count of used symbols
113
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
114
/* GPGME */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
115
#include <gpgme.h> 		/* All GPGME types, constants and
116
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
117
				   gpgme_*
24.1.26 by Björn Påhlsson
tally count of used symbols
118
				   GPGME_PROTOCOL_OpenPGP,
24.1.29 by Björn Påhlsson
Added more header file comments
119
				   GPG_ERR_NO_* */
13 by Björn Påhlsson
Added following support:
120
121
#define BUFFER_SIZE 256
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
122
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
123
#define PATHDIR "/conf/conf.d/mandos"
124
#define SECKEY "seckey.txt"
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
125
#define PUBKEY "pubkey.txt"
505.2.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
126
#define HOOKDIR "/lib/mandos/network-hooks.d"
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
127
15.1.2 by Björn Påhlsson
Added debug options from passprompt as --debug and --debug=passprompt
128
bool debug = false;
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
129
static const char mandos_protocol_version[] = "1";
217 by Teddy Hogeborn
* .bzrignore: Added "man" directory (created by "make install-html").
130
const char *argp_program_version = "mandos-client " VERSION;
505.1.2 by Teddy Hogeborn
Change "fukt.bsnet.se" to "recompile.se" throughout.
131
const char *argp_program_bug_address = "<mandos@recompile.se>";
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
132
static const char sys_class_net[] = "/sys/class/net";
133
char *connect_to = NULL;
24.1.10 by Björn Påhlsson
merge commit
134
485 by Teddy Hogeborn
Merge from Björn.
135
/* Doubly linked list that need to be circularly linked when used */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
136
typedef struct server{
137
  const char *ip;
138
  uint16_t port;
139
  AvahiIfIndex if_index;
140
  int af;
141
  struct timespec last_seen;
142
  struct server *next;
143
  struct server *prev;
144
} server;
145
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
146
/* Used for passing in values through the Avahi callback functions */
13 by Björn Påhlsson
Added following support:
147
typedef struct {
24.1.9 by Björn Påhlsson
not working midwork...
148
  AvahiSimplePoll *simple_poll;
149
  AvahiServer *server;
13 by Björn Påhlsson
Added following support:
150
  gnutls_certificate_credentials_t cred;
24.1.9 by Björn Påhlsson
not working midwork...
151
  unsigned int dh_bits;
24.1.13 by Björn Påhlsson
mandosclient
152
  gnutls_dh_params_t dh_params;
24.1.9 by Björn Påhlsson
not working midwork...
153
  const char *priority;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
154
  gpgme_ctx_t ctx;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
155
  server *current_server;
24.1.9 by Björn Påhlsson
not working midwork...
156
} mandos_context;
13 by Björn Påhlsson
Added following support:
157
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
158
/* global context so signal handler can reach it*/
24.1.135 by Björn Påhlsson
Earlier signal handling
159
mandos_context mc = { .simple_poll = NULL, .server = NULL,
160
		      .dh_bits = 1024, .priority = "SECURE256"
485 by Teddy Hogeborn
Merge from Björn.
161
		      ":!CTYPE-X.509:+CTYPE-OPENPGP",
162
		      .current_server = NULL };
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
163
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
164
sig_atomic_t quit_now = 0;
165
int signal_received = 0;
166
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
167
/* Function to use when printing errors */
168
void perror_plus(const char *print_text){
485 by Teddy Hogeborn
Merge from Björn.
169
  fprintf(stderr, "Mandos plugin %s: ",
170
	  program_invocation_short_name);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
171
  perror(print_text);
172
}
173
505.2.4 by Björn Påhlsson
New convinence error printer: fprintf_plus
174
int fprintf_plus(FILE *stream, const char *format, ...){
175
  va_list ap;
176
  va_start (ap, format);
177
  
178
  TEMP_FAILURE_RETRY(fprintf(stream, "Mandos plugin %s: ", program_invocation_short_name));
179
  return TEMP_FAILURE_RETRY(vfprintf(stream, format, ap));
180
}
181
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
182
/*
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
183
 * Make additional room in "buffer" for at least BUFFER_SIZE more
184
 * bytes. "buffer_capacity" is how much is currently allocated,
185
 * "buffer_length" is how much is already used.
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
186
 */
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
187
size_t incbuffer(char **buffer, size_t buffer_length,
24.1.10 by Björn Påhlsson
merge commit
188
		  size_t buffer_capacity){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
189
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
24.1.12 by Björn Påhlsson
merge +
190
    *buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
191
    if(buffer == NULL){
24.1.10 by Björn Påhlsson
merge commit
192
      return 0;
193
    }
194
    buffer_capacity += BUFFER_SIZE;
195
  }
196
  return buffer_capacity;
197
}
198
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
199
/* Add server to set of servers to retry periodically */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
200
int add_server(const char *ip, uint16_t port,
201
		 AvahiIfIndex if_index,
202
		 int af){
203
  int ret;
204
  server *new_server = malloc(sizeof(server));
205
  if(new_server == NULL){
206
    perror_plus("malloc");
207
    return -1;
208
  }
209
  *new_server = (server){ .ip = strdup(ip),
210
			 .port = port,
211
			 .if_index = if_index,
212
			 .af = af };
213
  if(new_server->ip == NULL){
214
    perror_plus("strdup");
485 by Teddy Hogeborn
Merge from Björn.
215
    return -1;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
216
  }
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
217
  /* Special case of first server */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
218
  if (mc.current_server == NULL){
219
    new_server->next = new_server;
220
    new_server->prev = new_server;
221
    mc.current_server = new_server;
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
222
  /* Place the new server last in the list */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
223
  } else {
224
    new_server->next = mc.current_server;
225
    new_server->prev = mc.current_server->prev;
226
    new_server->prev->next = new_server;
227
    mc.current_server->prev = new_server;
228
  }
229
  ret = clock_gettime(CLOCK_MONOTONIC, &mc.current_server->last_seen);
230
  if(ret == -1){
231
    perror_plus("clock_gettime");
232
    return -1;
233
  }
234
  return 0;
235
}
236
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
237
/* 
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
238
 * Initialize GPGME.
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
239
 */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
240
static bool init_gpgme(const char *seckey,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
241
		       const char *pubkey, const char *tempdir){
13 by Björn Påhlsson
Added following support:
242
  gpgme_error_t rc;
243
  gpgme_engine_info_t engine_info;
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
  
246
  /*
288 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Use separate bool variable instead
247
   * 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.
248
   */
249
  bool import_key(const char *filename){
361 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
250
    int ret;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
251
    int fd;
252
    gpgme_data_t pgp_data;
253
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
254
    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.
255
    if(fd == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
256
      perror_plus("open");
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
257
      return false;
258
    }
259
    
260
    rc = gpgme_data_new_from_fd(&pgp_data, fd);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
261
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
262
      fprintf(stderr, "bad gpgme_data_new_from_fd: %s: %s\n",
263
	      gpgme_strsource(rc), gpgme_strerror(rc));
264
      return false;
265
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
266
    
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
267
    rc = gpgme_op_import(mc.ctx, pgp_data);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
268
    if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
269
      fprintf(stderr, "bad gpgme_op_import: %s: %s\n",
270
	      gpgme_strsource(rc), gpgme_strerror(rc));
271
      return false;
272
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
273
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
274
    ret = (int)TEMP_FAILURE_RETRY(close(fd));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
275
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
276
      perror_plus("close");
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
277
    }
278
    gpgme_data_release(pgp_data);
279
    return true;
280
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
281
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
282
  if(debug){
307 by Teddy Hogeborn
Merge from Björn:
283
    fprintf(stderr, "Initializing GPGME\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
284
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
285
  
13 by Björn Påhlsson
Added following support:
286
  /* Init GPGME */
287
  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.
288
  rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
289
  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.
290
    fprintf(stderr, "bad gpgme_engine_check_version: %s: %s\n",
291
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
292
    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.
293
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
294
  
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
295
  /* Set GPGME home directory for the OpenPGP engine only */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
296
  rc = gpgme_get_engine_info(&engine_info);
297
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
298
    fprintf(stderr, "bad gpgme_get_engine_info: %s: %s\n",
299
	    gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
300
    return false;
13 by Björn Påhlsson
Added following support:
301
  }
302
  while(engine_info != NULL){
303
    if(engine_info->protocol == GPGME_PROTOCOL_OpenPGP){
304
      gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
305
			    engine_info->file_name, tempdir);
13 by Björn Påhlsson
Added following support:
306
      break;
307
    }
308
    engine_info = engine_info->next;
309
  }
310
  if(engine_info == NULL){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
311
    fprintf(stderr, "Could not set GPGME home dir to %s\n", tempdir);
312
    return false;
313
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
314
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
315
  /* Create new GPGME "context" */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
316
  rc = gpgme_new(&(mc.ctx));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
317
  if(rc != GPG_ERR_NO_ERROR){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
318
    fprintf(stderr, "bad gpgme_new: %s: %s\n",
319
	    gpgme_strsource(rc), gpgme_strerror(rc));
320
    return false;
321
  }
322
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
323
  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.
324
    return false;
325
  }
326
  
355 by Teddy Hogeborn
* mandos: White-space fixes only.
327
  return true;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
328
}
329
330
/* 
331
 * Decrypt OpenPGP data.
332
 * Returns -1 on error
333
 */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
334
static ssize_t pgp_packet_decrypt(const char *cryptotext,
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
335
				  size_t crypto_size,
336
				  char **plaintext){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
337
  gpgme_data_t dh_crypto, dh_plain;
338
  gpgme_error_t rc;
339
  ssize_t ret;
340
  size_t plaintext_capacity = 0;
341
  ssize_t plaintext_length = 0;
342
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
343
  if(debug){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
344
    fprintf(stderr, "Trying to decrypt OpenPGP data\n");
13 by Björn Påhlsson
Added following support:
345
  }
346
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
347
  /* Create new GPGME data buffer from memory cryptotext */
348
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
349
			       0);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
350
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
351
    fprintf(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
352
	    gpgme_strsource(rc), gpgme_strerror(rc));
353
    return -1;
354
  }
355
  
356
  /* Create new empty GPGME data buffer for the plaintext */
357
  rc = gpgme_data_new(&dh_plain);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
358
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
359
    fprintf(stderr, "bad gpgme_data_new: %s: %s\n",
360
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
361
    gpgme_data_release(dh_crypto);
13 by Björn Påhlsson
Added following support:
362
    return -1;
363
  }
364
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
365
  /* Decrypt data from the cryptotext data buffer to the plaintext
366
     data buffer */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
367
  rc = gpgme_op_decrypt(mc.ctx, dh_crypto, dh_plain);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
368
  if(rc != GPG_ERR_NO_ERROR){
13 by Björn Påhlsson
Added following support:
369
    fprintf(stderr, "bad gpgme_op_decrypt: %s: %s\n",
370
	    gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
371
    plaintext_length = -1;
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
372
    if(debug){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
373
      gpgme_decrypt_result_t result;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
374
      result = gpgme_op_decrypt_result(mc.ctx);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
375
      if(result == NULL){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
376
	fprintf(stderr, "gpgme_op_decrypt_result failed\n");
377
      } else {
378
	fprintf(stderr, "Unsupported algorithm: %s\n",
379
		result->unsupported_algorithm);
380
	fprintf(stderr, "Wrong key usage: %u\n",
381
		result->wrong_key_usage);
382
	if(result->file_name != NULL){
383
	  fprintf(stderr, "File name: %s\n", result->file_name);
384
	}
385
	gpgme_recipient_t recipient;
386
	recipient = result->recipients;
349 by Teddy Hogeborn
* plugins.d/mandos-client.c (pgp_packet_decrypt): Remove redundant
387
	while(recipient != NULL){
388
	  fprintf(stderr, "Public key algorithm: %s\n",
389
		  gpgme_pubkey_algo_name(recipient->pubkey_algo));
390
	  fprintf(stderr, "Key ID: %s\n", recipient->keyid);
391
	  fprintf(stderr, "Secret key available: %s\n",
392
		  recipient->status == GPG_ERR_NO_SECKEY
393
		  ? "No" : "Yes");
394
	  recipient = recipient->next;
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
395
	}
396
      }
397
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
398
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
399
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
400
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
401
  if(debug){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
402
    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
403
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
404
  
13 by Björn Påhlsson
Added following support:
405
  /* Seek back to the beginning of the GPGME plaintext data buffer */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
406
  if(gpgme_data_seek(dh_plain, (off_t)0, SEEK_SET) == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
407
    perror_plus("gpgme_data_seek");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
408
    plaintext_length = -1;
409
    goto decrypt_end;
24.1.5 by Björn Påhlsson
plugbasedclient:
410
  }
411
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
412
  *plaintext = NULL;
13 by Björn Påhlsson
Added following support:
413
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
414
    plaintext_capacity = incbuffer(plaintext,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
415
				      (size_t)plaintext_length,
24.1.12 by Björn Påhlsson
merge +
416
				      plaintext_capacity);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
417
    if(plaintext_capacity == 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
418
	perror_plus("incbuffer");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
419
	plaintext_length = -1;
420
	goto decrypt_end;
13 by Björn Påhlsson
Added following support:
421
    }
422
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
423
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
424
			  BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
425
    /* Print the data, if any */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
426
    if(ret == 0){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
427
      /* EOF */
13 by Björn Påhlsson
Added following support:
428
      break;
429
    }
430
    if(ret < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
431
      perror_plus("gpgme_data_read");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
432
      plaintext_length = -1;
433
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
434
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
435
    plaintext_length += ret;
13 by Björn Påhlsson
Added following support:
436
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
437
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
438
  if(debug){
439
    fprintf(stderr, "Decrypted password is: ");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
440
    for(ssize_t i = 0; i < plaintext_length; i++){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
441
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
442
    }
443
    fprintf(stderr, "\n");
444
  }
445
  
446
 decrypt_end:
447
  
448
  /* Delete the GPGME cryptotext data buffer */
449
  gpgme_data_release(dh_crypto);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
450
  
451
  /* Delete the GPGME plaintext data buffer */
13 by Björn Påhlsson
Added following support:
452
  gpgme_data_release(dh_plain);
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
453
  return plaintext_length;
13 by Björn Påhlsson
Added following support:
454
}
455
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
456
static const char * safer_gnutls_strerror(int value){
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
457
  const char *ret = gnutls_strerror(value); /* Spurious warning from
458
					       -Wunreachable-code */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
459
  if(ret == NULL)
13 by Björn Påhlsson
Added following support:
460
    ret = "(unknown)";
461
  return ret;
462
}
463
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
464
/* GnuTLS log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
465
static void debuggnutls(__attribute__((unused)) int level,
466
			const char* string){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
467
  fprintf(stderr, "GnuTLS: %s", string);
13 by Björn Påhlsson
Added following support:
468
}
469
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
470
static int init_gnutls_global(const char *pubkeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
471
			      const char *seckeyfilename){
13 by Björn Påhlsson
Added following support:
472
  int ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
473
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
474
  if(debug){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
475
    fprintf(stderr, "Initializing GnuTLS\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
476
  }
24.1.29 by Björn Påhlsson
Added more header file comments
477
  
478
  ret = gnutls_global_init();
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
479
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
480
    fprintf(stderr, "GnuTLS global_init: %s\n",
481
	    safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
482
    return -1;
483
  }
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
484
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
485
  if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
486
    /* "Use a log level over 10 to enable all debugging options."
487
     * - GnuTLS manual
488
     */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
489
    gnutls_global_set_log_level(11);
490
    gnutls_global_set_log_function(debuggnutls);
491
  }
492
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
493
  /* OpenPGP credentials */
484 by Teddy Hogeborn
* Makefile (plugins.d/mandos-client): Bug fix: Put $^ before all
494
  ret = gnutls_certificate_allocate_credentials(&mc.cred);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
495
  if(ret != GNUTLS_E_SUCCESS){
484 by Teddy Hogeborn
* Makefile (plugins.d/mandos-client): Bug fix: Put $^ before all
496
    fprintf(stderr, "GnuTLS memory error: %s\n",
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
497
	    safer_gnutls_strerror(ret));
498
    gnutls_global_deinit();
13 by Björn Påhlsson
Added following support:
499
    return -1;
500
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
501
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
502
  if(debug){
147 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Improved wording
503
    fprintf(stderr, "Attempting to use OpenPGP public key %s and"
504
	    " secret key %s as GnuTLS credentials\n", pubkeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
505
	    seckeyfilename);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
506
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
507
  
13 by Björn Påhlsson
Added following support:
508
  ret = gnutls_certificate_set_openpgp_key_file
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
509
    (mc.cred, pubkeyfilename, seckeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
510
     GNUTLS_OPENPGP_FMT_BASE64);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
511
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
512
    fprintf(stderr,
513
	    "Error[%d] while reading the OpenPGP key pair ('%s',"
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
514
	    " '%s')\n", ret, pubkeyfilename, seckeyfilename);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
515
    fprintf(stderr, "The GnuTLS error is: %s\n",
13 by Björn Påhlsson
Added following support:
516
	    safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
517
    goto globalfail;
13 by Björn Påhlsson
Added following support:
518
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
519
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
520
  /* GnuTLS server initialization */
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
521
  ret = gnutls_dh_params_init(&mc.dh_params);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
522
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
523
    fprintf(stderr, "Error in GnuTLS DH parameter initialization:"
524
	    " %s\n", safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
525
    goto globalfail;
13 by Björn Påhlsson
Added following support:
526
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
527
  ret = gnutls_dh_params_generate2(mc.dh_params, mc.dh_bits);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
528
  if(ret != GNUTLS_E_SUCCESS){
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
529
    fprintf(stderr, "Error in GnuTLS prime generation: %s\n",
530
	    safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
531
    goto globalfail;
13 by Björn Påhlsson
Added following support:
532
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
533
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
534
  gnutls_certificate_set_dh_params(mc.cred, mc.dh_params);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
535
  
24.1.13 by Björn Påhlsson
mandosclient
536
  return 0;
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
537
  
24.1.20 by Björn Påhlsson
mandosclient
538
 globalfail:
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
539
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
540
  gnutls_certificate_free_credentials(mc.cred);
24.1.26 by Björn Påhlsson
tally count of used symbols
541
  gnutls_global_deinit();
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
542
  gnutls_dh_params_deinit(mc.dh_params);
24.1.20 by Björn Påhlsson
mandosclient
543
  return -1;
24.1.13 by Björn Påhlsson
mandosclient
544
}
545
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
546
static int init_gnutls_session(gnutls_session_t *session){
24.1.13 by Björn Påhlsson
mandosclient
547
  int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
548
  /* GnuTLS session creation */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
549
  do {
550
    ret = gnutls_init(session, GNUTLS_SERVER);
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
551
    if(quit_now){
552
      return -1;
553
    }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
554
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
555
  if(ret != GNUTLS_E_SUCCESS){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
556
    fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
13 by Björn Påhlsson
Added following support:
557
	    safer_gnutls_strerror(ret));
558
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
559
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
560
  {
561
    const char *err;
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
562
    do {
563
      ret = gnutls_priority_set_direct(*session, mc.priority, &err);
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
564
      if(quit_now){
565
	gnutls_deinit(*session);
566
	return -1;
567
      }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
568
    } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
569
    if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
570
      fprintf(stderr, "Syntax error at: %s\n", err);
571
      fprintf(stderr, "GnuTLS error: %s\n",
572
	      safer_gnutls_strerror(ret));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
573
      gnutls_deinit(*session);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
574
      return -1;
575
    }
13 by Björn Påhlsson
Added following support:
576
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
577
  
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
578
  do {
579
    ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
580
				 mc.cred);
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
581
    if(quit_now){
582
      gnutls_deinit(*session);
583
      return -1;
584
    }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
585
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
586
  if(ret != GNUTLS_E_SUCCESS){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
587
    fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
13 by Björn Påhlsson
Added following support:
588
	    safer_gnutls_strerror(ret));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
589
    gnutls_deinit(*session);
13 by Björn Påhlsson
Added following support:
590
    return -1;
591
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
592
  
13 by Björn Påhlsson
Added following support:
593
  /* ignore client certificate if any. */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
594
  gnutls_certificate_server_set_request(*session, GNUTLS_CERT_IGNORE);
13 by Björn Påhlsson
Added following support:
595
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
596
  gnutls_dh_set_prime_bits(*session, mc.dh_bits);
13 by Björn Påhlsson
Added following support:
597
  
598
  return 0;
599
}
600
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
601
/* Avahi log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
602
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
603
		      __attribute__((unused)) const char *txt){}
13 by Björn Påhlsson
Added following support:
604
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
605
/* Called when a Mandos server is found */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
606
static int start_mandos_communication(const char *ip, uint16_t port,
24.1.9 by Björn Påhlsson
not working midwork...
607
				      AvahiIfIndex if_index,
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
608
				      int af){
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
609
  int ret, tcp_sd = -1;
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
610
  ssize_t sret;
304 by Teddy Hogeborn
Four new interrelated features:
611
  union {
612
    struct sockaddr_in in;
613
    struct sockaddr_in6 in6;
614
  } to;
13 by Björn Påhlsson
Added following support:
615
  char *buffer = NULL;
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
616
  char *decrypted_buffer = NULL;
13 by Björn Påhlsson
Added following support:
617
  size_t buffer_length = 0;
618
  size_t buffer_capacity = 0;
24.1.10 by Björn Påhlsson
merge commit
619
  size_t written;
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
620
  int retval = -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
621
  gnutls_session_t session;
304 by Teddy Hogeborn
Four new interrelated features:
622
  int pf;			/* Protocol family */
623
  
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
624
  errno = 0;
625
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
626
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
627
    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
628
    return -1;
629
  }
630
  
304 by Teddy Hogeborn
Four new interrelated features:
631
  switch(af){
632
  case AF_INET6:
633
    pf = PF_INET6;
634
    break;
635
  case AF_INET:
636
    pf = PF_INET;
637
    break;
638
  default:
639
    fprintf(stderr, "Bad address family: %d\n", af);
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
640
    errno = EINVAL;
304 by Teddy Hogeborn
Four new interrelated features:
641
    return -1;
642
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
643
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
644
  ret = init_gnutls_session(&session);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
645
  if(ret != 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
646
    return -1;
647
  }
648
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
649
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
650
    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.
651
	    "\n", ip, port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
652
  }
13 by Björn Påhlsson
Added following support:
653
  
304 by Teddy Hogeborn
Four new interrelated features:
654
  tcp_sd = socket(pf, SOCK_STREAM, 0);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
655
  if(tcp_sd < 0){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
656
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
657
    perror_plus("socket");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
658
    errno = e;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
659
    goto mandos_end;
660
  }
661
  
662
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
663
    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
664
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
665
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
666
  
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
667
  memset(&to, 0, sizeof(to));
304 by Teddy Hogeborn
Four new interrelated features:
668
  if(af == AF_INET6){
325 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): "sin6_family"
669
    to.in6.sin6_family = (sa_family_t)af;
304 by Teddy Hogeborn
Four new interrelated features:
670
    ret = inet_pton(af, ip, &to.in6.sin6_addr);
671
  } else {			/* IPv4 */
672
    to.in.sin_family = (sa_family_t)af;
673
    ret = inet_pton(af, ip, &to.in.sin_addr);
674
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
675
  if(ret < 0 ){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
676
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
677
    perror_plus("inet_pton");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
678
    errno = e;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
679
    goto mandos_end;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
680
  }
13 by Björn Påhlsson
Added following support:
681
  if(ret == 0){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
682
    int e = errno;
13 by Björn Påhlsson
Added following support:
683
    fprintf(stderr, "Bad address: %s\n", ip);
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
684
    errno = e;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
685
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
686
  }
304 by Teddy Hogeborn
Four new interrelated features:
687
  if(af == AF_INET6){
688
    to.in6.sin6_port = htons(port); /* Spurious warnings from
689
				       -Wconversion and
690
				       -Wunreachable-code */
691
    
692
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
693
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
694
			      -Wunreachable-code*/
695
      if(if_index == AVAHI_IF_UNSPEC){
696
	fprintf(stderr, "An IPv6 link-local address is incomplete"
697
		" without a network interface\n");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
698
	errno = EINVAL;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
699
	goto mandos_end;
304 by Teddy Hogeborn
Four new interrelated features:
700
      }
701
      /* Set the network interface number as scope */
702
      to.in6.sin6_scope_id = (uint32_t)if_index;
703
    }
704
  } else {
705
    to.in.sin_port = htons(port); /* Spurious warnings from
267 by Teddy Hogeborn
* plugins.d/mandos-client.c: Only comment changes.
706
				     -Wconversion and
707
				     -Wunreachable-code */
304 by Teddy Hogeborn
Four new interrelated features:
708
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
709
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
710
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
711
    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
712
    goto mandos_end;
713
  }
714
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
715
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
716
    if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){
717
      char interface[IF_NAMESIZE];
718
      if(if_indextoname((unsigned int)if_index, interface) == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
719
	perror_plus("if_indextoname");
304 by Teddy Hogeborn
Four new interrelated features:
720
      } else {
721
	fprintf(stderr, "Connection to: %s%%%s, port %" PRIu16 "\n",
722
		ip, interface, port);
723
      }
724
    } else {
725
      fprintf(stderr, "Connection to: %s, port %" PRIu16 "\n", ip,
726
	      port);
727
    }
728
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
729
		 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
730
    const char *pcret;
731
    if(af == AF_INET6){
732
      pcret = inet_ntop(af, &(to.in6.sin6_addr), addrstr,
733
			sizeof(addrstr));
734
    } else {
735
      pcret = inet_ntop(af, &(to.in.sin_addr), addrstr,
736
			sizeof(addrstr));
737
    }
738
    if(pcret == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
739
      perror_plus("inet_ntop");
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
740
    } else {
741
      if(strcmp(addrstr, ip) != 0){
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
742
	fprintf(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
743
      }
744
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
745
  }
13 by Björn Påhlsson
Added following support:
746
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
747
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
748
    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
749
    goto mandos_end;
750
  }
751
  
304 by Teddy Hogeborn
Four new interrelated features:
752
  if(af == AF_INET6){
753
    ret = connect(tcp_sd, &to.in6, sizeof(to));
754
  } else {
755
    ret = connect(tcp_sd, &to.in, sizeof(to)); /* IPv4 */
756
  }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
757
  if(ret < 0){
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
758
    if ((errno != ECONNREFUSED and errno != ENETUNREACH) or debug){
759
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
760
      perror_plus("connect");
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
761
      errno = e;
762
    }
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
763
    goto mandos_end;
764
  }
765
  
766
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
767
    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
768
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
769
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
770
  
24.1.12 by Björn Påhlsson
merge +
771
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
772
  written = 0;
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
773
  while(true){
24.1.10 by Björn Påhlsson
merge commit
774
    size_t out_size = strlen(out);
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
775
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
24.1.10 by Björn Påhlsson
merge commit
776
				   out_size - written));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
777
    if(ret == -1){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
778
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
779
      perror_plus("write");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
780
      errno = e;
24.1.12 by Björn Påhlsson
merge +
781
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
782
    }
24.1.12 by Björn Påhlsson
merge +
783
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
784
    if(written < out_size){
785
      continue;
786
    } else {
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
787
      if(out == mandos_protocol_version){
24.1.10 by Björn Påhlsson
merge commit
788
	written = 0;
789
	out = "\r\n";
790
      } else {
791
	break;
792
      }
793
    }
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
794
  
795
    if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
796
      errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
797
      goto mandos_end;
798
    }
24.1.10 by Björn Påhlsson
merge commit
799
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
800
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
801
  if(debug){
802
    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
803
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
804
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
805
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
806
    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
807
    goto mandos_end;
808
  }
809
  
485 by Teddy Hogeborn
Merge from Björn.
810
  /* Spurious warning from -Wint-to-pointer-cast */
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
811
  gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t) tcp_sd);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
812
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
813
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
814
    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
815
    goto mandos_end;
816
  }
817
  
363 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
818
  do {
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
819
    ret = gnutls_handshake(session);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
820
    if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
821
      errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
822
      goto mandos_end;
823
    }
24.1.29 by Björn Påhlsson
Added more header file comments
824
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
13 by Björn Påhlsson
Added following support:
825
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
826
  if(ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
827
    if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
828
      fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
829
      gnutls_perror(ret);
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
830
    }
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
831
    errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
832
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
833
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
834
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
835
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
836
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
837
  if(debug){
304 by Teddy Hogeborn
Four new interrelated features:
838
    fprintf(stderr, "Retrieving OpenPGP encrypted password from %s\n",
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
839
	    ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
840
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
841
  
13 by Björn Påhlsson
Added following support:
842
  while(true){
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
843
    
844
    if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
845
      errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
846
      goto mandos_end;
847
    }
848
    
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
849
    buffer_capacity = incbuffer(&buffer, buffer_length,
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
850
				   buffer_capacity);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
851
    if(buffer_capacity == 0){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
852
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
853
      perror_plus("incbuffer");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
854
      errno = e;
24.1.12 by Björn Påhlsson
merge +
855
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
856
    }
857
    
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
858
    if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
859
      errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
860
      goto mandos_end;
861
    }
862
    
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
863
    sret = gnutls_record_recv(session, buffer+buffer_length,
864
			      BUFFER_SIZE);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
865
    if(sret == 0){
13 by Björn Påhlsson
Added following support:
866
      break;
867
    }
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
868
    if(sret < 0){
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
869
      switch(sret){
13 by Björn Påhlsson
Added following support:
870
      case GNUTLS_E_INTERRUPTED:
871
      case GNUTLS_E_AGAIN:
872
	break;
873
      case GNUTLS_E_REHANDSHAKE:
363 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
874
	do {
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
875
	  ret = gnutls_handshake(session);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
876
	  
877
	  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
878
	    errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
879
	    goto mandos_end;
880
	  }
24.1.29 by Björn Påhlsson
Added more header file comments
881
	} while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
882
	if(ret < 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
883
	  fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
884
	  gnutls_perror(ret);
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
885
	  errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
886
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
887
	}
888
	break;
889
      default:
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
890
	fprintf(stderr, "Unknown error while reading data from"
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
891
		" encrypted session with Mandos server\n");
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
892
	gnutls_bye(session, GNUTLS_SHUT_RDWR);
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
893
	errno = EIO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
894
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
895
      }
896
    } else {
257.1.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
897
      buffer_length += (size_t) sret;
13 by Björn Påhlsson
Added following support:
898
    }
899
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
900
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
901
  if(debug){
902
    fprintf(stderr, "Closing TLS session\n");
903
  }
904
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
905
  if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
906
    errno = EINTR;
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
907
    goto mandos_end;
908
  }
909
  
910
  do {
911
    ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
912
    if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
913
      errno = EINTR;
371 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
914
      goto mandos_end;
915
    }
916
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
917
  
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
918
  if(buffer_length > 0){
362 by Teddy Hogeborn
* plugin-runner.c (getplugin, add_environment, main): Handle EINTR
919
    ssize_t decrypted_buffer_size;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
920
    decrypted_buffer_size = pgp_packet_decrypt(buffer,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
921
					       buffer_length,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
922
					       &decrypted_buffer);
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
923
    if(decrypted_buffer_size >= 0){
361 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
924
      
24.1.10 by Björn Påhlsson
merge commit
925
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
926
      while(written < (size_t) decrypted_buffer_size){
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
927
	if(quit_now){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
928
	  errno = EINTR;
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
929
	  goto mandos_end;
930
	}
931
	
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
932
	ret = (int)fwrite(decrypted_buffer + written, 1,
933
			  (size_t)decrypted_buffer_size - written,
934
			  stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
935
	if(ret == 0 and ferror(stdout)){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
936
	  int e = errno;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
937
	  if(debug){
938
	    fprintf(stderr, "Error writing encrypted data: %s\n",
939
		    strerror(errno));
940
	  }
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
941
	  errno = e;
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
942
	  goto mandos_end;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
943
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
944
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
945
      }
372 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
946
      retval = 0;
13 by Björn Påhlsson
Added following support:
947
    }
948
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
949
  
950
  /* Shutdown procedure */
951
  
952
 mandos_end:
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
953
  {
954
    int e = errno;
955
    free(decrypted_buffer);
956
    free(buffer);
957
    if(tcp_sd >= 0){
958
      ret = (int)TEMP_FAILURE_RETRY(close(tcp_sd));
959
    }
960
    if(ret == -1){
961
      if(e == 0){
962
	e = errno;
963
      }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
964
      perror_plus("close");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
965
    }
966
    gnutls_deinit(session);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
967
    errno = e;
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
968
    if(quit_now){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
969
      errno = EINTR;
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
970
      retval = -1;
971
    }
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
972
  }
13 by Björn Påhlsson
Added following support:
973
  return retval;
974
}
975
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
976
static void resolve_callback(AvahiSServiceResolver *r,
977
			     AvahiIfIndex interface,
304 by Teddy Hogeborn
Four new interrelated features:
978
			     AvahiProtocol proto,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
979
			     AvahiResolverEvent event,
980
			     const char *name,
981
			     const char *type,
982
			     const char *domain,
983
			     const char *host_name,
984
			     const AvahiAddress *address,
985
			     uint16_t port,
986
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
987
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
988
			     flags,
307 by Teddy Hogeborn
Merge from Björn:
989
			     AVAHI_GCC_UNUSED void* userdata){
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
990
  assert(r);
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
991
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
992
  /* Called whenever a service has been resolved successfully or
993
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
994
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
995
  if(quit_now){
996
    return;
997
  }
998
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
999
  switch(event){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1000
  default:
1001
  case AVAHI_RESOLVER_FAILURE:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1002
    fprintf(stderr, "(Avahi Resolver) Failed to resolve service '%s'"
1003
	    " 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
1004
	    avahi_strerror(avahi_server_errno(mc.server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1005
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1006
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1007
  case AVAHI_RESOLVER_FOUND:
1008
    {
1009
      char ip[AVAHI_ADDRESS_STR_MAX];
1010
      avahi_address_snprint(ip, sizeof(ip), address);
1011
      if(debug){
60 by Teddy Hogeborn
* mandos-client.c (main): Cast pid_t to unsigned int before printing.
1012
	fprintf(stderr, "Mandos server \"%s\" found on %s (%s, %"
268 by Teddy Hogeborn
Fixes for sscanf usage:
1013
		PRIdMAX ") on port %" PRIu16 "\n", name, host_name,
1014
		ip, (intmax_t)interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1015
      }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1016
      int ret = start_mandos_communication(ip, port, interface,
304 by Teddy Hogeborn
Four new interrelated features:
1017
					   avahi_proto_to_af(proto));
266 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1018
      if(ret == 0){
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1019
	avahi_simple_poll_quit(mc.simple_poll);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1020
      } else {
1021
	ret = add_server(ip, port, interface,
1022
			 avahi_proto_to_af(proto));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1023
      }
13 by Björn Påhlsson
Added following support:
1024
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1025
  }
1026
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
1027
}
1028
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1029
static void browse_callback(AvahiSServiceBrowser *b,
1030
			    AvahiIfIndex interface,
1031
			    AvahiProtocol protocol,
1032
			    AvahiBrowserEvent event,
1033
			    const char *name,
1034
			    const char *type,
1035
			    const char *domain,
1036
			    AVAHI_GCC_UNUSED AvahiLookupResultFlags
1037
			    flags,
307 by Teddy Hogeborn
Merge from Björn:
1038
			    AVAHI_GCC_UNUSED void* userdata){
84 by Teddy Hogeborn
* Makefile (DOCBOOKTOMAN): Use the local manpages/docbook.xsl file, do
1039
  assert(b);
24.1.9 by Björn Påhlsson
not working midwork...
1040
  
1041
  /* Called whenever a new services becomes available on the LAN or
1042
     is removed from the LAN */
1043
  
358 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1044
  if(quit_now){
1045
    return;
1046
  }
1047
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1048
  switch(event){
24.1.9 by Björn Påhlsson
not working midwork...
1049
  default:
1050
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1051
    
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1052
    fprintf(stderr, "(Avahi browser) %s\n",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1053
	    avahi_strerror(avahi_server_errno(mc.server)));
1054
    avahi_simple_poll_quit(mc.simple_poll);
24.1.9 by Björn Påhlsson
not working midwork...
1055
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1056
    
24.1.9 by Björn Påhlsson
not working midwork...
1057
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1058
    /* We ignore the returned Avahi resolver object. In the callback
1059
       function we free it. If the Avahi server is terminated before
1060
       the callback function is called the Avahi server will free the
1061
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1062
    
313 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
1063
    if(avahi_s_service_resolver_new(mc.server, interface, protocol,
1064
				    name, type, domain, protocol, 0,
1065
				    resolve_callback, NULL) == NULL)
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1066
      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
1067
	      name, avahi_strerror(avahi_server_errno(mc.server)));
24.1.9 by Björn Påhlsson
not working midwork...
1068
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1069
    
24.1.9 by Björn Påhlsson
not working midwork...
1070
  case AVAHI_BROWSER_REMOVE:
1071
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1072
    
24.1.9 by Björn Påhlsson
not working midwork...
1073
  case AVAHI_BROWSER_ALL_FOR_NOW:
1074
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1075
    if(debug){
1076
      fprintf(stderr, "No Mandos server found, still searching...\n");
1077
    }
24.1.9 by Björn Påhlsson
not working midwork...
1078
    break;
1079
  }
13 by Björn Påhlsson
Added following support:
1080
}
1081
485 by Teddy Hogeborn
Merge from Björn.
1082
/* Signal handler that stops main loop after SIGTERM */
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1083
static void handle_sigterm(int sig){
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1084
  if(quit_now){
1085
    return;
1086
  }
1087
  quit_now = 1;
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1088
  signal_received = sig;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1089
  int old_errno = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1090
  /* set main loop to exit */
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1091
  if(mc.simple_poll != NULL){
1092
    avahi_simple_poll_quit(mc.simple_poll);
1093
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1094
  errno = old_errno;
1095
}
1096
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1097
bool get_flags(const char *ifname, struct ifreq *ifr){
505.2.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1098
  int ret;
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1099
  
505.2.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1100
  int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1101
  if(s < 0){
1102
    perror_plus("socket");
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1103
    return false;
505.2.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1104
  }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1105
  strcpy(ifr->ifr_name, ifname);
1106
  ret = ioctl(s, SIOCGIFFLAGS, ifr);
505.2.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1107
  if(ret == -1){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1108
    if(debug){
505.2.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1109
      perror_plus("ioctl SIOCGIFFLAGS");
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1110
    }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1111
    return false;
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1112
  }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1113
  return true;
1114
}
1115
1116
bool good_flags(const char *ifname, const struct ifreq *ifr){
1117
  
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1118
  /* Reject the loopback device */
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1119
  if(ifr->ifr_flags & IFF_LOOPBACK){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1120
    if(debug){
1121
      fprintf(stderr, "Rejecting loopback interface \"%s\"\n",
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1122
	      ifname);
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1123
    }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1124
    return false;
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1125
  }
1126
  /* Accept point-to-point devices only if connect_to is specified */
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1127
  if(connect_to != NULL and (ifr->ifr_flags & IFF_POINTOPOINT)){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1128
    if(debug){
1129
      fprintf(stderr, "Accepting point-to-point interface \"%s\"\n",
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1130
	      ifname);
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1131
    }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1132
    return true;
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1133
  }
1134
  /* Otherwise, reject non-broadcast-capable devices */
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1135
  if(not (ifr->ifr_flags & IFF_BROADCAST)){
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1136
    if(debug){
1137
      fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n",
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1138
	      ifname);
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1139
    }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1140
    return false;
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1141
  }
481 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1142
  /* Reject non-ARP interfaces (including dummy interfaces) */
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1143
  if(ifr->ifr_flags & IFF_NOARP){
481 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1144
    if(debug){
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1145
      fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n", ifname);
481 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1146
    }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1147
    return false;
481 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1148
  }
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1149
  
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1150
  /* Accept this device */
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1151
  if(debug){
505.2.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1152
    fprintf(stderr, "Interface \"%s\" is good\n", ifname);
1153
  }
1154
  return true;
1155
}
1156
1157
/* 
1158
 * This function determines if a directory entry in /sys/class/net
1159
 * corresponds to an acceptable network device.
1160
 * (This function is passed to scandir(3) as a filter function.)
1161
 */
1162
int good_interface(const struct dirent *if_entry){
1163
  int ret;
1164
  if(if_entry->d_name[0] == '.'){
1165
    return 0;
1166
  }
1167
  struct ifreq ifr;
1168
1169
  if(not get_flags(if_entry->d_name, &ifr)){
1170
    return 0;
1171
  }
1172
  
1173
  if(not good_flags(if_entry->d_name, &ifr)){
1174
    return 0;
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1175
  }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1176
  return 1;
1177
}
1178
505.2.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1179
/* 
1180
 * This function determines if a directory entry in /sys/class/net
1181
 * corresponds to an acceptable network device which is up.
1182
 * (This function is passed to scandir(3) as a filter function.)
1183
 */
1184
int up_interface(const struct dirent *if_entry){
1185
  ssize_t ssret;
1186
  char *flagname = NULL;
1187
  if(if_entry->d_name[0] == '.'){
1188
    return 0;
1189
  }
1190
  int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net,
1191
		     if_entry->d_name);
1192
  if(ret < 0){
1193
    perror_plus("asprintf");
1194
    return 0;
1195
  }
1196
  int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY));
1197
  if(flags_fd == -1){
1198
    perror_plus("open");
1199
    free(flagname);
1200
    return 0;
1201
  }
1202
  free(flagname);
1203
  typedef short ifreq_flags;	/* ifreq.ifr_flags in netdevice(7) */
1204
  /* read line from flags_fd */
1205
  ssize_t to_read = 2+(sizeof(ifreq_flags)*2)+1; /* "0x1003\n" */
1206
  char *flagstring = malloc((size_t)to_read+1); /* +1 for final \0 */
1207
  flagstring[(size_t)to_read] = '\0';
1208
  if(flagstring == NULL){
1209
    perror_plus("malloc");
1210
    close(flags_fd);
1211
    return 0;
1212
  }
1213
  while(to_read > 0){
1214
    ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring,
1215
					     (size_t)to_read));
1216
    if(ssret == -1){
1217
      perror_plus("read");
1218
      free(flagstring);
1219
      close(flags_fd);
1220
      return 0;
1221
    }
1222
    to_read -= ssret;
1223
    if(ssret == 0){
1224
      break;
1225
    }
1226
  }
1227
  close(flags_fd);
1228
  intmax_t tmpmax;
1229
  char *tmp;
1230
  errno = 0;
1231
  tmpmax = strtoimax(flagstring, &tmp, 0);
1232
  if(errno != 0 or tmp == flagstring or (*tmp != '\0'
1233
					 and not (isspace(*tmp)))
1234
     or tmpmax != (ifreq_flags)tmpmax){
1235
    if(debug){
1236
      fprintf(stderr, "Invalid flags \"%s\" for interface \"%s\"\n",
1237
	      flagstring, if_entry->d_name);
1238
    }
1239
    free(flagstring);
1240
    return 0;
1241
  }
1242
  free(flagstring);
1243
  ifreq_flags flags = (ifreq_flags)tmpmax;
1244
  /* Reject the loopback device */
1245
  if(flags & IFF_LOOPBACK){
1246
    if(debug){
1247
      fprintf(stderr, "Rejecting loopback interface \"%s\"\n",
1248
	      if_entry->d_name);
1249
    }
1250
    return 0;
1251
  }
1252
1253
  /* Reject down interfaces */
1254
  if(not (flags & IFF_UP)){
1255
    return 0;
1256
  }
1257
  
1258
  /* Accept point-to-point devices only if connect_to is specified */
1259
  if(connect_to != NULL and (flags & IFF_POINTOPOINT)){
1260
    if(debug){
1261
      fprintf(stderr, "Accepting point-to-point interface \"%s\"\n",
1262
	      if_entry->d_name);
1263
    }
1264
    return 1;
1265
  }
1266
  /* Otherwise, reject non-broadcast-capable devices */
1267
  if(not (flags & IFF_BROADCAST)){
1268
    if(debug){
1269
      fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n",
1270
	      if_entry->d_name);
1271
    }
1272
    return 0;
1273
  }
1274
  /* Reject non-ARP interfaces (including dummy interfaces) */
1275
  if(flags & IFF_NOARP){
1276
    if(debug){
1277
      fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n",
1278
	      if_entry->d_name);
1279
    }
1280
    return 0;
1281
  }
1282
  /* Accept this device */
1283
  if(debug){
1284
    fprintf(stderr, "Interface \"%s\" is acceptable\n",
1285
	    if_entry->d_name);
1286
  }
1287
  return 1;
1288
}
1289
24.1.172 by Björn Påhlsson
using scandir instead of readdir
1290
int notdotentries(const struct dirent *direntry){
1291
  /* Skip "." and ".." */
1292
  if(direntry->d_name[0] == '.'
1293
     and (direntry->d_name[1] == '\0'
1294
	  or (direntry->d_name[1] == '.'
1295
	      and direntry->d_name[2] == '\0'))){
1296
    return 0;
1297
  }
1298
  return 1;
1299
}
1300
505.2.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1301
/* Is this directory entry a runnable program? */
1302
int runnable_hook(const struct dirent *direntry){
1303
  int ret;
1304
  struct stat st;
1305
  
1306
  if((direntry->d_name)[0] == '\0'){
1307
    /* Empty name? */
1308
    return 0;
1309
  }
1310
  
1311
  /* Save pointer to last character */
1312
  char *end = strchr(direntry->d_name, '\0')-1;
1313
  
1314
  if(*end == '~'){
1315
    /* Backup name~ */
1316
    return 0;
1317
  }
1318
  
1319
  if(((direntry->d_name)[0] == '#')
1320
     and (*end == '#')){
1321
    /* Temporary #name# */
1322
    return 0;
1323
  }
1324
  
1325
  /* XXX more rules here */
1326
  
1327
  ret = stat(direntry->d_name, &st);
1328
  if(ret == -1){
1329
    if(debug){
1330
      perror_plus("Could not stat plugin");
1331
    }
1332
    return 0;
1333
  }
1334
  if(not (st.st_mode & S_ISREG)){
1335
    /* Not a regular file */
1336
    return 0;
1337
  }
1338
  if(not (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))){
1339
    /* Not executable */
1340
    return 0;
1341
  }
1342
  return 1;
1343
}
1344
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1345
int avahi_loop_with_timeout(AvahiSimplePoll *s, int retry_interval){
1346
  int ret;
1347
  struct timespec now;
1348
  struct timespec waited_time;
1349
  intmax_t block_time;
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1350
  
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1351
  while(true){
1352
    if(mc.current_server == NULL){
1353
      if (debug){
485 by Teddy Hogeborn
Merge from Björn.
1354
	fprintf(stderr,
1355
		"Wait until first server is found. No timeout!\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1356
      }
1357
      ret = avahi_simple_poll_iterate(s, -1);
1358
    } else {
1359
      if (debug){
485 by Teddy Hogeborn
Merge from Björn.
1360
	fprintf(stderr, "Check current_server if we should run it,"
1361
		" or wait\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1362
      }
1363
      /* the current time */
1364
      ret = clock_gettime(CLOCK_MONOTONIC, &now);
1365
      if(ret == -1){
1366
	perror_plus("clock_gettime");
1367
	return -1;
1368
      }
1369
      /* Calculating in ms how long time between now and server
1370
	 who we visted longest time ago. Now - last seen.  */
485 by Teddy Hogeborn
Merge from Björn.
1371
      waited_time.tv_sec = (now.tv_sec
1372
			    - mc.current_server->last_seen.tv_sec);
1373
      waited_time.tv_nsec = (now.tv_nsec
1374
			     - mc.current_server->last_seen.tv_nsec);
1375
      /* total time is 10s/10,000ms.
1376
	 Converting to s from ms by dividing by 1,000,
1377
	 and ns to ms by dividing by 1,000,000. */
1378
      block_time = ((retry_interval
1379
		     - ((intmax_t)waited_time.tv_sec * 1000))
1380
		    - ((intmax_t)waited_time.tv_nsec / 1000000));
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1381
      
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1382
      if (debug){
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1383
	fprintf(stderr, "Blocking for %" PRIdMAX " ms\n", block_time);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1384
      }
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1385
      
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1386
      if(block_time <= 0){
1387
	ret = start_mandos_communication(mc.current_server->ip,
485 by Teddy Hogeborn
Merge from Björn.
1388
					 mc.current_server->port,
1389
					 mc.current_server->if_index,
1390
					 mc.current_server->af);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1391
	if(ret == 0){
1392
	  avahi_simple_poll_quit(mc.simple_poll);
1393
	  return 0;
1394
	}
485 by Teddy Hogeborn
Merge from Björn.
1395
	ret = clock_gettime(CLOCK_MONOTONIC,
1396
			    &mc.current_server->last_seen);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1397
	if(ret == -1){
1398
	  perror_plus("clock_gettime");
1399
	  return -1;
1400
	}
1401
	mc.current_server = mc.current_server->next;
485 by Teddy Hogeborn
Merge from Björn.
1402
	block_time = 0; 	/* Call avahi to find new Mandos
1403
				   servers, but don't block */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1404
      }
1405
      
1406
      ret = avahi_simple_poll_iterate(s, (int)block_time);
1407
    }
1408
    if(ret != 0){
1409
      if (ret > 0 or errno != EINTR) {
1410
	return (ret != 1) ? ret : 0;
1411
      }
1412
    }
1413
  }
1414
}
1415
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1416
int main(int argc, char *argv[]){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1417
  AvahiSServiceBrowser *sb = NULL;
1418
  int error;
1419
  int ret;
1420
  intmax_t tmpmax;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1421
  char *tmp;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1422
  int exitcode = EXIT_SUCCESS;
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1423
  const char *interface = "";
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1424
  struct ifreq network;
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1425
  int sd = -1;
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1426
  bool take_down_interface = false;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1427
  uid_t uid;
1428
  gid_t gid;
1429
  char tempdir[] = "/tmp/mandosXXXXXX";
1430
  bool tempdir_created = false;
1431
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
1432
  const char *seckey = PATHDIR "/" SECKEY;
1433
  const char *pubkey = PATHDIR "/" PUBKEY;
1434
  
1435
  bool gnutls_initialized = false;
1436
  bool gpgme_initialized = false;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1437
  float delay = 2.5f;
485 by Teddy Hogeborn
Merge from Björn.
1438
  double retry_interval = 10; /* 10s between trying a server and
1439
				 retrying the same server again */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1440
  
369 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
1441
  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
1442
  struct sigaction sigterm_action = { .sa_handler = handle_sigterm };
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1443
  
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1444
  uid = getuid();
1445
  gid = getgid();
1446
  
1447
  /* Lower any group privileges we might have, just to be safe */
1448
  errno = 0;
1449
  ret = setgid(gid);
1450
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1451
    perror_plus("setgid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1452
  }
1453
  
1454
  /* Lower user privileges (temporarily) */
1455
  errno = 0;
1456
  ret = seteuid(uid);
1457
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1458
    perror_plus("seteuid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1459
  }
1460
  
1461
  if(quit_now){
1462
    goto end;
1463
  }
1464
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1465
  {
1466
    struct argp_option options[] = {
1467
      { .name = "debug", .key = 128,
1468
	.doc = "Debug mode", .group = 3 },
1469
      { .name = "connect", .key = 'c',
1470
	.arg = "ADDRESS:PORT",
1471
	.doc = "Connect directly to a specific Mandos server",
1472
	.group = 1 },
1473
      { .name = "interface", .key = 'i',
1474
	.arg = "NAME",
304 by Teddy Hogeborn
Four new interrelated features:
1475
	.doc = "Network interface that will be used to search for"
1476
	" Mandos servers",
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1477
	.group = 1 },
1478
      { .name = "seckey", .key = 's',
1479
	.arg = "FILE",
1480
	.doc = "OpenPGP secret key file base name",
1481
	.group = 1 },
1482
      { .name = "pubkey", .key = 'p',
1483
	.arg = "FILE",
1484
	.doc = "OpenPGP public key file base name",
1485
	.group = 2 },
1486
      { .name = "dh-bits", .key = 129,
1487
	.arg = "BITS",
1488
	.doc = "Bit length of the prime number used in the"
1489
	" Diffie-Hellman key exchange",
1490
	.group = 2 },
1491
      { .name = "priority", .key = 130,
1492
	.arg = "STRING",
1493
	.doc = "GnuTLS priority string for the TLS handshake",
1494
	.group = 1 },
1495
      { .name = "delay", .key = 131,
1496
	.arg = "SECONDS",
1497
	.doc = "Maximum delay to wait for interface startup",
1498
	.group = 2 },
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1499
      { .name = "retry", .key = 132,
1500
	.arg = "SECONDS",
1501
	.doc = "Retry interval used when denied by the mandos server",
1502
	.group = 2 },
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1503
      /*
1504
       * These reproduce what we would get without ARGP_NO_HELP
1505
       */
1506
      { .name = "help", .key = '?',
1507
	.doc = "Give this help list", .group = -1 },
1508
      { .name = "usage", .key = -3,
1509
	.doc = "Give a short usage message", .group = -1 },
1510
      { .name = "version", .key = 'V',
1511
	.doc = "Print program version", .group = -1 },
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1512
      { .name = NULL }
1513
    };
1514
    
1515
    error_t parse_opt(int key, char *arg,
1516
		      struct argp_state *state){
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1517
      errno = 0;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1518
      switch(key){
1519
      case 128:			/* --debug */
1520
	debug = true;
1521
	break;
1522
      case 'c':			/* --connect */
1523
	connect_to = arg;
1524
	break;
1525
      case 'i':			/* --interface */
1526
	interface = arg;
1527
	break;
1528
      case 's':			/* --seckey */
1529
	seckey = arg;
1530
	break;
1531
      case 'p':			/* --pubkey */
1532
	pubkey = arg;
1533
	break;
1534
      case 129:			/* --dh-bits */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1535
	errno = 0;
1536
	tmpmax = strtoimax(arg, &tmp, 10);
1537
	if(errno != 0 or tmp == arg or *tmp != '\0'
1538
	   or tmpmax != (typeof(mc.dh_bits))tmpmax){
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1539
	  argp_error(state, "Bad number of DH bits");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1540
	}
1541
	mc.dh_bits = (typeof(mc.dh_bits))tmpmax;
1542
	break;
1543
      case 130:			/* --priority */
1544
	mc.priority = arg;
1545
	break;
1546
      case 131:			/* --delay */
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
1547
	errno = 0;
1548
	delay = strtof(arg, &tmp);
1549
	if(errno != 0 or tmp == arg or *tmp != '\0'){
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1550
	  argp_error(state, "Bad delay");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1551
	}
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1552
      case 132:			/* --retry */
1553
	errno = 0;
1554
	retry_interval = strtod(arg, &tmp);
1555
	if(errno != 0 or tmp == arg or *tmp != '\0'
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1556
	   or (retry_interval * 1000) > INT_MAX
1557
	   or retry_interval < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1558
	  argp_error(state, "Bad retry interval");
1559
	}
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1560
	break;
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1561
	/*
1562
	 * These reproduce what we would get without ARGP_NO_HELP
1563
	 */
1564
      case '?':			/* --help */
1565
	argp_state_help(state, state->out_stream,
1566
			(ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
1567
			& ~(unsigned int)ARGP_HELP_EXIT_OK);
1568
      case -3:			/* --usage */
1569
	argp_state_help(state, state->out_stream,
1570
			ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
1571
      case 'V':			/* --version */
1572
	fprintf(state->out_stream, "%s\n", argp_program_version);
1573
	exit(argp_err_exit_status);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1574
	break;
1575
      default:
1576
	return ARGP_ERR_UNKNOWN;
1577
      }
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1578
      return errno;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1579
    }
1580
    
1581
    struct argp argp = { .options = options, .parser = parse_opt,
1582
			 .args_doc = "",
1583
			 .doc = "Mandos client -- Get and decrypt"
1584
			 " passwords from a Mandos server" };
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1585
    ret = argp_parse(&argp, argc, argv,
1586
		     ARGP_IN_ORDER | ARGP_NO_HELP, 0, NULL);
1587
    switch(ret){
1588
    case 0:
1589
      break;
1590
    case ENOMEM:
1591
    default:
1592
      errno = ret;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1593
      perror_plus("argp_parse");
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1594
      exitcode = EX_OSERR;
1595
      goto end;
1596
    case EINVAL:
1597
      exitcode = EX_USAGE;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1598
      goto end;
1599
    }
1600
  }
487 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
1601
    
1602
  {
1603
    /* Work around Debian bug #633582:
1604
       <http://bugs.debian.org/633582> */
1605
    struct stat st;
1606
    
1607
    /* Re-raise priviliges */
1608
    errno = 0;
1609
    ret = seteuid(0);
1610
    if(ret == -1){
1611
      perror_plus("seteuid");
1612
    }
1613
    
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
1614
    if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
1615
      int seckey_fd = open(seckey, O_RDONLY);
1616
      if(seckey_fd == -1){
1617
	perror_plus("open");
487 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
1618
      } else {
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
1619
	ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
1620
	if(ret == -1){
1621
	  perror_plus("fstat");
1622
	} else {
1623
	  if(S_ISREG(st.st_mode) and st.st_uid == 0 and st.st_gid == 0){
1624
	    ret = fchown(seckey_fd, uid, gid);
1625
	    if(ret == -1){
1626
	      perror_plus("fchown");
1627
	    }
487 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
1628
	  }
1629
	}
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
1630
	TEMP_FAILURE_RETRY(close(seckey_fd));
487 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
1631
      }
1632
    }
1633
    
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
1634
    if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
1635
      int pubkey_fd = open(pubkey, O_RDONLY);
1636
      if(pubkey_fd == -1){
1637
	perror_plus("open");
487 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
1638
      } else {
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
1639
	ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
1640
	if(ret == -1){
1641
	  perror_plus("fstat");
1642
	} else {
1643
	  if(S_ISREG(st.st_mode) and st.st_uid == 0 and st.st_gid == 0){
1644
	    ret = fchown(pubkey_fd, uid, gid);
1645
	    if(ret == -1){
1646
	      perror_plus("fchown");
1647
	    }
487 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
1648
	  }
1649
	}
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
1650
	TEMP_FAILURE_RETRY(close(pubkey_fd));
487 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
1651
      }
1652
    }
1653
    
1654
    /* Lower privileges */
1655
    errno = 0;
1656
    ret = seteuid(uid);
1657
    if(ret == -1){
1658
      perror_plus("seteuid");
1659
    }
1660
  }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1661
  
505.2.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1662
  /* Find network hooks and run them */
1663
  {
1664
    struct dirent **direntries;
1665
    struct dirent *direntry;
1666
    int numhooks = scandir(HOOKDIR, &direntries, runnable_hook,
1667
			   alphasort);
1668
    int devnull = open("/dev/null", O_RDONLY);
1669
    for(int i = 0; i < numhooks; i++){
1670
      direntry = direntries[0];
1671
      char *fullname = NULL;
1672
      ret = asprintf(&fullname, "%s/%s", tempdir,
1673
		     direntry->d_name);
1674
      if(ret < 0){
1675
	perror_plus("asprintf");
1676
	continue;
1677
      }
1678
      pid_t hook_pid = fork();
1679
      if(hook_pid == 0){
1680
	/* Child */
1681
	dup2(devnull, STDIN_FILENO);
1682
	close(devnull);
1683
	dup2(STDERR_FILENO, STDOUT_FILENO);
1684
	setenv("DEVICE", interface, 1);
1685
	setenv("VERBOSE", debug ? "1" : "0", 1);
1686
	setenv("MODE", "start", 1);
1687
	/* setenv( XXX more here */
1688
	ret = execl(fullname, direntry->d_name, "start");
1689
	perror_plus("execl");
1690
      }
1691
      free(fullname);
1692
      if(quit_now){
1693
	goto end;
1694
      }
1695
    }
1696
    close(devnull);
1697
  }
1698
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1699
  if(not debug){
1700
    avahi_set_log_function(empty_log);
1701
  }
505.2.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1702
  
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1703
  if(interface[0] == '\0'){
1704
    struct dirent **direntries;
1705
    ret = scandir(sys_class_net, &direntries, good_interface,
1706
		  alphasort);
1707
    if(ret >= 1){
1708
      /* Pick the first good interface */
1709
      interface = strdup(direntries[0]->d_name);
237.2.34 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1710
      if(debug){
1711
	fprintf(stderr, "Using interface \"%s\"\n", interface);
1712
      }
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1713
      if(interface == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1714
	perror_plus("malloc");
237.2.33 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1715
	free(direntries);
1716
	exitcode = EXIT_FAILURE;
1717
	goto end;
1718
      }
1719
      free(direntries);
1720
    } else {
1721
      free(direntries);
1722
      fprintf(stderr, "Could not find a network interface\n");
1723
      exitcode = EXIT_FAILURE;
1724
      goto end;
1725
    }
1726
  }
309 by Teddy Hogeborn
Merge from Björn:
1727
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1728
  /* Initialize Avahi early so avahi_simple_poll_quit() can be called
1729
     from the signal handler */
1730
  /* Initialize the pseudo-RNG for Avahi */
1731
  srand((unsigned int) time(NULL));
1732
  mc.simple_poll = avahi_simple_poll_new();
1733
  if(mc.simple_poll == NULL){
1734
    fprintf(stderr, "Avahi: Failed to create simple poll object.\n");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1735
    exitcode = EX_UNAVAILABLE;
24.1.135 by Björn Påhlsson
Earlier signal handling
1736
    goto end;
1737
  }
309 by Teddy Hogeborn
Merge from Björn:
1738
  
24.1.135 by Björn Påhlsson
Earlier signal handling
1739
  sigemptyset(&sigterm_action.sa_mask);
309 by Teddy Hogeborn
Merge from Björn:
1740
  ret = sigaddset(&sigterm_action.sa_mask, SIGINT);
1741
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1742
    perror_plus("sigaddset");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1743
    exitcode = EX_OSERR;
309 by Teddy Hogeborn
Merge from Björn:
1744
    goto end;
1745
  }
1746
  ret = sigaddset(&sigterm_action.sa_mask, SIGHUP);
1747
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1748
    perror_plus("sigaddset");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1749
    exitcode = EX_OSERR;
309 by Teddy Hogeborn
Merge from Björn:
1750
    goto end;
1751
  }
24.1.135 by Björn Påhlsson
Earlier signal handling
1752
  ret = sigaddset(&sigterm_action.sa_mask, SIGTERM);
1753
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1754
    perror_plus("sigaddset");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1755
    exitcode = EX_OSERR;
24.1.135 by Björn Påhlsson
Earlier signal handling
1756
    goto end;
1757
  }
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1758
  /* Need to check if the handler is SIG_IGN before handling:
1759
     | [[info:libc:Initial Signal Actions]] |
1760
     | [[info:libc:Basic Signal Handling]]  |
1761
  */
1762
  ret = sigaction(SIGINT, NULL, &old_sigterm_action);
1763
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1764
    perror_plus("sigaction");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1765
    return EX_OSERR;
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1766
  }
1767
  if(old_sigterm_action.sa_handler != SIG_IGN){
1768
    ret = sigaction(SIGINT, &sigterm_action, NULL);
1769
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1770
      perror_plus("sigaction");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1771
      exitcode = EX_OSERR;
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1772
      goto end;
1773
    }
1774
  }
1775
  ret = sigaction(SIGHUP, NULL, &old_sigterm_action);
1776
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1777
    perror_plus("sigaction");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1778
    return EX_OSERR;
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1779
  }
1780
  if(old_sigterm_action.sa_handler != SIG_IGN){
1781
    ret = sigaction(SIGHUP, &sigterm_action, NULL);
1782
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1783
      perror_plus("sigaction");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1784
      exitcode = EX_OSERR;
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1785
      goto end;
1786
    }
1787
  }
1788
  ret = sigaction(SIGTERM, NULL, &old_sigterm_action);
1789
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1790
    perror_plus("sigaction");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1791
    return EX_OSERR;
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1792
  }
1793
  if(old_sigterm_action.sa_handler != SIG_IGN){
1794
    ret = sigaction(SIGTERM, &sigterm_action, NULL);
1795
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1796
      perror_plus("sigaction");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1797
      exitcode = EX_OSERR;
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
1798
      goto end;
1799
    }
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1800
  }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1801
  
1802
  /* 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
1803
  if(strcmp(interface, "none") != 0){
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1804
    if_index = (AvahiIfIndex) if_nametoindex(interface);
1805
    if(if_index == 0){
1806
      fprintf(stderr, "No such interface: \"%s\"\n", interface);
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1807
      exitcode = EX_UNAVAILABLE;
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1808
      goto end;
1809
    }
1810
    
1811
    if(quit_now){
1812
      goto end;
1813
    }
1814
    
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1815
    /* Re-raise priviliges */
1816
    errno = 0;
1817
    ret = seteuid(0);
1818
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1819
      perror_plus("seteuid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1820
    }
1821
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1822
#ifdef __linux__
1823
    /* Lower kernel loglevel to KERN_NOTICE to avoid KERN_INFO
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
1824
       messages about the network interface to mess up the prompt */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1825
    ret = klogctl(8, NULL, 5);
304 by Teddy Hogeborn
Four new interrelated features:
1826
    bool restore_loglevel = true;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1827
    if(ret == -1){
304 by Teddy Hogeborn
Four new interrelated features:
1828
      restore_loglevel = false;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1829
      perror_plus("klogctl");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1830
    }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1831
#endif	/* __linux__ */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1832
    
1833
    sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1834
    if(sd < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1835
      perror_plus("socket");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1836
      exitcode = EX_OSERR;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1837
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1838
      if(restore_loglevel){
1839
	ret = klogctl(7, NULL, 0);
1840
	if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1841
	  perror_plus("klogctl");
304 by Teddy Hogeborn
Four new interrelated features:
1842
	}
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1843
      }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1844
#endif	/* __linux__ */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1845
      /* Lower privileges */
1846
      errno = 0;
1847
      ret = seteuid(uid);
1848
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1849
	perror_plus("seteuid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1850
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1851
      goto end;
1852
    }
1853
    strcpy(network.ifr_name, interface);
1854
    ret = ioctl(sd, SIOCGIFFLAGS, &network);
1855
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1856
      perror_plus("ioctl SIOCGIFFLAGS");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1857
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1858
      if(restore_loglevel){
1859
	ret = klogctl(7, NULL, 0);
1860
	if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1861
	  perror_plus("klogctl");
304 by Teddy Hogeborn
Four new interrelated features:
1862
	}
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1863
      }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1864
#endif	/* __linux__ */
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1865
      exitcode = EX_OSERR;
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1866
      /* Lower privileges */
1867
      errno = 0;
1868
      ret = seteuid(uid);
1869
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1870
	perror_plus("seteuid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1871
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1872
      goto end;
1873
    }
1874
    if((network.ifr_flags & IFF_UP) == 0){
1875
      network.ifr_flags |= IFF_UP;
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1876
      take_down_interface = true;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1877
      ret = ioctl(sd, SIOCSIFFLAGS, &network);
1878
      if(ret == -1){
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1879
	take_down_interface = false;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1880
	perror_plus("ioctl SIOCSIFFLAGS +IFF_UP");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1881
	exitcode = EX_OSERR;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1882
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1883
	if(restore_loglevel){
1884
	  ret = klogctl(7, NULL, 0);
1885
	  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1886
	    perror_plus("klogctl");
304 by Teddy Hogeborn
Four new interrelated features:
1887
	  }
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
1888
	}
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1889
#endif	/* __linux__ */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1890
	/* Lower privileges */
1891
	errno = 0;
1892
	ret = seteuid(uid);
1893
	if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1894
	  perror_plus("seteuid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1895
	}
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1896
	goto end;
1897
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1898
    }
485 by Teddy Hogeborn
Merge from Björn.
1899
    /* Sleep checking until interface is running.
1900
       Check every 0.25s, up to total time of delay */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1901
    for(int i=0; i < delay * 4; i++){
65 by Teddy Hogeborn
* plugins.d/password-request.c (main): Bug fix: Bring up network
1902
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
1903
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1904
	perror_plus("ioctl SIOCGIFFLAGS");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1905
      } else if(network.ifr_flags & IFF_RUNNING){
1906
	break;
1907
      }
1908
      struct timespec sleeptime = { .tv_nsec = 250000000 };
1909
      ret = nanosleep(&sleeptime, NULL);
1910
      if(ret == -1 and errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1911
	perror_plus("nanosleep");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1912
      }
1913
    }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1914
    if(not take_down_interface){
1915
      /* We won't need the socket anymore */
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1916
      ret = (int)TEMP_FAILURE_RETRY(close(sd));
1917
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1918
	perror_plus("close");
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
1919
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1920
    }
1921
#ifdef __linux__
304 by Teddy Hogeborn
Four new interrelated features:
1922
    if(restore_loglevel){
1923
      /* Restores kernel loglevel to default */
1924
      ret = klogctl(7, NULL, 0);
1925
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1926
	perror_plus("klogctl");
304 by Teddy Hogeborn
Four new interrelated features:
1927
      }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1928
    }
308 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1929
#endif	/* __linux__ */
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1930
    /* Lower privileges */
1931
    errno = 0;
1932
    if(take_down_interface){
1933
      /* Lower privileges */
1934
      ret = seteuid(uid);
1935
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1936
	perror_plus("seteuid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1937
      }
1938
    } else {
1939
      /* Lower privileges permanently */
1940
      ret = setuid(uid);
1941
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1942
	perror_plus("setuid");
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
1943
      }
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
1944
    }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1945
  }
1946
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1947
  if(quit_now){
1948
    goto end;
1949
  }
1950
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1951
  ret = init_gnutls_global(pubkey, seckey);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1952
  if(ret == -1){
1953
    fprintf(stderr, "init_gnutls_global failed\n");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1954
    exitcode = EX_UNAVAILABLE;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1955
    goto end;
1956
  } else {
1957
    gnutls_initialized = true;
1958
  }
1959
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1960
  if(quit_now){
1961
    goto end;
1962
  }
1963
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1964
  if(mkdtemp(tempdir) == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1965
    perror_plus("mkdtemp");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1966
    goto end;
1967
  }
24.1.172 by Björn Påhlsson
using scandir instead of readdir
1968
  tempdir_created = true;
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1969
  
1970
  if(quit_now){
1971
    goto end;
1972
  }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1973
  
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1974
  if(not init_gpgme(pubkey, seckey, tempdir)){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1975
    fprintf(stderr, "init_gpgme failed\n");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1976
    exitcode = EX_UNAVAILABLE;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1977
    goto end;
1978
  } else {
1979
    gpgme_initialized = true;
1980
  }
1981
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1982
  if(quit_now){
1983
    goto end;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1984
  }
1985
  
1986
  if(connect_to != NULL){
1987
    /* Connect directly, do not use Zeroconf */
1988
    /* (Mainly meant for debugging) */
1989
    char *address = strrchr(connect_to, ':');
1990
    if(address == NULL){
1991
      fprintf(stderr, "No colon in address\n");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1992
      exitcode = EX_USAGE;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1993
      goto end;
1994
    }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1995
    
1996
    if(quit_now){
1997
      goto end;
1998
    }
1999
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2000
    uint16_t port;
311 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2001
    errno = 0;
2002
    tmpmax = strtoimax(address+1, &tmp, 10);
2003
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
2004
       or tmpmax != (uint16_t)tmpmax){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2005
      fprintf(stderr, "Bad port number\n");
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2006
      exitcode = EX_USAGE;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2007
      goto end;
2008
    }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2009
  
2010
    if(quit_now){
2011
      goto end;
2012
    }
2013
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2014
    port = (uint16_t)tmpmax;
2015
    *address = '\0';
304 by Teddy Hogeborn
Four new interrelated features:
2016
    /* Colon in address indicates IPv6 */
2017
    int af;
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2018
    if(strchr(connect_to, ':') != NULL){
304 by Teddy Hogeborn
Four new interrelated features:
2019
      af = AF_INET6;
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2020
      /* Accept [] around IPv6 address - see RFC 5952 */
2021
      if(connect_to[0] == '[' and address[-1] == ']')
2022
	{
2023
	  connect_to++;
2024
	  address[-1] = '\0';
2025
	}
304 by Teddy Hogeborn
Four new interrelated features:
2026
    } else {
2027
      af = AF_INET;
2028
    }
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2029
    address = connect_to;
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2030
    
2031
    if(quit_now){
2032
      goto end;
2033
    }
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2034
    
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
2035
    while(not quit_now){
2036
      ret = start_mandos_communication(address, port, if_index, af);
2037
      if(quit_now or ret == 0){
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2038
	break;
2039
      }
491 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2040
      if(debug){
2041
	fprintf(stderr, "Retrying in %d seconds\n",
2042
		(int)retry_interval);
2043
      }
2044
      sleep((int)retry_interval);
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
2045
    }
2046
    
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
2047
    if (not quit_now){
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2048
      exitcode = EXIT_SUCCESS;
2049
    }
505.2.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2050
    
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2051
    goto end;
2052
  }
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2053
  
2054
  if(quit_now){
2055
    goto end;
2056
  }
2057
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2058
  {
2059
    AvahiServerConfig config;
2060
    /* Do not publish any local Zeroconf records */
2061
    avahi_server_config_init(&config);
2062
    config.publish_hinfo = 0;
2063
    config.publish_addresses = 0;
2064
    config.publish_workstation = 0;
2065
    config.publish_domain = 0;
2066
    
2067
    /* Allocate a new server */
2068
    mc.server = avahi_server_new(avahi_simple_poll_get
2069
				 (mc.simple_poll), &config, NULL,
2070
				 NULL, &error);
2071
    
2072
    /* Free the Avahi configuration data */
2073
    avahi_server_config_free(&config);
2074
  }
2075
  
2076
  /* Check if creating the Avahi server object succeeded */
2077
  if(mc.server == NULL){
2078
    fprintf(stderr, "Failed to create Avahi server: %s\n",
2079
	    avahi_strerror(error));
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2080
    exitcode = EX_UNAVAILABLE;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2081
    goto end;
2082
  }
2083
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2084
  if(quit_now){
2085
    goto end;
2086
  }
2087
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2088
  /* Create the Avahi service browser */
2089
  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
2090
				   AVAHI_PROTO_UNSPEC, "_mandos._tcp",
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
2091
				   NULL, 0, browse_callback, NULL);
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2092
  if(sb == NULL){
2093
    fprintf(stderr, "Failed to create service browser: %s\n",
2094
	    avahi_strerror(avahi_server_errno(mc.server)));
399 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2095
    exitcode = EX_UNAVAILABLE;
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2096
    goto end;
2097
  }
307 by Teddy Hogeborn
Merge from Björn:
2098
  
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2099
  if(quit_now){
2100
    goto end;
2101
  }
2102
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2103
  /* Run the main loop */
2104
  
2105
  if(debug){
2106
    fprintf(stderr, "Starting Avahi loop search\n");
2107
  }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2108
485 by Teddy Hogeborn
Merge from Björn.
2109
  ret = avahi_loop_with_timeout(mc.simple_poll,
2110
				(int)(retry_interval * 1000));
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2111
  if(debug){
2112
    fprintf(stderr, "avahi_loop_with_timeout exited %s\n",
2113
	    (ret == 0) ? "successfully" : "with error");
2114
  }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2115
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
2116
 end:
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2117
  
2118
  if(debug){
2119
    fprintf(stderr, "%s exiting\n", argv[0]);
2120
  }
2121
  
2122
  /* Cleanup things */
2123
  if(sb != NULL)
2124
    avahi_s_service_browser_free(sb);
2125
  
2126
  if(mc.server != NULL)
2127
    avahi_server_free(mc.server);
2128
  
2129
  if(mc.simple_poll != NULL)
2130
    avahi_simple_poll_free(mc.simple_poll);
2131
  
2132
  if(gnutls_initialized){
2133
    gnutls_certificate_free_credentials(mc.cred);
2134
    gnutls_global_deinit();
2135
    gnutls_dh_params_deinit(mc.dh_params);
2136
  }
2137
  
2138
  if(gpgme_initialized){
2139
    gpgme_release(mc.ctx);
2140
  }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2141
485 by Teddy Hogeborn
Merge from Björn.
2142
  /* Cleans up the circular linked list of Mandos servers the client
2143
     has seen */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2144
  if(mc.current_server != NULL){
2145
    mc.current_server->prev->next = NULL;
2146
    while(mc.current_server != NULL){
2147
      server *next = mc.current_server->next;
2148
      free(mc.current_server);
2149
      mc.current_server = next;
2150
    }
2151
  }
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2152
  
505.2.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2153
  /* XXX run network hooks "stop" here  */
2154
  
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
2155
  /* Take down the network interface */
353 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2156
  if(take_down_interface){
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2157
    /* Re-raise priviliges */
2158
    errno = 0;
2159
    ret = seteuid(0);
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
2160
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2161
      perror_plus("seteuid");
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
2162
    }
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2163
    if(geteuid() == 0){
2164
      ret = ioctl(sd, SIOCGIFFLAGS, &network);
2165
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2166
	perror_plus("ioctl SIOCGIFFLAGS");
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2167
      } else if(network.ifr_flags & IFF_UP) {
394 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2168
	network.ifr_flags &= ~(short)IFF_UP; /* clear flag */
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2169
	ret = ioctl(sd, SIOCSIFFLAGS, &network);
2170
	if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2171
	  perror_plus("ioctl SIOCSIFFLAGS -IFF_UP");
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2172
	}
2173
      }
2174
      ret = (int)TEMP_FAILURE_RETRY(close(sd));
2175
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2176
	perror_plus("close");
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2177
      }
368 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2178
      /* Lower privileges permanently */
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2179
      errno = 0;
2180
      ret = setuid(uid);
2181
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2182
	perror_plus("setuid");
365 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2183
      }
350 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
2184
    }
2185
  }
2186
  
24.1.172 by Björn Påhlsson
using scandir instead of readdir
2187
  /* Removes the GPGME temp directory and all files inside */
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2188
  if(tempdir_created){
24.1.172 by Björn Påhlsson
using scandir instead of readdir
2189
    struct dirent **direntries = NULL;
2190
    struct dirent *direntry = NULL;
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
2191
    int numentries = scandir(tempdir, &direntries, notdotentries,
2192
			     alphasort);
2193
    if (numentries > 0){
2194
      for(int i = 0; i < numentries; i++){
24.1.172 by Björn Påhlsson
using scandir instead of readdir
2195
	direntry = direntries[i];
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2196
	char *fullname = NULL;
2197
	ret = asprintf(&fullname, "%s/%s", tempdir,
2198
		       direntry->d_name);
2199
	if(ret < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2200
	  perror_plus("asprintf");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2201
	  continue;
2202
	}
2203
	ret = remove(fullname);
2204
	if(ret == -1){
2205
	  fprintf(stderr, "remove(\"%s\"): %s\n", fullname,
2206
		  strerror(errno));
2207
	}
2208
	free(fullname);
2209
      }
24.1.172 by Björn Påhlsson
using scandir instead of readdir
2210
    }
2211
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
2212
    /* need to clean even if 0 because man page doesn't specify */
24.1.172 by Björn Påhlsson
using scandir instead of readdir
2213
    free(direntries);
492 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
2214
    if (numentries == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2215
      perror_plus("scandir");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2216
    }
2217
    ret = rmdir(tempdir);
2218
    if(ret == -1 and errno != ENOENT){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2219
      perror_plus("rmdir");
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2220
    }
2221
  }
2222
  
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2223
  if(quit_now){
357 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2224
    sigemptyset(&old_sigterm_action.sa_mask);
2225
    old_sigterm_action.sa_handler = SIG_DFL;
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
2226
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
2227
					    &old_sigterm_action,
2228
					    NULL));
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2229
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2230
      perror_plus("sigaction");
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2231
    }
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
2232
    do {
2233
      ret = raise(signal_received);
2234
    } while(ret != 0 and errno == EINTR);
2235
    if(ret != 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2236
      perror_plus("raise");
374 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
2237
      abort();
2238
    }
2239
    TEMP_FAILURE_RETRY(pause());
354 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2240
  }
2241
  
293 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2242
  return exitcode;
13 by Björn Påhlsson
Added following support:
2243
}