/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1
/*  -*- coding: utf-8 -*- */
2
/*
237.2.24 by Teddy Hogeborn
* plugins.d/askpass-fifo.c: Fix name in header.
3
 * Mandos-client - get and decrypt data from a Mandos server
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
4
 *
5
 * This program is partly derived from an example program for an Avahi
6
 * service browser, downloaded from
7
 * <http://avahi.org/browser/examples/core-browse-services.c>.  This
8
 * includes the following functions: "resolve_callback",
9
 * "browse_callback", and parts of "main".
10
 * 
28 by Teddy Hogeborn
* server.conf: New file.
11
 * Everything else is
237.7.471 by Teddy Hogeborn
Update copyright year to 2018
12
 * Copyright © 2008-2018 Teddy Hogeborn
13
 * Copyright © 2008-2018 Björn Påhlsson
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
14
 * 
237.7.455 by Teddy Hogeborn
Alter copyright notices slightly. Actual license is unchanged!
15
 * This file is part of Mandos.
16
 * 
17
 * Mandos is free software: you can redistribute it and/or modify it
18
 * under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation, either version 3 of the License, or
20
 * (at your option) any later version.
21
 * 
22
 * Mandos is distributed in the hope that it will be useful, but
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
23
 * WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25
 * General Public License for more details.
26
 * 
27
 * You should have received a copy of the GNU General Public License
237.7.455 by Teddy Hogeborn
Alter copyright notices slightly. Actual license is unchanged!
28
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
29
 * 
237.11.2 by Teddy Hogeborn
Change "fukt.bsnet.se" to "recompile.se" throughout.
30
 * Contact the authors at <mandos@recompile.se>.
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
31
 */
32
28 by Teddy Hogeborn
* server.conf: New file.
33
/* Needed by GPGME, specifically gpgme_data_seek() */
237.2.80 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
34
#ifndef _LARGEFILE_SOURCE
13 by Björn Påhlsson
Added following support:
35
#define _LARGEFILE_SOURCE
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
36
#endif	/* not _LARGEFILE_SOURCE */
237.2.80 by Teddy Hogeborn
Use "getconf" to get correct LFS compile and link flags.
37
#ifndef _FILE_OFFSET_BITS
13 by Björn Påhlsson
Added following support:
38
#define _FILE_OFFSET_BITS 64
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
39
#endif	/* not _FILE_OFFSET_BITS */
13 by Björn Påhlsson
Added following support:
40
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
41
#define _GNU_SOURCE		/* TEMP_FAILURE_RETRY(), asprintf() */
24.1.10 by Björn Påhlsson
merge commit
42
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
43
#include <stdio.h>		/* fprintf(), stderr, fwrite(),
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
44
				   stdout, ferror() */
237.7.136 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Eliminate
45
#include <stdint.h> 		/* uint16_t, uint32_t, intptr_t */
24.1.26 by Björn Påhlsson
tally count of used symbols
46
#include <stddef.h>		/* NULL, size_t, ssize_t */
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
47
#include <stdlib.h> 		/* free(), EXIT_SUCCESS, srand(),
48
				   strtof(), abort() */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
49
#include <stdbool.h>		/* bool, false, true */
237.7.321 by Teddy Hogeborn
mandos-client: Don't use memset().
50
#include <string.h>		/* strcmp(), strlen(), strerror(),
237.7.418 by Teddy Hogeborn
Show what signal, if any, made mandos-client exit.
51
				   asprintf(), strncpy(), strsignal()
52
				*/
237.2.67 by Teddy Hogeborn
Four new interrelated features:
53
#include <sys/ioctl.h>		/* ioctl */
24.1.26 by Björn Påhlsson
tally count of used symbols
54
#include <sys/types.h>		/* socket(), inet_pton(), sockaddr,
24.1.29 by Björn Påhlsson
Added more header file comments
55
				   sockaddr_in6, PF_INET6,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
56
				   SOCK_STREAM, uid_t, gid_t, open(),
57
				   opendir(), DIR */
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
58
#include <sys/stat.h>		/* open(), S_ISREG */
24.1.26 by Björn Påhlsson
tally count of used symbols
59
#include <sys/socket.h>		/* socket(), struct sockaddr_in6,
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
60
				   inet_pton(), connect(),
61
				   getnameinfo() */
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
62
#include <fcntl.h>		/* open(), unlinkat(), AT_REMOVEDIR */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
63
#include <dirent.h>		/* opendir(), struct dirent, readdir()
64
				 */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
65
#include <inttypes.h>		/* PRIu16, PRIdMAX, intmax_t,
66
				   strtoimax() */
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
67
#include <errno.h>		/* perror(), errno, EINTR, EINVAL,
68
				   EAI_SYSTEM, ENETUNREACH,
69
				   EHOSTUNREACH, ECONNREFUSED, EPROTO,
70
				   EIO, ENOENT, ENXIO, ENOMEM, EISDIR,
71
				   ENOTEMPTY,
237.7.33 by Teddy Hogeborn
Merge from Björn.
72
				   program_invocation_short_name */
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
73
#include <time.h>		/* nanosleep(), time(), sleep() */
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
74
#include <net/if.h>		/* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
24.1.26 by Björn Påhlsson
tally count of used symbols
75
				   SIOCSIFFLAGS, if_indextoname(),
76
				   if_nametoindex(), IF_NAMESIZE */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
77
#include <netinet/in.h>		/* IN6_IS_ADDR_LINKLOCAL,
78
				   INET_ADDRSTRLEN, INET6_ADDRSTRLEN
79
				*/
24.1.29 by Björn Påhlsson
Added more header file comments
80
#include <unistd.h>		/* close(), SEEK_SET, off_t, write(),
237.2.128 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
81
				   getuid(), getgid(), seteuid(),
237.7.242 by Teddy Hogeborn
Make mandos-client use unlinkat() instead of remove().
82
				   setgid(), pause(), _exit(),
83
				   unlinkat() */
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
84
#include <arpa/inet.h>		/* inet_pton(), htons() */
237.2.67 by Teddy Hogeborn
Four new interrelated features:
85
#include <iso646.h>		/* not, or, and */
24.1.29 by Björn Påhlsson
Added more header file comments
86
#include <argp.h>		/* struct argp_option, error_t, struct
87
				   argp_state, struct argp,
88
				   argp_parse(), ARGP_KEY_ARG,
89
				   ARGP_KEY_END, ARGP_ERR_UNKNOWN */
237.2.70 by Teddy Hogeborn
Merge from Björn:
90
#include <signal.h>		/* sigemptyset(), sigaddset(),
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
91
				   sigaction(), SIGTERM, sig_atomic_t,
92
				   raise() */
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
93
#include <sysexits.h>		/* EX_OSERR, EX_USAGE, EX_UNAVAILABLE,
94
				   EX_NOHOST, EX_IOERR, EX_PROTOCOL */
237.16.3 by teddy at bsnet
* plugins.d/mandos-client.c: Prefix all printouts with "Mandos plugin
95
#include <sys/wait.h>		/* waitpid(), WIFEXITED(),
96
				   WEXITSTATUS(), WTERMSIG() */
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
97
#include <grp.h>		/* setgroups() */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
98
#include <argz.h>		/* argz_add_sep(), argz_next(),
99
				   argz_delete(), argz_append(),
100
				   argz_stringify(), argz_add(),
101
				   argz_count() */
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
102
#include <netdb.h>		/* getnameinfo(), NI_NUMERICHOST,
103
				   EAI_SYSTEM, gai_strerror() */
237.2.70 by Teddy Hogeborn
Merge from Björn:
104
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
105
#ifdef __linux__
24.1.124 by Björn Påhlsson
Added lower kernel loglevel to reduce clutter on system console.
106
#include <sys/klog.h> 		/* klogctl() */
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
107
#endif	/* __linux__ */
24.1.26 by Björn Påhlsson
tally count of used symbols
108
109
/* Avahi */
24.1.29 by Björn Påhlsson
Added more header file comments
110
/* All Avahi types, constants and functions
111
 Avahi*, avahi_*,
112
 AVAHI_* */
113
#include <avahi-core/core.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
114
#include <avahi-core/lookup.h>
24.1.29 by Björn Påhlsson
Added more header file comments
115
#include <avahi-core/log.h>
24.1.26 by Björn Påhlsson
tally count of used symbols
116
#include <avahi-common/simple-watch.h>
117
#include <avahi-common/malloc.h>
118
#include <avahi-common/error.h>
119
120
/* GnuTLS */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
121
#include <gnutls/gnutls.h>	/* All GnuTLS types, constants and
122
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
123
				   gnutls_*
24.1.26 by Björn Påhlsson
tally count of used symbols
124
				   init_gnutls_session(),
24.1.29 by Björn Påhlsson
Added more header file comments
125
				   GNUTLS_* */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
126
#include <gnutls/openpgp.h>
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
127
			 /* gnutls_certificate_set_openpgp_key_file(),
128
			    GNUTLS_OPENPGP_FMT_BASE64 */
24.1.26 by Björn Påhlsson
tally count of used symbols
129
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
130
/* GPGME */
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
131
#include <gpgme.h> 		/* All GPGME types, constants and
132
				   functions:
24.1.29 by Björn Påhlsson
Added more header file comments
133
				   gpgme_*
24.1.26 by Björn Påhlsson
tally count of used symbols
134
				   GPGME_PROTOCOL_OpenPGP,
24.1.29 by Björn Påhlsson
Added more header file comments
135
				   GPG_ERR_NO_* */
13 by Björn Påhlsson
Added following support:
136
137
#define BUFFER_SIZE 256
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
138
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
139
#define PATHDIR "/conf/conf.d/mandos"
140
#define SECKEY "seckey.txt"
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
141
#define PUBKEY "pubkey.txt"
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
142
#define HOOKDIR "/lib/mandos/network-hooks.d"
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
143
15.1.2 by Björn Påhlsson
Added debug options from passprompt as --debug and --debug=passprompt
144
bool debug = false;
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
145
static const char mandos_protocol_version[] = "1";
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
146
const char *argp_program_version = "mandos-client " VERSION;
147
const char *argp_program_bug_address = "<mandos@recompile.se>";
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
148
static const char sys_class_net[] = "/sys/class/net";
149
char *connect_to = NULL;
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
150
const char *hookdir = HOOKDIR;
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
151
int hookdir_fd = -1;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
152
uid_t uid = 65534;
153
gid_t gid = 65534;
24.1.10 by Björn Påhlsson
merge commit
154
237.7.33 by Teddy Hogeborn
Merge from Björn.
155
/* 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.
156
typedef struct server{
157
  const char *ip;
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
158
  in_port_t port;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
159
  AvahiIfIndex if_index;
160
  int af;
161
  struct timespec last_seen;
162
  struct server *next;
163
  struct server *prev;
164
} server;
165
42 by Teddy Hogeborn
* plugins.d/mandosclient.c (start_mandos_communication): Change "to"
166
/* Used for passing in values through the Avahi callback functions */
13 by Björn Påhlsson
Added following support:
167
typedef struct {
24.1.9 by Björn Påhlsson
not working midwork...
168
  AvahiServer *server;
13 by Björn Påhlsson
Added following support:
169
  gnutls_certificate_credentials_t cred;
24.1.9 by Björn Påhlsson
not working midwork...
170
  unsigned int dh_bits;
24.1.13 by Björn Påhlsson
mandosclient
171
  gnutls_dh_params_t dh_params;
24.1.9 by Björn Påhlsson
not working midwork...
172
  const char *priority;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
173
  gpgme_ctx_t ctx;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
174
  server *current_server;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
175
  char *interfaces;
176
  size_t interfaces_size;
24.1.9 by Björn Påhlsson
not working midwork...
177
} mandos_context;
13 by Björn Påhlsson
Added following support:
178
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
179
/* global so signal handler can reach it*/
180
AvahiSimplePoll *simple_poll;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
181
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
182
sig_atomic_t quit_now = 0;
183
int signal_received = 0;
184
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
185
/* Function to use when printing errors */
186
void perror_plus(const char *print_text){
237.7.82 by teddy at bsnet
* plugin-runner.c (add_to_char_array): Added "nonnull" attribute.
187
  int e = errno;
237.7.33 by Teddy Hogeborn
Merge from Björn.
188
  fprintf(stderr, "Mandos plugin %s: ",
189
	  program_invocation_short_name);
237.7.82 by teddy at bsnet
* plugin-runner.c (add_to_char_array): Added "nonnull" attribute.
190
  errno = e;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
191
  perror(print_text);
192
}
193
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
194
__attribute__((format (gnu_printf, 2, 3), nonnull))
237.15.4 by Björn Påhlsson
New convinence error printer: fprintf_plus
195
int fprintf_plus(FILE *stream, const char *format, ...){
196
  va_list ap;
197
  va_start (ap, format);
198
  
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
199
  TEMP_FAILURE_RETRY(fprintf(stream, "Mandos plugin %s: ",
200
			     program_invocation_short_name));
237.7.170 by Teddy Hogeborn
* debian/control (Build-Depends): Depend on debhelper 8.9.7 for using
201
  return (int)TEMP_FAILURE_RETRY(vfprintf(stream, format, ap));
237.15.4 by Björn Påhlsson
New convinence error printer: fprintf_plus
202
}
203
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
204
/*
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
205
 * Make additional room in "buffer" for at least BUFFER_SIZE more
206
 * bytes. "buffer_capacity" is how much is currently allocated,
207
 * "buffer_length" is how much is already used.
43 by Teddy Hogeborn
* plugins.d/mandosclient.c: Cosmetic changes.
208
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
209
__attribute__((nonnull, warn_unused_result))
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
210
size_t incbuffer(char **buffer, size_t buffer_length,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
211
		 size_t buffer_capacity){
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
212
  if(buffer_length + BUFFER_SIZE > buffer_capacity){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
213
    char *new_buf = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
214
    if(new_buf == NULL){
215
      int old_errno = errno;
216
      free(*buffer);
217
      errno = old_errno;
218
      *buffer = NULL;
24.1.10 by Björn Påhlsson
merge commit
219
      return 0;
220
    }
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
221
    *buffer = new_buf;
24.1.10 by Björn Påhlsson
merge commit
222
    buffer_capacity += BUFFER_SIZE;
223
  }
224
  return buffer_capacity;
225
}
226
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
227
/* Add server to set of servers to retry periodically */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
228
__attribute__((nonnull, warn_unused_result))
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
229
bool add_server(const char *ip, in_port_t port, AvahiIfIndex if_index,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
230
		int af, server **current_server){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
231
  int ret;
232
  server *new_server = malloc(sizeof(server));
233
  if(new_server == NULL){
234
    perror_plus("malloc");
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
235
    return false;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
236
  }
237
  *new_server = (server){ .ip = strdup(ip),
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
238
			  .port = port,
239
			  .if_index = if_index,
240
			  .af = af };
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
241
  if(new_server->ip == NULL){
242
    perror_plus("strdup");
237.7.258 by Teddy Hogeborn
mandos-client: Fix minor memory leak on memory full or clock failure.
243
    free(new_server);
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
244
    return false;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
245
  }
237.7.216 by Teddy Hogeborn
Do not add a new server to server list if clock_gettime() fails
246
  ret = clock_gettime(CLOCK_MONOTONIC, &(new_server->last_seen));
247
  if(ret == -1){
248
    perror_plus("clock_gettime");
237.7.262 by Teddy Hogeborn
mandos-client: Fix mem free bug.
249
#ifdef __GNUC__
250
#pragma GCC diagnostic push
251
#pragma GCC diagnostic ignored "-Wcast-qual"
252
#endif
253
    free((char *)(new_server->ip));
254
#ifdef __GNUC__
255
#pragma GCC diagnostic pop
256
#endif
237.7.258 by Teddy Hogeborn
mandos-client: Fix minor memory leak on memory full or clock failure.
257
    free(new_server);
237.7.216 by Teddy Hogeborn
Do not add a new server to server list if clock_gettime() fails
258
    return false;
259
  }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
260
  /* Special case of first server */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
261
  if(*current_server == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
262
    new_server->next = new_server;
263
    new_server->prev = new_server;
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
264
    *current_server = new_server;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
265
  } else {
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
266
    /* Place the new server last in the list */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
267
    new_server->next = *current_server;
268
    new_server->prev = (*current_server)->prev;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
269
    new_server->prev->next = new_server;
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
270
    (*current_server)->prev = new_server;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
271
  }
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
272
  return true;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
273
}
274
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
275
/* 
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
276
 * Initialize GPGME.
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
277
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
278
__attribute__((nonnull, warn_unused_result))
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
279
static bool init_gpgme(const char * const seckey,
280
		       const char * const pubkey,
281
		       const char * const tempdir,
282
		       mandos_context *mc){
13 by Björn Påhlsson
Added following support:
283
  gpgme_error_t rc;
284
  gpgme_engine_info_t engine_info;
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
285
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
286
  /*
237.2.51 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Use separate bool variable instead
287
   * 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.
288
   */
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
289
  bool import_key(const char * const filename){
237.2.124 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
290
    int ret;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
291
    int fd;
292
    gpgme_data_t pgp_data;
293
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
294
    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.
295
    if(fd == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
296
      perror_plus("open");
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
297
      return false;
298
    }
299
    
300
    rc = gpgme_data_new_from_fd(&pgp_data, fd);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
301
    if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
302
      fprintf_plus(stderr, "bad gpgme_data_new_from_fd: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
303
		   gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
304
      return false;
305
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
306
    
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
307
    rc = gpgme_op_import(mc->ctx, pgp_data);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
308
    if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
309
      fprintf_plus(stderr, "bad gpgme_op_import: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
310
		   gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
311
      return false;
312
    }
237.7.495 by Teddy Hogeborn
Check for and report GPGME key import errors
313
    {
314
      gpgme_import_result_t import_result
315
	= gpgme_op_import_result(mc->ctx);
316
      if((import_result->imported < 1
317
	  or import_result->not_imported > 0)
318
	 and import_result->unchanged == 0){
319
	fprintf_plus(stderr, "bad gpgme_op_import_results:\n");
320
	fprintf_plus(stderr,
321
		     "The total number of considered keys: %d\n",
322
		     import_result->considered);
323
	fprintf_plus(stderr,
324
		     "The number of keys without user ID: %d\n",
325
		     import_result->no_user_id);
326
	fprintf_plus(stderr,
327
		     "The total number of imported keys: %d\n",
328
		     import_result->imported);
329
	fprintf_plus(stderr, "The number of imported RSA keys: %d\n",
330
		     import_result->imported_rsa);
331
	fprintf_plus(stderr, "The number of unchanged keys: %d\n",
332
		     import_result->unchanged);
333
	fprintf_plus(stderr, "The number of new user IDs: %d\n",
334
		     import_result->new_user_ids);
335
	fprintf_plus(stderr, "The number of new sub keys: %d\n",
336
		     import_result->new_sub_keys);
337
	fprintf_plus(stderr, "The number of new signatures: %d\n",
338
		     import_result->new_signatures);
339
	fprintf_plus(stderr, "The number of new revocations: %d\n",
340
		     import_result->new_revocations);
341
	fprintf_plus(stderr,
342
		     "The total number of secret keys read: %d\n",
343
		     import_result->secret_read);
344
	fprintf_plus(stderr,
345
		     "The number of imported secret keys: %d\n",
346
		     import_result->secret_imported);
347
	fprintf_plus(stderr,
348
		     "The number of unchanged secret keys: %d\n",
349
		     import_result->secret_unchanged);
350
	fprintf_plus(stderr, "The number of keys not imported: %d\n",
351
		     import_result->not_imported);
352
	for(gpgme_import_status_t import_status
353
	      = import_result->imports;
354
	    import_status != NULL;
355
	    import_status = import_status->next){
356
	  fprintf_plus(stderr, "Import status for key: %s\n",
357
		       import_status->fpr);
358
	  if(import_status->result != GPG_ERR_NO_ERROR){
359
	    fprintf_plus(stderr, "Import result: %s: %s\n",
360
			 gpgme_strsource(import_status->result),
361
			 gpgme_strerror(import_status->result));
362
	  }
363
	  fprintf_plus(stderr, "Key status:\n");
364
	  fprintf_plus(stderr,
365
		       import_status->status & GPGME_IMPORT_NEW
366
		       ? "The key was new.\n"
367
		       : "The key was not new.\n");
368
	  fprintf_plus(stderr,
369
		       import_status->status & GPGME_IMPORT_UID
370
		       ? "The key contained new user IDs.\n"
371
		       : "The key did not contain new user IDs.\n");
372
	  fprintf_plus(stderr,
373
		       import_status->status & GPGME_IMPORT_SIG
374
		       ? "The key contained new signatures.\n"
375
		       : "The key did not contain new signatures.\n");
376
	  fprintf_plus(stderr,
377
		       import_status->status & GPGME_IMPORT_SUBKEY
378
		       ? "The key contained new sub keys.\n"
379
		       : "The key did not contain new sub keys.\n");
380
	  fprintf_plus(stderr,
381
		       import_status->status & GPGME_IMPORT_SECRET
382
		       ? "The key contained a secret key.\n"
383
		       : "The key did not contain a secret key.\n");
384
	}
385
	return false;
386
      }
387
    }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
388
    
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
389
    ret = close(fd);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
390
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
391
      perror_plus("close");
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
392
    }
393
    gpgme_data_release(pgp_data);
394
    return true;
395
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
396
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
397
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
398
    fprintf_plus(stderr, "Initializing GPGME\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
399
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
400
  
13 by Björn Påhlsson
Added following support:
401
  /* Init GPGME */
402
  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.
403
  rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
404
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
405
    fprintf_plus(stderr, "bad gpgme_engine_check_version: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
406
		 gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
407
    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.
408
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
409
  
237.7.40 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
410
  /* Set GPGME home directory for the OpenPGP engine only */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
411
  rc = gpgme_get_engine_info(&engine_info);
412
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
413
    fprintf_plus(stderr, "bad gpgme_get_engine_info: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
414
		 gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
415
    return false;
13 by Björn Påhlsson
Added following support:
416
  }
417
  while(engine_info != NULL){
418
    if(engine_info->protocol == GPGME_PROTOCOL_OpenPGP){
419
      gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP,
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
420
			    engine_info->file_name, tempdir);
13 by Björn Påhlsson
Added following support:
421
      break;
422
    }
423
    engine_info = engine_info->next;
424
  }
425
  if(engine_info == NULL){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
426
    fprintf_plus(stderr, "Could not set GPGME home dir to %s\n",
427
		 tempdir);
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
428
    return false;
429
  }
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
430
  
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
431
  /* Create new GPGME "context" */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
432
  rc = gpgme_new(&(mc->ctx));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
433
  if(rc != GPG_ERR_NO_ERROR){
237.7.494 by Teddy Hogeborn
Remove duplicate "Mandos plugin mandos-client:" in error output
434
    fprintf_plus(stderr, "bad gpgme_new: %s: %s\n",
435
		 gpgme_strsource(rc), gpgme_strerror(rc));
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
436
    return false;
437
  }
438
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
439
  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.
440
    return false;
441
  }
442
  
237.2.118 by Teddy Hogeborn
* mandos: White-space fixes only.
443
  return true;
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
444
}
445
446
/* 
447
 * Decrypt OpenPGP data.
448
 * Returns -1 on error
449
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
450
__attribute__((nonnull, warn_unused_result))
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
451
static ssize_t pgp_packet_decrypt(const char *cryptotext,
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
452
				  size_t crypto_size,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
453
				  char **plaintext,
454
				  mandos_context *mc){
24.1.81 by Björn Påhlsson
removed keyring pre-requirement for starting password-request.
455
  gpgme_data_t dh_crypto, dh_plain;
456
  gpgme_error_t rc;
457
  ssize_t ret;
458
  size_t plaintext_capacity = 0;
459
  ssize_t plaintext_length = 0;
460
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
461
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
462
    fprintf_plus(stderr, "Trying to decrypt OpenPGP data\n");
13 by Björn Påhlsson
Added following support:
463
  }
464
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
465
  /* Create new GPGME data buffer from memory cryptotext */
466
  rc = gpgme_data_new_from_mem(&dh_crypto, cryptotext, crypto_size,
467
			       0);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
468
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
469
    fprintf_plus(stderr, "bad gpgme_data_new_from_mem: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
470
		 gpgme_strsource(rc), gpgme_strerror(rc));
13 by Björn Påhlsson
Added following support:
471
    return -1;
472
  }
473
  
474
  /* Create new empty GPGME data buffer for the plaintext */
475
  rc = gpgme_data_new(&dh_plain);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
476
  if(rc != GPG_ERR_NO_ERROR){
237.7.494 by Teddy Hogeborn
Remove duplicate "Mandos plugin mandos-client:" in error output
477
    fprintf_plus(stderr, "bad gpgme_data_new: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
478
		 gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
479
    gpgme_data_release(dh_crypto);
13 by Björn Påhlsson
Added following support:
480
    return -1;
481
  }
482
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
483
  /* Decrypt data from the cryptotext data buffer to the plaintext
484
     data buffer */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
485
  rc = gpgme_op_decrypt(mc->ctx, dh_crypto, dh_plain);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
486
  if(rc != GPG_ERR_NO_ERROR){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
487
    fprintf_plus(stderr, "bad gpgme_op_decrypt: %s: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
488
		 gpgme_strsource(rc), gpgme_strerror(rc));
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
489
    plaintext_length = -1;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
490
    if(debug){
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
491
      gpgme_decrypt_result_t result;
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
492
      result = gpgme_op_decrypt_result(mc->ctx);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
493
      if(result == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
494
	fprintf_plus(stderr, "gpgme_op_decrypt_result failed\n");
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
495
      } else {
237.7.492 by Teddy Hogeborn
Don't print NULL string pointers in error message output
496
	if(result->unsupported_algorithm != NULL) {
497
	  fprintf_plus(stderr, "Unsupported algorithm: %s\n",
498
		       result->unsupported_algorithm);
499
	}
237.7.493 by Teddy Hogeborn
Print a boolean more readably in error message output
500
	fprintf_plus(stderr, "Wrong key usage: %s\n",
501
		     result->wrong_key_usage ? "Yes" : "No");
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
502
	if(result->file_name != NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
503
	  fprintf_plus(stderr, "File name: %s\n", result->file_name);
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
504
	}
505
	gpgme_recipient_t recipient;
506
	recipient = result->recipients;
237.2.112 by Teddy Hogeborn
* plugins.d/mandos-client.c (pgp_packet_decrypt): Remove redundant
507
	while(recipient != NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
508
	  fprintf_plus(stderr, "Public key algorithm: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
509
		       gpgme_pubkey_algo_name
510
		       (recipient->pubkey_algo));
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
511
	  fprintf_plus(stderr, "Key ID: %s\n", recipient->keyid);
512
	  fprintf_plus(stderr, "Secret key available: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
513
		       recipient->status == GPG_ERR_NO_SECKEY
514
		       ? "No" : "Yes");
237.2.112 by Teddy Hogeborn
* plugins.d/mandos-client.c (pgp_packet_decrypt): Remove redundant
515
	  recipient = recipient->next;
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
516
	}
517
      }
518
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
519
    goto decrypt_end;
13 by Björn Påhlsson
Added following support:
520
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
521
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
522
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
523
    fprintf_plus(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
524
  }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
525
  
13 by Björn Påhlsson
Added following support:
526
  /* Seek back to the beginning of the GPGME plaintext data buffer */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
527
  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.
528
    perror_plus("gpgme_data_seek");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
529
    plaintext_length = -1;
530
    goto decrypt_end;
24.1.5 by Björn Påhlsson
plugbasedclient:
531
  }
532
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
533
  *plaintext = NULL;
13 by Björn Påhlsson
Added following support:
534
  while(true){
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
535
    plaintext_capacity = incbuffer(plaintext,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
536
				   (size_t)plaintext_length,
537
				   plaintext_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
538
    if(plaintext_capacity == 0){
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
539
      perror_plus("incbuffer");
540
      plaintext_length = -1;
541
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
542
    }
543
    
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
544
    ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
545
			  BUFFER_SIZE);
13 by Björn Påhlsson
Added following support:
546
    /* Print the data, if any */
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
547
    if(ret == 0){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
548
      /* EOF */
13 by Björn Påhlsson
Added following support:
549
      break;
550
    }
551
    if(ret < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
552
      perror_plus("gpgme_data_read");
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
553
      plaintext_length = -1;
554
      goto decrypt_end;
13 by Björn Påhlsson
Added following support:
555
    }
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
556
    plaintext_length += ret;
13 by Björn Påhlsson
Added following support:
557
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
558
  
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
559
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
560
    fprintf_plus(stderr, "Decrypted password is: ");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
561
    for(ssize_t i = 0; i < plaintext_length; i++){
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
562
      fprintf(stderr, "%02hhX ", (*plaintext)[i]);
563
    }
564
    fprintf(stderr, "\n");
565
  }
566
  
567
 decrypt_end:
568
  
569
  /* Delete the GPGME cryptotext data buffer */
570
  gpgme_data_release(dh_crypto);
15.1.3 by Björn Påhlsson
Added getopt_long support for mandosclient and passprompt
571
  
572
  /* Delete the GPGME plaintext data buffer */
13 by Björn Påhlsson
Added following support:
573
  gpgme_data_release(dh_plain);
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
574
  return plaintext_length;
13 by Björn Påhlsson
Added following support:
575
}
576
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
577
__attribute__((warn_unused_result, const))
578
static const char *safe_string(const char *str){
579
  if(str == NULL)
580
    return "(unknown)";
581
  return str;
582
}
583
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
584
__attribute__((warn_unused_result))
585
static const char *safer_gnutls_strerror(int value){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
586
  const char *ret = gnutls_strerror(value);
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
587
  return safe_string(ret);
13 by Björn Påhlsson
Added following support:
588
}
589
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
590
/* GnuTLS log function callback */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
591
__attribute__((nonnull))
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
592
static void debuggnutls(__attribute__((unused)) int level,
593
			const char* string){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
594
  fprintf_plus(stderr, "GnuTLS: %s", string);
13 by Björn Påhlsson
Added following support:
595
}
596
237.7.359 by Teddy Hogeborn
Client: Remove an incorrect "nonnull" attribute
597
__attribute__((nonnull(1, 2, 4), warn_unused_result))
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
598
static int init_gnutls_global(const char *pubkeyfilename,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
599
			      const char *seckeyfilename,
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
600
			      const char *dhparamsfilename,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
601
			      mandos_context *mc){
13 by Björn Påhlsson
Added following support:
602
  int ret;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
603
  unsigned int uret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
604
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
605
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
606
    fprintf_plus(stderr, "Initializing GnuTLS\n");
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
607
  }
24.1.29 by Björn Påhlsson
Added more header file comments
608
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
609
  if(debug){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
610
    /* "Use a log level over 10 to enable all debugging options."
611
     * - GnuTLS manual
612
     */
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
613
    gnutls_global_set_log_level(11);
614
    gnutls_global_set_log_function(debuggnutls);
615
  }
616
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
617
  /* OpenPGP credentials */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
618
  ret = gnutls_certificate_allocate_credentials(&mc->cred);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
619
  if(ret != GNUTLS_E_SUCCESS){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
620
    fprintf_plus(stderr, "GnuTLS memory error: %s\n",
621
		 safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
622
    return -1;
623
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
624
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
625
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
626
    fprintf_plus(stderr, "Attempting to use OpenPGP public key %s and"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
627
		 " secret key %s as GnuTLS credentials\n",
628
		 pubkeyfilename,
629
		 seckeyfilename);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
630
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
631
  
13 by Björn Påhlsson
Added following support:
632
  ret = gnutls_certificate_set_openpgp_key_file
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
633
    (mc->cred, pubkeyfilename, seckeyfilename,
76 by Teddy Hogeborn
* plugins.d/password-request.c (init_gnutls_global): Renamed
634
     GNUTLS_OPENPGP_FMT_BASE64);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
635
  if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
636
    fprintf_plus(stderr,
637
		 "Error[%d] while reading the OpenPGP key pair ('%s',"
638
		 " '%s')\n", ret, pubkeyfilename, seckeyfilename);
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
639
    fprintf_plus(stderr, "The GnuTLS error is: %s\n",
640
		 safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
641
    goto globalfail;
13 by Björn Påhlsson
Added following support:
642
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
643
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
644
  /* GnuTLS server initialization */
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
645
  ret = gnutls_dh_params_init(&mc->dh_params);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
646
  if(ret != GNUTLS_E_SUCCESS){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
647
    fprintf_plus(stderr, "Error in GnuTLS DH parameter"
648
		 " initialization: %s\n",
649
		 safer_gnutls_strerror(ret));
24.1.20 by Björn Påhlsson
mandosclient
650
    goto globalfail;
13 by Björn Påhlsson
Added following support:
651
  }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
652
  /* If a Diffie-Hellman parameters file was given, try to use it */
653
  if(dhparamsfilename != NULL){
654
    gnutls_datum_t params = { .data = NULL, .size = 0 };
655
    do {
656
      int dhpfile = open(dhparamsfilename, O_RDONLY);
657
      if(dhpfile == -1){
658
	perror_plus("open");
659
	dhparamsfilename = NULL;
660
	break;
661
      }
662
      size_t params_capacity = 0;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
663
      while(true){
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
664
	params_capacity = incbuffer((char **)&params.data,
665
				    (size_t)params.size,
666
				    (size_t)params_capacity);
667
	if(params_capacity == 0){
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
668
	  perror_plus("incbuffer");
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
669
	  free(params.data);
670
	  params.data = NULL;
671
	  dhparamsfilename = NULL;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
672
	  break;
673
	}
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
674
	ssize_t bytes_read = read(dhpfile,
675
				  params.data + params.size,
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
676
				  BUFFER_SIZE);
677
	/* EOF */
678
	if(bytes_read == 0){
679
	  break;
680
	}
681
	/* check bytes_read for failure */
682
	if(bytes_read < 0){
683
	  perror_plus("read");
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
684
	  free(params.data);
685
	  params.data = NULL;
686
	  dhparamsfilename = NULL;
687
	  break;
688
	}
689
	params.size += (unsigned int)bytes_read;
690
      }
237.7.489 by Teddy Hogeborn
Check return values from newly added close() calls
691
      ret = close(dhpfile);
692
      if(ret == -1){
693
	perror_plus("close");
694
      }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
695
      if(params.data == NULL){
696
	dhparamsfilename = NULL;
697
      }
698
      if(dhparamsfilename == NULL){
699
	break;
700
      }
701
      ret = gnutls_dh_params_import_pkcs3(mc->dh_params, &params,
702
					  GNUTLS_X509_FMT_PEM);
703
      if(ret != GNUTLS_E_SUCCESS){
704
	fprintf_plus(stderr, "Failed to parse DH parameters in file"
705
		     " \"%s\": %s\n", dhparamsfilename,
706
		     safer_gnutls_strerror(ret));
707
	dhparamsfilename = NULL;
708
      }
237.7.425 by Teddy Hogeborn
Fix bug where Mandos client would crash on exit
709
      free(params.data);
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
710
    } while(false);
711
  }
712
  if(dhparamsfilename == NULL){
713
    if(mc->dh_bits == 0){
714
      /* Find out the optimal number of DH bits */
715
      /* Try to read the private key file */
716
      gnutls_datum_t buffer = { .data = NULL, .size = 0 };
717
      do {
718
	int secfile = open(seckeyfilename, O_RDONLY);
719
	if(secfile == -1){
720
	  perror_plus("open");
721
	  break;
722
	}
723
	size_t buffer_capacity = 0;
724
	while(true){
725
	  buffer_capacity = incbuffer((char **)&buffer.data,
726
				      (size_t)buffer.size,
727
				      (size_t)buffer_capacity);
728
	  if(buffer_capacity == 0){
729
	    perror_plus("incbuffer");
730
	    free(buffer.data);
731
	    buffer.data = NULL;
732
	    break;
733
	  }
734
	  ssize_t bytes_read = read(secfile,
735
				    buffer.data + buffer.size,
736
				    BUFFER_SIZE);
737
	  /* EOF */
738
	  if(bytes_read == 0){
739
	    break;
740
	  }
741
	  /* check bytes_read for failure */
742
	  if(bytes_read < 0){
743
	    perror_plus("read");
744
	    free(buffer.data);
745
	    buffer.data = NULL;
746
	    break;
747
	  }
748
	  buffer.size += (unsigned int)bytes_read;
749
	}
750
	close(secfile);
751
      } while(false);
752
      /* If successful, use buffer to parse private key */
753
      gnutls_sec_param_t sec_param = GNUTLS_SEC_PARAM_ULTRA;
754
      if(buffer.data != NULL){
755
	{
756
	  gnutls_openpgp_privkey_t privkey = NULL;
757
	  ret = gnutls_openpgp_privkey_init(&privkey);
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
758
	  if(ret != GNUTLS_E_SUCCESS){
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
759
	    fprintf_plus(stderr, "Error initializing OpenPGP key"
760
			 " structure: %s",
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
761
			 safer_gnutls_strerror(ret));
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
762
	    free(buffer.data);
763
	    buffer.data = NULL;
764
	  } else {
765
	    ret = gnutls_openpgp_privkey_import
766
	      (privkey, &buffer, GNUTLS_OPENPGP_FMT_BASE64, "", 0);
767
	    if(ret != GNUTLS_E_SUCCESS){
768
	      fprintf_plus(stderr, "Error importing OpenPGP key : %s",
769
			   safer_gnutls_strerror(ret));
770
	      privkey = NULL;
771
	    }
772
	    free(buffer.data);
773
	    buffer.data = NULL;
774
	    if(privkey != NULL){
775
	      /* Use private key to suggest an appropriate
776
		 sec_param */
777
	      sec_param = gnutls_openpgp_privkey_sec_param(privkey);
778
	      gnutls_openpgp_privkey_deinit(privkey);
779
	      if(debug){
780
		fprintf_plus(stderr, "This OpenPGP key implies using"
781
			     " a GnuTLS security parameter \"%s\".\n",
782
			     safe_string(gnutls_sec_param_get_name
783
					 (sec_param)));
784
	      }
785
	    }
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
786
	  }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
787
	}
788
	if(sec_param == GNUTLS_SEC_PARAM_UNKNOWN){
789
	  /* Err on the side of caution */
790
	  sec_param = GNUTLS_SEC_PARAM_ULTRA;
791
	  if(debug){
792
	    fprintf_plus(stderr, "Falling back to security parameter"
793
			 " \"%s\"\n",
794
			 safe_string(gnutls_sec_param_get_name
795
				     (sec_param)));
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
796
	  }
797
	}
798
      }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
799
      uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
800
      if(uret != 0){
801
	mc->dh_bits = uret;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
802
	if(debug){
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
803
	  fprintf_plus(stderr, "A \"%s\" GnuTLS security parameter"
804
		       " implies %u DH bits; using that.\n",
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
805
		       safe_string(gnutls_sec_param_get_name
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
806
				   (sec_param)),
807
		       mc->dh_bits);
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
808
	}
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
809
      } else {
810
	fprintf_plus(stderr, "Failed to get implied number of DH"
811
		     " bits for security parameter \"%s\"): %s\n",
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
812
		     safe_string(gnutls_sec_param_get_name
813
				 (sec_param)),
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
814
		     safer_gnutls_strerror(ret));
815
	goto globalfail;
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
816
      }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
817
    } else if(debug){
818
      fprintf_plus(stderr, "DH bits explicitly set to %u\n",
819
		   mc->dh_bits);
820
    }
821
    ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
822
    if(ret != GNUTLS_E_SUCCESS){
823
      fprintf_plus(stderr, "Error in GnuTLS prime generation (%u"
824
		   " bits): %s\n", mc->dh_bits,
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
825
		   safer_gnutls_strerror(ret));
826
      goto globalfail;
827
    }
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
828
  }
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
829
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
830
  
24.1.13 by Björn Påhlsson
mandosclient
831
  return 0;
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
832
  
24.1.20 by Björn Påhlsson
mandosclient
833
 globalfail:
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
834
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
835
  gnutls_certificate_free_credentials(mc->cred);
836
  gnutls_dh_params_deinit(mc->dh_params);
24.1.20 by Björn Påhlsson
mandosclient
837
  return -1;
24.1.13 by Björn Påhlsson
mandosclient
838
}
839
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
840
__attribute__((nonnull, warn_unused_result))
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
841
static int init_gnutls_session(gnutls_session_t *session,
842
			       mandos_context *mc){
24.1.13 by Björn Påhlsson
mandosclient
843
  int ret;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
844
  /* GnuTLS session creation */
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
845
  do {
846
    ret = gnutls_init(session, GNUTLS_SERVER);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
847
    if(quit_now){
848
      return -1;
849
    }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
850
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
851
  if(ret != GNUTLS_E_SUCCESS){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
852
    fprintf_plus(stderr,
853
		 "Error in GnuTLS session initialization: %s\n",
854
		 safer_gnutls_strerror(ret));
13 by Björn Påhlsson
Added following support:
855
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
856
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
857
  {
858
    const char *err;
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
859
    do {
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
860
      ret = gnutls_priority_set_direct(*session, mc->priority, &err);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
861
      if(quit_now){
862
	gnutls_deinit(*session);
863
	return -1;
864
      }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
865
    } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
866
    if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
867
      fprintf_plus(stderr, "Syntax error at: %s\n", err);
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
868
      fprintf_plus(stderr, "GnuTLS error: %s\n",
869
		   safer_gnutls_strerror(ret));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
870
      gnutls_deinit(*session);
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
871
      return -1;
872
    }
13 by Björn Påhlsson
Added following support:
873
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
874
  
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
875
  do {
876
    ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
877
				 mc->cred);
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
878
    if(quit_now){
879
      gnutls_deinit(*session);
880
      return -1;
881
    }
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
882
  } while(ret == GNUTLS_E_INTERRUPTED or ret == GNUTLS_E_AGAIN);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
883
  if(ret != GNUTLS_E_SUCCESS){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
884
    fprintf_plus(stderr, "Error setting GnuTLS credentials: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
885
		 safer_gnutls_strerror(ret));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
886
    gnutls_deinit(*session);
13 by Björn Påhlsson
Added following support:
887
    return -1;
888
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
889
  
13 by Björn Påhlsson
Added following support:
890
  /* ignore client certificate if any. */
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
891
  gnutls_certificate_server_set_request(*session, GNUTLS_CERT_IGNORE);
13 by Björn Påhlsson
Added following support:
892
  
893
  return 0;
894
}
895
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
896
/* Avahi log function callback */
36 by Teddy Hogeborn
* TODO: Converted to org-mode style
897
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
898
		      __attribute__((unused)) const char *txt){}
13 by Björn Påhlsson
Added following support:
899
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
900
/* Set effective uid to 0, return errno */
901
__attribute__((warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
902
int raise_privileges(void){
903
  int old_errno = errno;
904
  int ret = 0;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
905
  if(seteuid(0) == -1){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
906
    ret = errno;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
907
  }
908
  errno = old_errno;
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
909
  return ret;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
910
}
911
912
/* Set effective and real user ID to 0.  Return errno. */
913
__attribute__((warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
914
int raise_privileges_permanently(void){
915
  int old_errno = errno;
916
  int ret = raise_privileges();
917
  if(ret != 0){
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
918
    errno = old_errno;
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
919
    return ret;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
920
  }
921
  if(setuid(0) == -1){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
922
    ret = errno;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
923
  }
924
  errno = old_errno;
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
925
  return ret;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
926
}
927
928
/* Set effective user ID to unprivileged saved user ID */
929
__attribute__((warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
930
int lower_privileges(void){
931
  int old_errno = errno;
932
  int ret = 0;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
933
  if(seteuid(uid) == -1){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
934
    ret = errno;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
935
  }
936
  errno = old_errno;
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
937
  return ret;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
938
}
939
940
/* Lower privileges permanently */
941
__attribute__((warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
942
int lower_privileges_permanently(void){
943
  int old_errno = errno;
944
  int ret = 0;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
945
  if(setuid(uid) == -1){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
946
    ret = errno;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
947
  }
948
  errno = old_errno;
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
949
  return ret;
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
950
}
951
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
952
/* Helper function to add_local_route() and delete_local_route() */
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
953
__attribute__((nonnull, warn_unused_result))
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
954
static bool add_delete_local_route(const bool add,
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
955
				   const char *address,
956
				   AvahiIfIndex if_index){
957
  int ret;
958
  char helper[] = "mandos-client-iprouteadddel";
959
  char add_arg[] = "add";
237.25.4 by Teddy Hogeborn
Add plugin for mandos-client to add and delete local routes.
960
  char delete_arg[] = "delete";
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
961
  char debug_flag[] = "--debug";
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
962
  char *pluginhelperdir = getenv("MANDOSPLUGINHELPERDIR");
963
  if(pluginhelperdir == NULL){
964
    if(debug){
965
      fprintf_plus(stderr, "MANDOSPLUGINHELPERDIR environment"
966
		   " variable not set; cannot run helper\n");
967
    }
968
    return false;
969
  }
970
  
971
  char interface[IF_NAMESIZE];
972
  if(if_indextoname((unsigned int)if_index, interface) == NULL){
973
    perror_plus("if_indextoname");
974
    return false;
975
  }
976
  
977
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
978
  if(devnull == -1){
979
    perror_plus("open(\"/dev/null\", O_RDONLY)");
980
    return false;
981
  }
982
  pid_t pid = fork();
983
  if(pid == 0){
984
    /* Child */
985
    /* Raise privileges */
986
    errno = raise_privileges_permanently();
987
    if(errno != 0){
988
      perror_plus("Failed to raise privileges");
989
      /* _exit(EX_NOPERM); */
990
    } else {
991
      /* Set group */
992
      errno = 0;
993
      ret = setgid(0);
994
      if(ret == -1){
995
	perror_plus("setgid");
996
	_exit(EX_NOPERM);
997
      }
998
      /* Reset supplementary groups */
999
      errno = 0;
1000
      ret = setgroups(0, NULL);
1001
      if(ret == -1){
1002
	perror_plus("setgroups");
1003
	_exit(EX_NOPERM);
1004
      }
1005
    }
1006
    ret = dup2(devnull, STDIN_FILENO);
1007
    if(ret == -1){
1008
      perror_plus("dup2(devnull, STDIN_FILENO)");
1009
      _exit(EX_OSERR);
1010
    }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
1011
    ret = close(devnull);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1012
    if(ret == -1){
1013
      perror_plus("close");
1014
      _exit(EX_OSERR);
1015
    }
1016
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1017
    if(ret == -1){
1018
      perror_plus("dup2(STDERR_FILENO, STDOUT_FILENO)");
1019
      _exit(EX_OSERR);
1020
    }
1021
    int helperdir_fd = (int)TEMP_FAILURE_RETRY(open(pluginhelperdir,
1022
						    O_RDONLY
1023
						    | O_DIRECTORY
1024
						    | O_PATH
1025
						    | O_CLOEXEC));
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1026
    if(helperdir_fd == -1){
1027
      perror_plus("open");
1028
      _exit(EX_UNAVAILABLE);
1029
    }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1030
    int helper_fd = (int)TEMP_FAILURE_RETRY(openat(helperdir_fd,
1031
						   helper, O_RDONLY));
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1032
    if(helper_fd == -1){
1033
      perror_plus("openat");
237.7.323 by Teddy Hogeborn
plugin-runner: Minor fix: close helperdir before exiting in fork.
1034
      close(helperdir_fd);
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
1035
      _exit(EX_UNAVAILABLE);
1036
    }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
1037
    close(helperdir_fd);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1038
#ifdef __GNUC__
1039
#pragma GCC diagnostic push
1040
#pragma GCC diagnostic ignored "-Wcast-qual"
1041
#endif
1042
    if(fexecve(helper_fd, (char *const [])
237.25.4 by Teddy Hogeborn
Add plugin for mandos-client to add and delete local routes.
1043
	       { helper, add ? add_arg : delete_arg, (char *)address,
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1044
		   interface, debug ? debug_flag : NULL, NULL },
1045
	       environ) == -1){
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1046
#ifdef __GNUC__
1047
#pragma GCC diagnostic pop
1048
#endif
1049
      perror_plus("fexecve");
1050
      _exit(EXIT_FAILURE);
1051
    }
1052
  }
1053
  if(pid == -1){
1054
    perror_plus("fork");
1055
    return false;
1056
  }
1057
  int status;
1058
  pid_t pret = -1;
1059
  errno = 0;
1060
  do {
1061
    pret = waitpid(pid, &status, 0);
1062
    if(pret == -1 and errno == EINTR and quit_now){
1063
      int errno_raising = 0;
1064
      if((errno = raise_privileges()) != 0){
1065
	errno_raising = errno;
1066
	perror_plus("Failed to raise privileges in order to"
1067
		    " kill helper program");
1068
      }
1069
      if(kill(pid, SIGTERM) == -1){
1070
	perror_plus("kill");
1071
      }
1072
      if((errno_raising == 0) and (errno = lower_privileges()) != 0){
1073
	perror_plus("Failed to lower privileges after killing"
1074
		    " helper program");
1075
      }
1076
      return false;
1077
    }
1078
  } while(pret == -1 and errno == EINTR);
1079
  if(pret == -1){
1080
    perror_plus("waitpid");
1081
    return false;
1082
  }
1083
  if(WIFEXITED(status)){
1084
    if(WEXITSTATUS(status) != 0){
1085
      fprintf_plus(stderr, "Error: iprouteadddel exited"
1086
		   " with status %d\n", WEXITSTATUS(status));
1087
      return false;
1088
    }
1089
    return true;
1090
  }
1091
  if(WIFSIGNALED(status)){
1092
    fprintf_plus(stderr, "Error: iprouteadddel died by"
1093
		 " signal %d\n", WTERMSIG(status));
1094
    return false;
1095
  }
1096
  fprintf_plus(stderr, "Error: iprouteadddel crashed\n");
1097
  return false;
1098
}
1099
1100
__attribute__((nonnull, warn_unused_result))
1101
static bool add_local_route(const char *address,
1102
			    AvahiIfIndex if_index){
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1103
  if(debug){
1104
    fprintf_plus(stderr, "Adding route to %s\n", address);
1105
  }
1106
  return add_delete_local_route(true, address, if_index);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1107
}
1108
1109
__attribute__((nonnull, warn_unused_result))
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1110
static bool delete_local_route(const char *address,
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1111
			       AvahiIfIndex if_index){
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1112
  if(debug){
1113
    fprintf_plus(stderr, "Removing route to %s\n", address);
1114
  }
1115
  return add_delete_local_route(false, address, if_index);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1116
}
1117
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1118
/* Called when a Mandos server is found */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1119
__attribute__((nonnull, warn_unused_result))
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1120
static int start_mandos_communication(const char *ip, in_port_t port,
24.1.9 by Björn Påhlsson
not working midwork...
1121
				      AvahiIfIndex if_index,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1122
				      int af, mandos_context *mc){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1123
  int ret, tcp_sd = -1;
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1124
  ssize_t sret;
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1125
  struct sockaddr_storage to;
13 by Björn Påhlsson
Added following support:
1126
  char *buffer = NULL;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1127
  char *decrypted_buffer = NULL;
13 by Björn Påhlsson
Added following support:
1128
  size_t buffer_length = 0;
1129
  size_t buffer_capacity = 0;
24.1.10 by Björn Påhlsson
merge commit
1130
  size_t written;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1131
  int retval = -1;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1132
  gnutls_session_t session;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1133
  int pf;			/* Protocol family */
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1134
  bool route_added = false;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1135
  
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1136
  errno = 0;
1137
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1138
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1139
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1140
    return -1;
1141
  }
1142
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1143
  switch(af){
1144
  case AF_INET6:
1145
    pf = PF_INET6;
1146
    break;
1147
  case AF_INET:
1148
    pf = PF_INET;
1149
    break;
1150
  default:
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1151
    fprintf_plus(stderr, "Bad address family: %d\n", af);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1152
    errno = EINVAL;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1153
    return -1;
1154
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1155
  
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
1156
  /* If the interface is specified and we have a list of interfaces */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
1157
  if(if_index != AVAHI_IF_UNSPEC and mc->interfaces != NULL){
1158
    /* Check if the interface is one of the interfaces we are using */
1159
    bool match = false;
1160
    {
1161
      char *interface = NULL;
237.7.438 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
1162
      while((interface = argz_next(mc->interfaces,
1163
				   mc->interfaces_size,
1164
				   interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
1165
	if(if_nametoindex(interface) == (unsigned int)if_index){
1166
	  match = true;
1167
	  break;
1168
	}
1169
      }
1170
    }
1171
    if(not match){
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
1172
      /* This interface does not match any in the list, so we don't
1173
	 connect to the server */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
1174
      if(debug){
1175
	char interface[IF_NAMESIZE];
1176
	if(if_indextoname((unsigned int)if_index, interface) == NULL){
1177
	  perror_plus("if_indextoname");
1178
	} else {
1179
	  fprintf_plus(stderr, "Skipping server on non-used interface"
1180
		       " \"%s\"\n",
1181
		       if_indextoname((unsigned int)if_index,
1182
				      interface));
1183
	}
1184
      }
1185
      return -1;
1186
    }
1187
  }
1188
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1189
  ret = init_gnutls_session(&session, mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1190
  if(ret != 0){
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1191
    return -1;
1192
  }
1193
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1194
  if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1195
    fprintf_plus(stderr, "Setting up a TCP connection to %s, port %"
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1196
		 PRIuMAX "\n", ip, (uintmax_t)port);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1197
  }
13 by Björn Påhlsson
Added following support:
1198
  
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1199
  tcp_sd = socket(pf, SOCK_STREAM | SOCK_CLOEXEC, 0);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1200
  if(tcp_sd < 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1201
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1202
    perror_plus("socket");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1203
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1204
    goto mandos_end;
1205
  }
1206
  
1207
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1208
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1209
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
1210
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1211
  
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1212
  if(af == AF_INET6){
237.7.321 by Teddy Hogeborn
mandos-client: Don't use memset().
1213
    struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&to;
1214
    *to6 = (struct sockaddr_in6){ .sin6_family = (sa_family_t)af };
1215
    ret = inet_pton(af, ip, &to6->sin6_addr);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1216
  } else {			/* IPv4 */
237.7.321 by Teddy Hogeborn
mandos-client: Don't use memset().
1217
    struct sockaddr_in *to4 = (struct sockaddr_in *)&to;
1218
    *to4 = (struct sockaddr_in){ .sin_family = (sa_family_t)af };
1219
    ret = inet_pton(af, ip, &to4->sin_addr);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1220
  }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1221
  if(ret < 0 ){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1222
    int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1223
    perror_plus("inet_pton");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1224
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1225
    goto mandos_end;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1226
  }
13 by Björn Påhlsson
Added following support:
1227
  if(ret == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1228
    int e = errno;
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1229
    fprintf_plus(stderr, "Bad address: %s\n", ip);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1230
    errno = e;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1231
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
1232
  }
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1233
  if(af == AF_INET6){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1234
    ((struct sockaddr_in6 *)&to)->sin6_port = htons(port);
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1235
    if(IN6_IS_ADDR_LINKLOCAL
1236
       (&((struct sockaddr_in6 *)&to)->sin6_addr)){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1237
      if(if_index == AVAHI_IF_UNSPEC){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1238
	fprintf_plus(stderr, "An IPv6 link-local address is"
1239
		     " incomplete without a network interface\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1240
	errno = EINVAL;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1241
	goto mandos_end;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1242
      }
1243
      /* Set the network interface number as scope */
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1244
      ((struct sockaddr_in6 *)&to)->sin6_scope_id = (uint32_t)if_index;
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1245
    }
1246
  } else {
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1247
    ((struct sockaddr_in *)&to)->sin_port = htons(port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1248
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1249
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1250
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1251
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1252
    goto mandos_end;
1253
  }
1254
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1255
  if(debug){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1256
    if(af == AF_INET6 and if_index != AVAHI_IF_UNSPEC){
1257
      char interface[IF_NAMESIZE];
1258
      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.
1259
	perror_plus("if_indextoname");
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1260
      } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1261
	fprintf_plus(stderr, "Connection to: %s%%%s, port %" PRIuMAX
1262
		     "\n", ip, interface, (uintmax_t)port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1263
      }
1264
    } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1265
      fprintf_plus(stderr, "Connection to: %s, port %" PRIuMAX "\n",
1266
		   ip, (uintmax_t)port);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1267
    }
1268
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
1269
		 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
1270
    if(af == AF_INET6){
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1271
      ret = getnameinfo((struct sockaddr *)&to,
1272
			sizeof(struct sockaddr_in6),
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1273
			addrstr, sizeof(addrstr), NULL, 0,
1274
			NI_NUMERICHOST);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1275
    } else {
237.7.217 by Teddy Hogeborn
Use "struct sockaddr_storage" instead of a union in mandos-client.
1276
      ret = getnameinfo((struct sockaddr *)&to,
1277
			sizeof(struct sockaddr_in),
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1278
			addrstr, sizeof(addrstr), NULL, 0,
1279
			NI_NUMERICHOST);
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1280
    }
237.7.215 by Teddy Hogeborn
Use getnameinfo() instead of inet_ntop() in mandos-client.
1281
    if(ret == EAI_SYSTEM){
1282
      perror_plus("getnameinfo");
1283
    } else if(ret != 0) {
1284
      fprintf_plus(stderr, "getnameinfo: %s", gai_strerror(ret));
1285
    } else if(strcmp(addrstr, ip) != 0){
1286
      fprintf_plus(stderr, "Canonical address form: %s\n", addrstr);
37 by Teddy Hogeborn
Non-tested commit for merge purposes.
1287
    }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1288
  }
13 by Björn Påhlsson
Added following support:
1289
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1290
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1291
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1292
    goto mandos_end;
1293
  }
1294
  
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1295
  while(true){
1296
    if(af == AF_INET6){
1297
      ret = connect(tcp_sd, (struct sockaddr *)&to,
1298
		    sizeof(struct sockaddr_in6));
1299
    } else {
1300
      ret = connect(tcp_sd, (struct sockaddr *)&to, /* IPv4 */
1301
		    sizeof(struct sockaddr_in));
1302
    }
1303
    if(ret < 0){
237.7.338 by Teddy Hogeborn
Bug fix: Add local route also when host is unreachable.
1304
      if(((errno == ENETUNREACH) or (errno == EHOSTUNREACH))
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1305
	 and if_index != AVAHI_IF_UNSPEC
1306
	 and connect_to == NULL
1307
	 and not route_added and
1308
	 ((af == AF_INET6 and not
1309
	   IN6_IS_ADDR_LINKLOCAL(&(((struct sockaddr_in6 *)
1310
				    &to)->sin6_addr)))
1311
	  or (af == AF_INET and
1312
	      /* Not a a IPv4LL address */
1313
	      (ntohl(((struct sockaddr_in *)&to)->sin_addr.s_addr)
1314
	       & 0xFFFF0000L) != 0xA9FE0000L))){
1315
	/* Work around Avahi bug - Avahi does not announce link-local
1316
	   addresses if it has a global address, so local hosts with
1317
	   *only* a link-local address (e.g. Mandos clients) cannot
1318
	   connect to a Mandos server announced by Avahi on a server
1319
	   host with a global address.  Work around this by retrying
1320
	   with an explicit route added with the server's address.
1321
	   
1322
	   Avahi bug reference:
237.7.416 by Teddy Hogeborn
Change all http:// URLs to https:// wherever possible.
1323
	   https://lists.freedesktop.org/archives/avahi/2010-February/001833.html
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1324
	   https://bugs.debian.org/587961
1325
	*/
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1326
	if(debug){
1327
	  fprintf_plus(stderr, "Mandos server unreachable, trying"
1328
		       " direct route\n");
1329
	}
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1330
	int e = errno;
1331
	route_added = add_local_route(ip, if_index);
1332
	if(route_added){
1333
	  continue;
1334
	}
1335
	errno = e;
1336
      }
1337
      if(errno != ECONNREFUSED or debug){
1338
	int e = errno;
1339
	perror_plus("connect");
1340
	errno = e;
1341
      }
1342
      goto mandos_end;
1343
    }
1344
    
1345
    if(quit_now){
1346
      errno = EINTR;
1347
      goto mandos_end;
1348
    }
1349
    break;
13 by Björn Påhlsson
Added following support:
1350
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1351
  
24.1.12 by Björn Påhlsson
merge +
1352
  const char *out = mandos_protocol_version;
24.1.10 by Björn Påhlsson
merge commit
1353
  written = 0;
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1354
  while(true){
24.1.10 by Björn Påhlsson
merge commit
1355
    size_t out_size = strlen(out);
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1356
    ret = (int)TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1357
					out_size - written));
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1358
    if(ret == -1){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1359
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1360
      perror_plus("write");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1361
      errno = e;
24.1.12 by Björn Påhlsson
merge +
1362
      goto mandos_end;
24.1.10 by Björn Påhlsson
merge commit
1363
    }
24.1.12 by Björn Påhlsson
merge +
1364
    written += (size_t)ret;
24.1.10 by Björn Påhlsson
merge commit
1365
    if(written < out_size){
1366
      continue;
1367
    } else {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1368
      if(out == mandos_protocol_version){
24.1.10 by Björn Påhlsson
merge commit
1369
	written = 0;
1370
	out = "\r\n";
1371
      } else {
1372
	break;
1373
      }
1374
    }
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1375
  
1376
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1377
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1378
      goto mandos_end;
1379
    }
24.1.10 by Björn Påhlsson
merge commit
1380
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1381
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1382
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1383
    fprintf_plus(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
1384
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1385
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1386
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1387
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1388
    goto mandos_end;
1389
  }
1390
  
237.7.136 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Eliminate
1391
  /* This casting via intptr_t is to eliminate warning about casting
1392
     an int to a pointer type.  This is exactly how the GnuTLS Guile
1393
     function "set-session-transport-fd!" does it. */
1394
  gnutls_transport_set_ptr(session,
1395
			   (gnutls_transport_ptr_t)(intptr_t)tcp_sd);
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1396
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1397
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1398
    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1399
    goto mandos_end;
1400
  }
1401
  
237.2.126 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
1402
  do {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1403
    ret = gnutls_handshake(session);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1404
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1405
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1406
      goto mandos_end;
1407
    }
24.1.29 by Björn Påhlsson
Added more header file comments
1408
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
13 by Björn Påhlsson
Added following support:
1409
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1410
  if(ret != GNUTLS_E_SUCCESS){
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
1411
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1412
      fprintf_plus(stderr, "*** GnuTLS Handshake failed ***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1413
      gnutls_perror(ret);
25 by Teddy Hogeborn
* mandos-clients.conf ([DEFAULT]): New section.
1414
    }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1415
    errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1416
    goto mandos_end;
13 by Björn Påhlsson
Added following support:
1417
  }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1418
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1419
  /* Read OpenPGP packet that contains the wanted password */
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1420
  
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1421
  if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1422
    fprintf_plus(stderr, "Retrieving OpenPGP encrypted password from"
1423
		 " %s\n", ip);
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1424
  }
143 by Teddy Hogeborn
* Makefile (mandos.8): Add dependency on "overview.xml" and
1425
  
13 by Björn Påhlsson
Added following support:
1426
  while(true){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1427
    
1428
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1429
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1430
      goto mandos_end;
1431
    }
1432
    
24.1.132 by Björn Påhlsson
Fixed a bug in fallback handling
1433
    buffer_capacity = incbuffer(&buffer, buffer_length,
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1434
				buffer_capacity);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1435
    if(buffer_capacity == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1436
      int e = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1437
      perror_plus("incbuffer");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1438
      errno = e;
24.1.12 by Björn Påhlsson
merge +
1439
      goto mandos_end;
13 by Björn Påhlsson
Added following support:
1440
    }
1441
    
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1442
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1443
      errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1444
      goto mandos_end;
1445
    }
1446
    
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1447
    sret = gnutls_record_recv(session, buffer+buffer_length,
1448
			      BUFFER_SIZE);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1449
    if(sret == 0){
13 by Björn Påhlsson
Added following support:
1450
      break;
1451
    }
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1452
    if(sret < 0){
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1453
      switch(sret){
13 by Björn Påhlsson
Added following support:
1454
      case GNUTLS_E_INTERRUPTED:
1455
      case GNUTLS_E_AGAIN:
1456
	break;
1457
      case GNUTLS_E_REHANDSHAKE:
237.2.126 by Teddy Hogeborn
* plugin-runner.c: Minor stylistic changes.
1458
	do {
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1459
	  ret = gnutls_handshake(session);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1460
	  
1461
	  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1462
	    errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1463
	    goto mandos_end;
1464
	  }
24.1.29 by Björn Påhlsson
Added more header file comments
1465
	} while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1466
	if(ret < 0){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1467
	  fprintf_plus(stderr, "*** GnuTLS Re-handshake failed "
1468
		       "***\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1469
	  gnutls_perror(ret);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1470
	  errno = EPROTO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1471
	  goto mandos_end;
13 by Björn Påhlsson
Added following support:
1472
	}
1473
	break;
1474
      default:
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1475
	fprintf_plus(stderr, "Unknown error while reading data from"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1476
		     " encrypted session with Mandos server\n");
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1477
	gnutls_bye(session, GNUTLS_SHUT_RDWR);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1478
	errno = EIO;
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1479
	goto mandos_end;
13 by Björn Påhlsson
Added following support:
1480
      }
1481
    } else {
237.3.2 by Mooie
Fixed warnings in the 64 bit build. Added explicit cast to int for
1482
      buffer_length += (size_t) sret;
13 by Björn Påhlsson
Added following support:
1483
    }
1484
  }
15.1.1 by Björn Påhlsson
Added debugg support in form off --debug and --debug=mandosclient
1485
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1486
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1487
    fprintf_plus(stderr, "Closing TLS session\n");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1488
  }
1489
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1490
  if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1491
    errno = EINTR;
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
1492
    goto mandos_end;
1493
  }
1494
  
1495
  do {
1496
    ret = gnutls_bye(session, GNUTLS_SHUT_RDWR);
1497
    if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1498
      errno = EINTR;
237.2.134 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Always fail and
1499
      goto mandos_end;
1500
    }
1501
  } while(ret == GNUTLS_E_AGAIN or ret == GNUTLS_E_INTERRUPTED);
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1502
  
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1503
  if(buffer_length > 0){
237.2.125 by Teddy Hogeborn
* plugin-runner.c (getplugin, add_environment, main): Handle EINTR
1504
    ssize_t decrypted_buffer_size;
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1505
    decrypted_buffer_size = pgp_packet_decrypt(buffer, buffer_length,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1506
					       &decrypted_buffer, mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1507
    if(decrypted_buffer_size >= 0){
237.2.124 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gpgme): Move variable "ret" into the
1508
      
237.7.414 by Teddy Hogeborn
mandos-client: Bug fix: flush stdout to detect write errors.
1509
      clearerr(stdout);
24.1.10 by Björn Påhlsson
merge commit
1510
      written = 0;
28 by Teddy Hogeborn
* server.conf: New file.
1511
      while(written < (size_t) decrypted_buffer_size){
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1512
	if(quit_now){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1513
	  errno = EINTR;
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1514
	  goto mandos_end;
1515
	}
1516
	
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1517
	ret = (int)fwrite(decrypted_buffer + written, 1,
1518
			  (size_t)decrypted_buffer_size - written,
1519
			  stdout);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1520
	if(ret == 0 and ferror(stdout)){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1521
	  int e = errno;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1522
	  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1523
	    fprintf_plus(stderr, "Error writing encrypted data: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1524
			 strerror(errno));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1525
	  }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1526
	  errno = e;
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1527
	  goto mandos_end;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1528
	}
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1529
	written += (size_t)ret;
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1530
      }
237.7.414 by Teddy Hogeborn
mandos-client: Bug fix: flush stdout to detect write errors.
1531
      ret = fflush(stdout);
1532
      if(ret != 0){
1533
	int e = errno;
1534
	if(debug){
1535
	  fprintf_plus(stderr, "Error writing encrypted data: %s\n",
1536
		       strerror(errno));
1537
	}
1538
	errno = e;
1539
	goto mandos_end;
1540
      }
237.2.135 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Bug fix:
1541
      retval = 0;
13 by Björn Påhlsson
Added following support:
1542
    }
1543
  }
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1544
  
1545
  /* Shutdown procedure */
1546
  
1547
 mandos_end:
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1548
  {
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1549
    if(route_added){
237.25.6 by Teddy Hogeborn
Fix minor bugs and typos and add some more debug output.
1550
      if(not delete_local_route(ip, if_index)){
1551
	fprintf_plus(stderr, "Failed to delete local route to %s on"
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
1552
		     " interface %d", ip, if_index);
1553
      }
1554
    }
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1555
    int e = errno;
1556
    free(decrypted_buffer);
1557
    free(buffer);
1558
    if(tcp_sd >= 0){
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
1559
      ret = close(tcp_sd);
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1560
    }
1561
    if(ret == -1){
1562
      if(e == 0){
1563
	e = errno;
1564
      }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1565
      perror_plus("close");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1566
    }
1567
    gnutls_deinit(session);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1568
    errno = e;
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1569
    if(quit_now){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1570
      errno = EINTR;
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
1571
      retval = -1;
1572
    }
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1573
  }
13 by Björn Påhlsson
Added following support:
1574
  return retval;
1575
}
1576
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
1577
static void resolve_callback(AvahiSServiceResolver *r,
1578
			     AvahiIfIndex interface,
237.2.67 by Teddy Hogeborn
Four new interrelated features:
1579
			     AvahiProtocol proto,
39 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Renamed variables.
1580
			     AvahiResolverEvent event,
1581
			     const char *name,
1582
			     const char *type,
1583
			     const char *domain,
1584
			     const char *host_name,
1585
			     const AvahiAddress *address,
1586
			     uint16_t port,
1587
			     AVAHI_GCC_UNUSED AvahiStringList *txt,
1588
			     AVAHI_GCC_UNUSED AvahiLookupResultFlags
1589
			     flags,
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1590
			     void *mc){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1591
  if(r == NULL){
1592
    return;
1593
  }
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1594
  
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1595
  /* Called whenever a service has been resolved successfully or
1596
     timed out */
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1597
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1598
  if(quit_now){
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
1599
    avahi_s_service_resolver_free(r);
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
1600
    return;
1601
  }
1602
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1603
  switch(event){
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1604
  default:
1605
  case AVAHI_RESOLVER_FAILURE:
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1606
    fprintf_plus(stderr, "(Avahi Resolver) Failed to resolve service "
1607
		 "'%s' of type '%s' in domain '%s': %s\n", name, type,
1608
		 domain,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1609
		 avahi_strerror(avahi_server_errno
1610
				(((mandos_context*)mc)->server)));
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1611
    break;
22 by Teddy Hogeborn
* plugins.d/mandosclient.c (pgp_packet_decrypt): Cast "0" argument to
1612
    
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1613
  case AVAHI_RESOLVER_FOUND:
1614
    {
1615
      char ip[AVAHI_ADDRESS_STR_MAX];
1616
      avahi_address_snprint(ip, sizeof(ip), address);
1617
      if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1618
	fprintf_plus(stderr, "Mandos server \"%s\" found on %s (%s, %"
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1619
		     PRIdMAX ") on port %" PRIu16 "\n", name,
1620
		     host_name, ip, (intmax_t)interface, port);
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1621
      }
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1622
      int ret = start_mandos_communication(ip, (in_port_t)port,
1623
					   interface,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1624
					   avahi_proto_to_af(proto),
1625
					   mc);
237.2.29 by Teddy Hogeborn
* plugin-runner.c: Only space changes.
1626
      if(ret == 0){
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1627
	avahi_simple_poll_quit(simple_poll);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1628
      } else {
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1629
	if(not add_server(ip, (in_port_t)port, interface,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1630
			  avahi_proto_to_af(proto),
1631
			  &((mandos_context*)mc)->current_server)){
237.11.27 by teddy at bsnet
* plugins.d/mandos-client.c (add_server): Return bool; all callers
1632
	  fprintf_plus(stderr, "Failed to add server \"%s\" to server"
1633
		       " list\n", name);
1634
	}
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1635
      }
13 by Björn Påhlsson
Added following support:
1636
    }
21 by Teddy Hogeborn
* Makefile (CFLAGS): Changed to use $(WARN), $(DEBUG), $(COVERAGE) and
1637
  }
1638
  avahi_s_service_resolver_free(r);
13 by Björn Påhlsson
Added following support:
1639
}
1640
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1641
static void browse_callback(AvahiSServiceBrowser *b,
1642
			    AvahiIfIndex interface,
1643
			    AvahiProtocol protocol,
1644
			    AvahiBrowserEvent event,
1645
			    const char *name,
1646
			    const char *type,
1647
			    const char *domain,
1648
			    AVAHI_GCC_UNUSED AvahiLookupResultFlags
1649
			    flags,
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1650
			    void *mc){
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
1651
  if(b == NULL){
1652
    return;
1653
  }
24.1.9 by Björn Påhlsson
not working midwork...
1654
  
1655
  /* Called whenever a new services becomes available on the LAN or
1656
     is removed from the LAN */
1657
  
237.2.121 by Teddy Hogeborn
* plugins.d/mandos-client.c (start_mandos_communication): Check
1658
  if(quit_now){
1659
    return;
1660
  }
1661
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
1662
  switch(event){
24.1.9 by Björn Påhlsson
not working midwork...
1663
  default:
1664
  case AVAHI_BROWSER_FAILURE:
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1665
    
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1666
    fprintf_plus(stderr, "(Avahi browser) %s\n",
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1667
		 avahi_strerror(avahi_server_errno
1668
				(((mandos_context*)mc)->server)));
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1669
    avahi_simple_poll_quit(simple_poll);
24.1.9 by Björn Påhlsson
not working midwork...
1670
    return;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1671
    
24.1.9 by Björn Påhlsson
not working midwork...
1672
  case AVAHI_BROWSER_NEW:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1673
    /* We ignore the returned Avahi resolver object. In the callback
1674
       function we free it. If the Avahi server is terminated before
1675
       the callback function is called the Avahi server will free the
1676
       resolver for us. */
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1677
    
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1678
    if(avahi_s_service_resolver_new(((mandos_context*)mc)->server,
1679
				    interface, protocol, name, type,
1680
				    domain, protocol, 0,
1681
				    resolve_callback, mc) == NULL)
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1682
      fprintf_plus(stderr, "Avahi: Failed to resolve service '%s':"
1683
		   " %s\n", name,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1684
		   avahi_strerror(avahi_server_errno
1685
				  (((mandos_context*)mc)->server)));
24.1.9 by Björn Påhlsson
not working midwork...
1686
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1687
    
24.1.9 by Björn Påhlsson
not working midwork...
1688
  case AVAHI_BROWSER_REMOVE:
1689
    break;
38 by Teddy Hogeborn
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
1690
    
24.1.9 by Björn Påhlsson
not working midwork...
1691
  case AVAHI_BROWSER_ALL_FOR_NOW:
1692
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1693
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1694
      fprintf_plus(stderr, "No Mandos server found, still"
1695
		   " searching...\n");
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
1696
    }
24.1.9 by Björn Påhlsson
not working midwork...
1697
    break;
1698
  }
13 by Björn Påhlsson
Added following support:
1699
}
1700
237.7.33 by Teddy Hogeborn
Merge from Björn.
1701
/* Signal handler that stops main loop after SIGTERM */
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1702
static void handle_sigterm(int sig){
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1703
  if(quit_now){
1704
    return;
1705
  }
1706
  quit_now = 1;
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
1707
  signal_received = sig;
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1708
  int old_errno = errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1709
  /* set main loop to exit */
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
1710
  if(simple_poll != NULL){
1711
    avahi_simple_poll_quit(simple_poll);
237.2.71 by Teddy Hogeborn
* plugin-runner.c: Comment change.
1712
  }
24.1.134 by Björn Påhlsson
plugin-runner: Added support for empty string arguments
1713
  errno = old_errno;
1714
}
1715
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1716
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1717
bool get_flags(const char *ifname, struct ifreq *ifr){
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1718
  int ret;
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1719
  int old_errno;
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1720
  
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1721
  int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1722
  if(s < 0){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1723
    old_errno = errno;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1724
    perror_plus("socket");
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1725
    errno = old_errno;
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1726
    return false;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1727
  }
237.7.346 by Teddy Hogeborn
plugins.d/mandos-client.c (get_flags): Use strncpy(), not strcpy().
1728
  strncpy(ifr->ifr_name, ifname, IF_NAMESIZE);
1729
  ifr->ifr_name[IF_NAMESIZE-1] = '\0'; /* NUL terminate */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1730
  ret = ioctl(s, SIOCGIFFLAGS, ifr);
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1731
  if(ret == -1){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1732
    if(debug){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1733
      old_errno = errno;
237.15.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1734
      perror_plus("ioctl SIOCGIFFLAGS");
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
1735
      errno = old_errno;
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1736
    }
237.7.489 by Teddy Hogeborn
Check return values from newly added close() calls
1737
    if((close(s) == -1) and debug){
1738
      old_errno = errno;
1739
      perror_plus("close");
1740
      errno = old_errno;
1741
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1742
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1743
  }
237.7.489 by Teddy Hogeborn
Check return values from newly added close() calls
1744
  if((close(s) == -1) and debug){
1745
    old_errno = errno;
1746
    perror_plus("close");
1747
    errno = old_errno;
1748
  }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1749
  return true;
1750
}
1751
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1752
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1753
bool good_flags(const char *ifname, const struct ifreq *ifr){
1754
  
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1755
  /* Reject the loopback device */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1756
  if(ifr->ifr_flags & IFF_LOOPBACK){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1757
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1758
      fprintf_plus(stderr, "Rejecting loopback interface \"%s\"\n",
1759
		   ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1760
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1761
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1762
  }
1763
  /* Accept point-to-point devices only if connect_to is specified */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1764
  if(connect_to != NULL and (ifr->ifr_flags & IFF_POINTOPOINT)){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1765
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1766
      fprintf_plus(stderr, "Accepting point-to-point interface"
1767
		   " \"%s\"\n", ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1768
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1769
    return true;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1770
  }
1771
  /* Otherwise, reject non-broadcast-capable devices */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1772
  if(not (ifr->ifr_flags & IFF_BROADCAST)){
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1773
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1774
      fprintf_plus(stderr, "Rejecting non-broadcast interface"
1775
		   " \"%s\"\n", ifname);
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1776
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1777
    return false;
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1778
  }
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1779
  /* Reject non-ARP interfaces (including dummy interfaces) */
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1780
  if(ifr->ifr_flags & IFF_NOARP){
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1781
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1782
      fprintf_plus(stderr, "Rejecting non-ARP interface \"%s\"\n",
1783
		   ifname);
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1784
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1785
    return false;
237.7.29 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Reject non-ARP
1786
  }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1787
  
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1788
  /* Accept this device */
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1789
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1790
    fprintf_plus(stderr, "Interface \"%s\" is good\n", ifname);
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1791
  }
1792
  return true;
1793
}
1794
1795
/* 
1796
 * This function determines if a directory entry in /sys/class/net
1797
 * corresponds to an acceptable network device.
1798
 * (This function is passed to scandir(3) as a filter function.)
1799
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1800
__attribute__((nonnull, warn_unused_result))
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1801
int good_interface(const struct dirent *if_entry){
1802
  if(if_entry->d_name[0] == '.'){
1803
    return 0;
1804
  }
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1805
  
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1806
  struct ifreq ifr;
1807
  if(not get_flags(if_entry->d_name, &ifr)){
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1808
    if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1809
      fprintf_plus(stderr, "Failed to get flags for interface "
1810
		   "\"%s\"\n", if_entry->d_name);
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1811
    }
237.15.2 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Use SIOCGIFFLAGS instead
1812
    return 0;
1813
  }
1814
  
1815
  if(not good_flags(if_entry->d_name, &ifr)){
1816
    return 0;
269.1.2 by teddy at bsnet
* plugins.d/mandos-client.c: Added debug output.
1817
  }
269.1.1 by teddy at bsnet
* plugins.d/mandos-client.c: An empty interface name now means to
1818
  return 1;
1819
}
1820
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1821
/* 
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1822
 * This function determines if a network interface is up.
1823
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1824
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1825
bool interface_is_up(const char *interface){
1826
  struct ifreq ifr;
1827
  if(not get_flags(interface, &ifr)){
1828
    if(debug){
1829
      fprintf_plus(stderr, "Failed to get flags for interface "
1830
		   "\"%s\"\n", interface);
1831
    }
1832
    return false;
1833
  }
1834
  
1835
  return (bool)(ifr.ifr_flags & IFF_UP);
1836
}
1837
1838
/* 
1839
 * This function determines if a network interface is running
1840
 */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1841
__attribute__((nonnull, warn_unused_result))
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
1842
bool interface_is_running(const char *interface){
1843
  struct ifreq ifr;
1844
  if(not get_flags(interface, &ifr)){
1845
    if(debug){
1846
      fprintf_plus(stderr, "Failed to get flags for interface "
1847
		   "\"%s\"\n", interface);
1848
    }
1849
    return false;
1850
  }
1851
  
1852
  return (bool)(ifr.ifr_flags & IFF_RUNNING);
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1853
}
1854
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1855
__attribute__((nonnull, pure, warn_unused_result))
24.1.172 by Björn Påhlsson
using scandir instead of readdir
1856
int notdotentries(const struct dirent *direntry){
1857
  /* Skip "." and ".." */
1858
  if(direntry->d_name[0] == '.'
1859
     and (direntry->d_name[1] == '\0'
1860
	  or (direntry->d_name[1] == '.'
1861
	      and direntry->d_name[2] == '\0'))){
1862
    return 0;
1863
  }
1864
  return 1;
1865
}
1866
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1867
/* Is this directory entry a runnable program? */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1868
__attribute__((nonnull, warn_unused_result))
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1869
int runnable_hook(const struct dirent *direntry){
1870
  int ret;
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1871
  size_t sret;
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1872
  struct stat st;
1873
  
1874
  if((direntry->d_name)[0] == '\0'){
1875
    /* Empty name? */
1876
    return 0;
1877
  }
1878
  
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1879
  sret = strspn(direntry->d_name, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1880
		"abcdefghijklmnopqrstuvwxyz"
1881
		"0123456789"
237.7.236 by Teddy Hogeborn
Minor bug fix in mandos-client: Allow periods in network hook names.
1882
		"_.-");
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1883
  if((direntry->d_name)[sret] != '\0'){
1884
    /* Contains non-allowed characters */
1885
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1886
      fprintf_plus(stderr, "Ignoring hook \"%s\" with bad name\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1887
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1888
    }
1889
    return 0;
1890
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1891
  
237.7.241 by Teddy Hogeborn
Make mandos-client use fstatat().
1892
  ret = fstatat(hookdir_fd, direntry->d_name, &st, 0);
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1893
  if(ret == -1){
1894
    if(debug){
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1895
      perror_plus("Could not stat hook");
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1896
    }
1897
    return 0;
1898
  }
237.16.1 by teddy at bsnet
* plugins.d/mandos-client.c (good_interface): Add error message.
1899
  if(not (S_ISREG(st.st_mode))){
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1900
    /* Not a regular file */
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1901
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1902
      fprintf_plus(stderr, "Ignoring hook \"%s\" - not a file\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1903
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1904
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1905
    return 0;
1906
  }
1907
  if(not (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))){
1908
    /* Not executable */
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1909
    if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
1910
      fprintf_plus(stderr, "Ignoring hook \"%s\" - not executable\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1911
		   direntry->d_name);
237.16.6 by teddy at bsnet
* plugins.d/mandos-client.c: Some white space fixes.
1912
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1913
    return 0;
1914
  }
237.16.12 by Teddy Hogeborn
* plugins.d/mandos-client.c (runnable_hook): Add debug output.
1915
  if(debug){
1916
    fprintf_plus(stderr, "Hook \"%s\" is acceptable\n",
1917
		 direntry->d_name);
1918
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
1919
  return 1;
1920
}
1921
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1922
__attribute__((nonnull, warn_unused_result))
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1923
int avahi_loop_with_timeout(AvahiSimplePoll *s, int retry_interval,
1924
			    mandos_context *mc){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1925
  int ret;
1926
  struct timespec now;
1927
  struct timespec waited_time;
1928
  intmax_t block_time;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1929
  
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1930
  while(true){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1931
    if(mc->current_server == NULL){
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1932
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1933
	fprintf_plus(stderr, "Wait until first server is found."
1934
		     " No timeout!\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1935
      }
1936
      ret = avahi_simple_poll_iterate(s, -1);
1937
    } else {
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1938
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1939
	fprintf_plus(stderr, "Check current_server if we should run"
1940
		     " it, or wait\n");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1941
      }
1942
      /* the current time */
1943
      ret = clock_gettime(CLOCK_MONOTONIC, &now);
1944
      if(ret == -1){
1945
	perror_plus("clock_gettime");
1946
	return -1;
1947
      }
1948
      /* Calculating in ms how long time between now and server
1949
	 who we visted longest time ago. Now - last seen.  */
237.7.33 by Teddy Hogeborn
Merge from Björn.
1950
      waited_time.tv_sec = (now.tv_sec
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1951
			    - mc->current_server->last_seen.tv_sec);
237.7.33 by Teddy Hogeborn
Merge from Björn.
1952
      waited_time.tv_nsec = (now.tv_nsec
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1953
			     - mc->current_server->last_seen.tv_nsec);
237.7.33 by Teddy Hogeborn
Merge from Björn.
1954
      /* total time is 10s/10,000ms.
1955
	 Converting to s from ms by dividing by 1,000,
1956
	 and ns to ms by dividing by 1,000,000. */
1957
      block_time = ((retry_interval
1958
		     - ((intmax_t)waited_time.tv_sec * 1000))
1959
		    - ((intmax_t)waited_time.tv_nsec / 1000000));
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1960
      
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1961
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
1962
	fprintf_plus(stderr, "Blocking for %" PRIdMAX " ms\n",
1963
		     block_time);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1964
      }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
1965
      
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1966
      if(block_time <= 0){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1967
	ret = start_mandos_communication(mc->current_server->ip,
1968
					 mc->current_server->port,
1969
					 mc->current_server->if_index,
1970
					 mc->current_server->af, mc);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1971
	if(ret == 0){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1972
	  avahi_simple_poll_quit(s);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1973
	  return 0;
1974
	}
237.7.33 by Teddy Hogeborn
Merge from Björn.
1975
	ret = clock_gettime(CLOCK_MONOTONIC,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1976
			    &mc->current_server->last_seen);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1977
	if(ret == -1){
1978
	  perror_plus("clock_gettime");
1979
	  return -1;
1980
	}
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
1981
	mc->current_server = mc->current_server->next;
237.7.33 by Teddy Hogeborn
Merge from Björn.
1982
	block_time = 0; 	/* Call avahi to find new Mandos
1983
				   servers, but don't block */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1984
      }
1985
      
1986
      ret = avahi_simple_poll_iterate(s, (int)block_time);
1987
    }
1988
    if(ret != 0){
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
1989
      if(ret > 0 or errno != EINTR){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
1990
	return (ret != 1) ? ret : 0;
1991
      }
1992
    }
1993
  }
1994
}
1995
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
1996
__attribute__((nonnull))
1997
void run_network_hooks(const char *mode, const char *interface,
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
1998
		       const float delay){
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
1999
  struct dirent **direntries = NULL;
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2000
  if(hookdir_fd == -1){
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2001
    hookdir_fd = open(hookdir, O_RDONLY | O_DIRECTORY | O_PATH
2002
		      | O_CLOEXEC);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2003
    if(hookdir_fd == -1){
2004
      if(errno == ENOENT){
2005
	if(debug){
2006
	  fprintf_plus(stderr, "Network hook directory \"%s\" not"
2007
		       " found\n", hookdir);
2008
	}
2009
      } else {
2010
	perror_plus("open");
2011
      }
2012
      return;
2013
    }
2014
  }
237.7.483 by Teddy Hogeborn
Client: Bug fix: Possible memory leak if failing to open /dev/null
2015
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
2016
  if(devnull == -1){
2017
    perror_plus("open(\"/dev/null\", O_RDONLY)");
2018
    return;
2019
  }
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2020
  int numhooks = scandirat(hookdir_fd, ".", &direntries,
2021
			   runnable_hook, alphasort);
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2022
  if(numhooks == -1){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2023
    perror_plus("scandir");
237.7.483 by Teddy Hogeborn
Client: Bug fix: Possible memory leak if failing to open /dev/null
2024
    close(devnull);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2025
    return;
2026
  }
2027
  struct dirent *direntry;
2028
  int ret;
2029
  for(int i = 0; i < numhooks; i++){
2030
    direntry = direntries[i];
2031
    if(debug){
2032
      fprintf_plus(stderr, "Running network hook \"%s\"\n",
2033
		   direntry->d_name);
2034
    }
2035
    pid_t hook_pid = fork();
2036
    if(hook_pid == 0){
2037
      /* Child */
2038
      /* Raise privileges */
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2039
      errno = raise_privileges_permanently();
2040
      if(errno != 0){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2041
	perror_plus("Failed to raise privileges");
2042
	_exit(EX_NOPERM);
2043
      }
2044
      /* Set group */
2045
      errno = 0;
2046
      ret = setgid(0);
2047
      if(ret == -1){
2048
	perror_plus("setgid");
2049
	_exit(EX_NOPERM);
2050
      }
2051
      /* Reset supplementary groups */
2052
      errno = 0;
2053
      ret = setgroups(0, NULL);
2054
      if(ret == -1){
2055
	perror_plus("setgroups");
2056
	_exit(EX_NOPERM);
2057
      }
2058
      ret = setenv("MANDOSNETHOOKDIR", hookdir, 1);
2059
      if(ret == -1){
2060
	perror_plus("setenv");
2061
	_exit(EX_OSERR);
2062
      }
2063
      ret = setenv("DEVICE", interface, 1);
2064
      if(ret == -1){
2065
	perror_plus("setenv");
2066
	_exit(EX_OSERR);
2067
      }
2068
      ret = setenv("VERBOSITY", debug ? "1" : "0", 1);
2069
      if(ret == -1){
2070
	perror_plus("setenv");
2071
	_exit(EX_OSERR);
2072
      }
2073
      ret = setenv("MODE", mode, 1);
2074
      if(ret == -1){
2075
	perror_plus("setenv");
2076
	_exit(EX_OSERR);
2077
      }
2078
      char *delaystring;
2079
      ret = asprintf(&delaystring, "%f", (double)delay);
2080
      if(ret == -1){
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2081
	perror_plus("asprintf");
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2082
	_exit(EX_OSERR);
2083
      }
2084
      ret = setenv("DELAY", delaystring, 1);
2085
      if(ret == -1){
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2086
	free(delaystring);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2087
	perror_plus("setenv");
2088
	_exit(EX_OSERR);
2089
      }
2090
      free(delaystring);
2091
      if(connect_to != NULL){
2092
	ret = setenv("CONNECT", connect_to, 1);
2093
	if(ret == -1){
2094
	  perror_plus("setenv");
2095
	  _exit(EX_OSERR);
2096
	}
2097
      }
237.25.3 by Teddy Hogeborn
mandos-client: Minor changes to check for more error conditions.
2098
      int hook_fd = (int)TEMP_FAILURE_RETRY(openat(hookdir_fd,
2099
						   direntry->d_name,
2100
						   O_RDONLY));
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
2101
      if(hook_fd == -1){
2102
	perror_plus("openat");
2103
	_exit(EXIT_FAILURE);
2104
      }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2105
      if(close(hookdir_fd) == -1){
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
2106
	perror_plus("close");
2107
	_exit(EXIT_FAILURE);
2108
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2109
      ret = dup2(devnull, STDIN_FILENO);
2110
      if(ret == -1){
2111
	perror_plus("dup2(devnull, STDIN_FILENO)");
2112
	_exit(EX_OSERR);
2113
      }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2114
      ret = close(devnull);
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2115
      if(ret == -1){
2116
	perror_plus("close");
2117
	_exit(EX_OSERR);
2118
      }
2119
      ret = dup2(STDERR_FILENO, STDOUT_FILENO);
2120
      if(ret == -1){
2121
	perror_plus("dup2(STDERR_FILENO, STDOUT_FILENO)");
2122
	_exit(EX_OSERR);
2123
      }
237.7.244 by Teddy Hogeborn
Bug fix for mandos-client: Run the network hook, not the directory.
2124
      if(fexecve(hook_fd, (char *const []){ direntry->d_name, NULL },
2125
		 environ) == -1){
237.7.240 by Teddy Hogeborn
Make mandos-client use fexecve().
2126
	perror_plus("fexecve");
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2127
	_exit(EXIT_FAILURE);
2128
      }
2129
    } else {
237.7.281 by Teddy Hogeborn
mandos-client: Bug fix: Check fork() return value.
2130
      if(hook_pid == -1){
2131
	perror_plus("fork");
2132
	free(direntry);
2133
	continue;
2134
      }
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2135
      int status;
2136
      if(TEMP_FAILURE_RETRY(waitpid(hook_pid, &status, 0)) == -1){
2137
	perror_plus("waitpid");
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2138
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2139
	continue;
2140
      }
2141
      if(WIFEXITED(status)){
2142
	if(WEXITSTATUS(status) != 0){
2143
	  fprintf_plus(stderr, "Warning: network hook \"%s\" exited"
2144
		       " with status %d\n", direntry->d_name,
2145
		       WEXITSTATUS(status));
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2146
	  free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2147
	  continue;
2148
	}
2149
      } else if(WIFSIGNALED(status)){
2150
	fprintf_plus(stderr, "Warning: network hook \"%s\" died by"
2151
		     " signal %d\n", direntry->d_name,
2152
		     WTERMSIG(status));
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2153
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2154
	continue;
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2155
      } else {
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2156
	fprintf_plus(stderr, "Warning: network hook \"%s\""
2157
		     " crashed\n", direntry->d_name);
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2158
	free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2159
	continue;
2160
      }
2161
    }
2162
    if(debug){
2163
      fprintf_plus(stderr, "Network hook \"%s\" ran successfully\n",
2164
		   direntry->d_name);
2165
    }
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2166
    free(direntry);
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2167
  }
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
2168
  free(direntries);
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2169
  if(close(hookdir_fd) == -1){
237.7.239 by Teddy Hogeborn
Make mandos-client use scandirat() if it exists.
2170
    perror_plus("close");
2171
  } else {
2172
    hookdir_fd = -1;
2173
  }
2174
  close(devnull);
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
2175
}
2176
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2177
__attribute__((nonnull, warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2178
int bring_up_interface(const char *const interface,
2179
		       const float delay){
2180
  int old_errno = errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2181
  int ret;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2182
  struct ifreq network;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2183
  unsigned int if_index = if_nametoindex(interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2184
  if(if_index == 0){
2185
    fprintf_plus(stderr, "No such interface: \"%s\"\n", interface);
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2186
    errno = old_errno;
2187
    return ENXIO;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2188
  }
2189
  
2190
  if(quit_now){
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2191
    errno = old_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2192
    return EINTR;
2193
  }
2194
  
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2195
  if(not interface_is_up(interface)){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2196
    int ret_errno = 0;
2197
    int ioctl_errno = 0;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2198
    if(not get_flags(interface, &network)){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2199
      ret_errno = errno;
2200
      fprintf_plus(stderr, "Failed to get flags for interface "
2201
		   "\"%s\"\n", interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2202
      errno = old_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2203
      return ret_errno;
2204
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2205
    network.ifr_flags |= IFF_UP; /* set flag */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2206
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2207
    int sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
2208
    if(sd == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2209
      ret_errno = errno;
2210
      perror_plus("socket");
2211
      errno = old_errno;
2212
      return ret_errno;
2213
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2214
    
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2215
    if(quit_now){
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2216
      ret = close(sd);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2217
      if(ret == -1){
2218
	perror_plus("close");
2219
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2220
      errno = old_errno;
2221
      return EINTR;
2222
    }
2223
    
2224
    if(debug){
2225
      fprintf_plus(stderr, "Bringing up interface \"%s\"\n",
2226
		   interface);
2227
    }
2228
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2229
    /* Raise privileges */
2230
    ret_errno = raise_privileges();
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2231
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2232
      errno = ret_errno;
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2233
      perror_plus("Failed to raise privileges");
2234
    }
2235
    
2236
#ifdef __linux__
2237
    int ret_linux;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2238
    bool restore_loglevel = false;
2239
    if(ret_errno == 0){
2240
      /* Lower kernel loglevel to KERN_NOTICE to avoid KERN_INFO
2241
	 messages about the network interface to mess up the prompt */
2242
      ret_linux = klogctl(8, NULL, 5);
2243
      if(ret_linux == -1){
2244
	perror_plus("klogctl");
2245
      } else {
2246
	restore_loglevel = true;
2247
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2248
    }
2249
#endif	/* __linux__ */
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2250
    int ret_setflags = ioctl(sd, SIOCSIFFLAGS, &network);
2251
    ioctl_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2252
#ifdef __linux__
2253
    if(restore_loglevel){
2254
      ret_linux = klogctl(7, NULL, 0);
2255
      if(ret_linux == -1){
2256
	perror_plus("klogctl");
2257
      }
2258
    }
2259
#endif	/* __linux__ */
2260
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2261
    /* If raise_privileges() succeeded above */
2262
    if(ret_errno == 0){
2263
      /* Lower privileges */
2264
      ret_errno = lower_privileges();
2265
      if(ret_errno != 0){
2266
	errno = ret_errno;
2267
	perror_plus("Failed to lower privileges");
2268
      }
2269
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2270
    
2271
    /* Close the socket */
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2272
    ret = close(sd);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2273
    if(ret == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2274
      perror_plus("close");
2275
    }
2276
    
2277
    if(ret_setflags == -1){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2278
      errno = ioctl_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2279
      perror_plus("ioctl SIOCSIFFLAGS +IFF_UP");
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2280
      errno = old_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2281
      return ioctl_errno;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2282
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2283
  } else if(debug){
2284
    fprintf_plus(stderr, "Interface \"%s\" is already up; good\n",
2285
		 interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2286
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2287
  
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2288
  /* Sleep checking until interface is running.
2289
     Check every 0.25s, up to total time of delay */
237.7.438 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
2290
  for(int i = 0; i < delay * 4; i++){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2291
    if(interface_is_running(interface)){
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2292
      break;
2293
    }
2294
    struct timespec sleeptime = { .tv_nsec = 250000000 };
2295
    ret = nanosleep(&sleeptime, NULL);
2296
    if(ret == -1 and errno != EINTR){
2297
      perror_plus("nanosleep");
2298
    }
2299
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2300
  
2301
  errno = old_errno;
2302
  return 0;
2303
}
2304
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2305
__attribute__((nonnull, warn_unused_result))
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2306
int take_down_interface(const char *const interface){
2307
  int old_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2308
  struct ifreq network;
2309
  unsigned int if_index = if_nametoindex(interface);
2310
  if(if_index == 0){
2311
    fprintf_plus(stderr, "No such interface: \"%s\"\n", interface);
2312
    errno = old_errno;
2313
    return ENXIO;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2314
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2315
  if(interface_is_up(interface)){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2316
    int ret_errno = 0;
2317
    int ioctl_errno = 0;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2318
    if(not get_flags(interface, &network) and debug){
2319
      ret_errno = errno;
2320
      fprintf_plus(stderr, "Failed to get flags for interface "
2321
		   "\"%s\"\n", interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2322
      errno = old_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2323
      return ret_errno;
2324
    }
2325
    network.ifr_flags &= ~(short)IFF_UP; /* clear flag */
2326
    
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2327
    int sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2328
    if(sd == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2329
      ret_errno = errno;
2330
      perror_plus("socket");
2331
      errno = old_errno;
2332
      return ret_errno;
2333
    }
2334
    
2335
    if(debug){
2336
      fprintf_plus(stderr, "Taking down interface \"%s\"\n",
2337
		   interface);
2338
    }
2339
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2340
    /* Raise privileges */
2341
    ret_errno = raise_privileges();
2342
    if(ret_errno != 0){
237.7.254 by Teddy Hogeborn
mandos-client: Better error messages.
2343
      errno = ret_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2344
      perror_plus("Failed to raise privileges");
2345
    }
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
2346
    
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2347
    int ret_setflags = ioctl(sd, SIOCSIFFLAGS, &network);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2348
    ioctl_errno = errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2349
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2350
    /* If raise_privileges() succeeded above */
2351
    if(ret_errno == 0){
2352
      /* Lower privileges */
2353
      ret_errno = lower_privileges();
2354
      if(ret_errno != 0){
2355
	errno = ret_errno;
2356
	perror_plus("Failed to lower privileges");
2357
      }
2358
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2359
    
2360
    /* Close the socket */
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2361
    int ret = close(sd);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2362
    if(ret == -1){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2363
      perror_plus("close");
2364
    }
2365
    
2366
    if(ret_setflags == -1){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2367
      errno = ioctl_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2368
      perror_plus("ioctl SIOCSIFFLAGS -IFF_UP");
2369
      errno = old_errno;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2370
      return ioctl_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2371
    }
2372
  } else if(debug){
2373
    fprintf_plus(stderr, "Interface \"%s\" is already down; odd\n",
2374
		 interface);
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2375
  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2376
  
237.22.2 by Teddy Hogeborn
* plugins.d/mandos-client.c (bring_up_interface): Bug fix: Return
2377
  errno = old_errno;
2378
  return 0;
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2379
}
2380
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
2381
int main(int argc, char *argv[]){
237.7.291 by Teddy Hogeborn
Automatically determine the number of DH bits in the TLS handshake.
2382
  mandos_context mc = { .server = NULL, .dh_bits = 0,
237.7.325 by Teddy Hogeborn
Bug fix for GnuTLS 3: be compatible with old 2048-bit DSA keys.
2383
			.priority = "SECURE256:!CTYPE-X.509"
2384
			":+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256",
2385
			.current_server = NULL, .interfaces = NULL,
2386
			.interfaces_size = 0 };
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2387
  AvahiSServiceBrowser *sb = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2388
  error_t ret_errno;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2389
  int ret;
2390
  intmax_t tmpmax;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2391
  char *tmp;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2392
  int exitcode = EXIT_SUCCESS;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2393
  char *interfaces_to_take_down = NULL;
2394
  size_t interfaces_to_take_down_size = 0;
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
2395
  char run_tempdir[] = "/run/tmp/mandosXXXXXX";
2396
  char old_tempdir[] = "/tmp/mandosXXXXXX";
2397
  char *tempdir = NULL;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2398
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
2399
  const char *seckey = PATHDIR "/" SECKEY;
2400
  const char *pubkey = PATHDIR "/" PUBKEY;
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2401
  const char *dh_params_file = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2402
  char *interfaces_hooks = NULL;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2403
  
2404
  bool gnutls_initialized = false;
2405
  bool gpgme_initialized = false;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2406
  float delay = 2.5f;
237.7.33 by Teddy Hogeborn
Merge from Björn.
2407
  double retry_interval = 10; /* 10s between trying a server and
2408
				 retrying the same server again */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2409
  
237.2.132 by Teddy Hogeborn
* init.d-mandos (Required-Start, Required-Stop): Bug fix: Added
2410
  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
2411
  struct sigaction sigterm_action = { .sa_handler = handle_sigterm };
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2412
  
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2413
  uid = getuid();
2414
  gid = getgid();
2415
  
2416
  /* Lower any group privileges we might have, just to be safe */
2417
  errno = 0;
2418
  ret = setgid(gid);
2419
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2420
    perror_plus("setgid");
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2421
  }
2422
  
2423
  /* Lower user privileges (temporarily) */
2424
  errno = 0;
2425
  ret = seteuid(uid);
2426
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2427
    perror_plus("seteuid");
237.2.131 by Teddy Hogeborn
* plugins.d/mandos-client.c (init_gnutls_session): Retry interrupted
2428
  }
2429
  
2430
  if(quit_now){
2431
    goto end;
2432
  }
2433
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2434
  {
2435
    struct argp_option options[] = {
2436
      { .name = "debug", .key = 128,
2437
	.doc = "Debug mode", .group = 3 },
2438
      { .name = "connect", .key = 'c',
2439
	.arg = "ADDRESS:PORT",
2440
	.doc = "Connect directly to a specific Mandos server",
2441
	.group = 1 },
2442
      { .name = "interface", .key = 'i',
2443
	.arg = "NAME",
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2444
	.doc = "Network interface that will be used to search for"
2445
	" Mandos servers",
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2446
	.group = 1 },
2447
      { .name = "seckey", .key = 's',
2448
	.arg = "FILE",
2449
	.doc = "OpenPGP secret key file base name",
2450
	.group = 1 },
2451
      { .name = "pubkey", .key = 'p',
2452
	.arg = "FILE",
2453
	.doc = "OpenPGP public key file base name",
2454
	.group = 2 },
2455
      { .name = "dh-bits", .key = 129,
2456
	.arg = "BITS",
2457
	.doc = "Bit length of the prime number used in the"
2458
	" Diffie-Hellman key exchange",
2459
	.group = 2 },
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2460
      { .name = "dh-params", .key = 134,
2461
	.arg = "FILE",
2462
	.doc = "PEM-encoded PKCS#3 file with pre-generated parameters"
2463
	" for the Diffie-Hellman key exchange",
2464
	.group = 2 },
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2465
      { .name = "priority", .key = 130,
2466
	.arg = "STRING",
2467
	.doc = "GnuTLS priority string for the TLS handshake",
2468
	.group = 1 },
2469
      { .name = "delay", .key = 131,
2470
	.arg = "SECONDS",
2471
	.doc = "Maximum delay to wait for interface startup",
2472
	.group = 2 },
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2473
      { .name = "retry", .key = 132,
2474
	.arg = "SECONDS",
237.17.1 by teddy at recompile
Add wireless network hook
2475
	.doc = "Retry interval used when denied by the Mandos server",
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2476
	.group = 2 },
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
2477
      { .name = "network-hook-dir", .key = 133,
2478
	.arg = "DIR",
2479
	.doc = "Directory where network hooks are located",
2480
	.group = 2 },
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2481
      /*
2482
       * These reproduce what we would get without ARGP_NO_HELP
2483
       */
2484
      { .name = "help", .key = '?',
2485
	.doc = "Give this help list", .group = -1 },
2486
      { .name = "usage", .key = -3,
2487
	.doc = "Give a short usage message", .group = -1 },
2488
      { .name = "version", .key = 'V',
2489
	.doc = "Print program version", .group = -1 },
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2490
      { .name = NULL }
2491
    };
2492
    
2493
    error_t parse_opt(int key, char *arg,
2494
		      struct argp_state *state){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2495
      errno = 0;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2496
      switch(key){
2497
      case 128:			/* --debug */
2498
	debug = true;
2499
	break;
2500
      case 'c':			/* --connect */
2501
	connect_to = arg;
2502
	break;
2503
      case 'i':			/* --interface */
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2504
	ret_errno = argz_add_sep(&mc.interfaces, &mc.interfaces_size,
2505
				 arg, (int)',');
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2506
	if(ret_errno != 0){
2507
	  argp_error(state, "%s", strerror(ret_errno));
2508
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2509
	break;
2510
      case 's':			/* --seckey */
2511
	seckey = arg;
2512
	break;
2513
      case 'p':			/* --pubkey */
2514
	pubkey = arg;
2515
	break;
2516
      case 129:			/* --dh-bits */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2517
	errno = 0;
2518
	tmpmax = strtoimax(arg, &tmp, 10);
2519
	if(errno != 0 or tmp == arg or *tmp != '\0'
2520
	   or tmpmax != (typeof(mc.dh_bits))tmpmax){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2521
	  argp_error(state, "Bad number of DH bits");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2522
	}
2523
	mc.dh_bits = (typeof(mc.dh_bits))tmpmax;
2524
	break;
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2525
      case 134:			/* --dh-params */
2526
	dh_params_file = arg;
2527
	break;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2528
      case 130:			/* --priority */
2529
	mc.priority = arg;
2530
	break;
2531
      case 131:			/* --delay */
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2532
	errno = 0;
2533
	delay = strtof(arg, &tmp);
2534
	if(errno != 0 or tmp == arg or *tmp != '\0'){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2535
	  argp_error(state, "Bad delay");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2536
	}
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2537
      case 132:			/* --retry */
2538
	errno = 0;
2539
	retry_interval = strtod(arg, &tmp);
2540
	if(errno != 0 or tmp == arg or *tmp != '\0'
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2541
	   or (retry_interval * 1000) > INT_MAX
2542
	   or retry_interval < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2543
	  argp_error(state, "Bad retry interval");
2544
	}
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2545
	break;
237.16.4 by teddy at bsnet
* plugins.d/mandos-client.c (runnable_hook): Bug fix: stat using the
2546
      case 133:			/* --network-hook-dir */
2547
	hookdir = arg;
2548
	break;
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2549
	/*
2550
	 * These reproduce what we would get without ARGP_NO_HELP
2551
	 */
2552
      case '?':			/* --help */
2553
	argp_state_help(state, state->out_stream,
2554
			(ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2555
			& ~(unsigned int)ARGP_HELP_EXIT_OK);
2556
      case -3:			/* --usage */
2557
	argp_state_help(state, state->out_stream,
2558
			ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
2559
      case 'V':			/* --version */
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2560
	fprintf_plus(state->out_stream, "%s\n", argp_program_version);
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2561
	exit(argp_err_exit_status);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2562
	break;
2563
      default:
2564
	return ARGP_ERR_UNKNOWN;
2565
      }
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2566
      return errno;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2567
    }
2568
    
2569
    struct argp argp = { .options = options, .parser = parse_opt,
2570
			 .args_doc = "",
2571
			 .doc = "Mandos client -- Get and decrypt"
2572
			 " passwords from a Mandos server" };
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2573
    ret_errno = argp_parse(&argp, argc, argv,
2574
			   ARGP_IN_ORDER | ARGP_NO_HELP, 0, NULL);
2575
    switch(ret_errno){
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2576
    case 0:
2577
      break;
2578
    case ENOMEM:
2579
    default:
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2580
      errno = ret_errno;
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2581
      perror_plus("argp_parse");
237.2.157 by Teddy Hogeborn
Convert some programs to use the exit codes from <sysexits.h>. Change
2582
      exitcode = EX_OSERR;
2583
      goto end;
2584
    case EINVAL:
2585
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2586
      goto end;
2587
    }
2588
  }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2589
  
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2590
  {
237.7.35 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
2591
    /* Work around Debian bug #633582:
237.7.416 by Teddy Hogeborn
Change all http:// URLs to https:// wherever possible.
2592
       <https://bugs.debian.org/633582> */
237.7.35 by Teddy Hogeborn
* initramfs-tools-script: Abort if plugin-runner is missing. Removed
2593
    
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2594
    /* Re-raise privileges */
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2595
    ret = raise_privileges();
2596
    if(ret != 0){
2597
      errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2598
      perror_plus("Failed to raise privileges");
2599
    } else {
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2600
      struct stat st;
2601
      
2602
      if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
2603
	int seckey_fd = open(seckey, O_RDONLY);
2604
	if(seckey_fd == -1){
2605
	  perror_plus("open");
2606
	} else {
2607
	  ret = (int)TEMP_FAILURE_RETRY(fstat(seckey_fd, &st));
2608
	  if(ret == -1){
2609
	    perror_plus("fstat");
2610
	  } else {
2611
	    if(S_ISREG(st.st_mode)
2612
	       and st.st_uid == 0 and st.st_gid == 0){
2613
	      ret = fchown(seckey_fd, uid, gid);
2614
	      if(ret == -1){
2615
		perror_plus("fchown");
2616
	      }
2617
	    }
2618
	  }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2619
	  close(seckey_fd);
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2620
	}
2621
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2622
      
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2623
      if(strcmp(pubkey, PATHDIR "/" PUBKEY) == 0){
2624
	int pubkey_fd = open(pubkey, O_RDONLY);
2625
	if(pubkey_fd == -1){
2626
	  perror_plus("open");
2627
	} else {
2628
	  ret = (int)TEMP_FAILURE_RETRY(fstat(pubkey_fd, &st));
2629
	  if(ret == -1){
2630
	    perror_plus("fstat");
2631
	  } else {
2632
	    if(S_ISREG(st.st_mode)
2633
	       and st.st_uid == 0 and st.st_gid == 0){
2634
	      ret = fchown(pubkey_fd, uid, gid);
2635
	      if(ret == -1){
2636
		perror_plus("fchown");
2637
	      }
2638
	    }
2639
	  }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2640
	  close(pubkey_fd);
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2641
	}
2642
      }
237.25.2 by Teddy Hogeborn
mandos-client: Try to start a plugin to add and remove a local route.
2643
      
237.7.324 by Teddy Hogeborn
mandos-client: Bug fix: don't crash if --dh-params was not used.
2644
      if(dh_params_file != NULL
2645
	 and strcmp(dh_params_file, PATHDIR "/dhparams.pem" ) == 0){
237.7.313 by Teddy Hogeborn
Install client Diffie-Hellman parameters into initramfs.
2646
	int dhparams_fd = open(dh_params_file, O_RDONLY);
2647
	if(dhparams_fd == -1){
2648
	  perror_plus("open");
2649
	} else {
2650
	  ret = (int)TEMP_FAILURE_RETRY(fstat(dhparams_fd, &st));
2651
	  if(ret == -1){
2652
	    perror_plus("fstat");
2653
	  } else {
2654
	    if(S_ISREG(st.st_mode)
2655
	       and st.st_uid == 0 and st.st_gid == 0){
2656
	      ret = fchown(dhparams_fd, uid, gid);
2657
	      if(ret == -1){
2658
		perror_plus("fchown");
2659
	      }
2660
	    }
2661
	  }
237.7.322 by Teddy Hogeborn
Don't use TEMP_FAILURE_RETRY around close().
2662
	  close(dhparams_fd);
237.7.313 by Teddy Hogeborn
Install client Diffie-Hellman parameters into initramfs.
2663
	}
2664
      }
2665
      
237.16.11 by Teddy Hogeborn
* Makefile (run-client): Add "--network-hook-dir" option.
2666
      /* Lower privileges */
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
2667
      ret = lower_privileges();
2668
      if(ret != 0){
2669
	errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2670
	perror_plus("Failed to lower privileges");
2671
      }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2672
    }
2673
  }
2674
  
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2675
  /* Remove invalid interface names (except "none") */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2676
  {
2677
    char *interface = NULL;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2678
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2679
				 interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2680
      if(strcmp(interface, "none") != 0
2681
	 and if_nametoindex(interface) == 0){
2682
	if(interface[0] != '\0'){
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2683
	  fprintf_plus(stderr, "Not using nonexisting interface"
2684
		       " \"%s\"\n", interface);
2685
	}
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2686
	argz_delete(&mc.interfaces, &mc.interfaces_size, interface);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2687
	interface = NULL;
2688
      }
2689
    }
2690
  }
2691
  
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2692
  /* Run network hooks */
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2693
  {
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2694
    if(mc.interfaces != NULL){
2695
      interfaces_hooks = malloc(mc.interfaces_size);
237.7.147 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Set DEVICE environment
2696
      if(interfaces_hooks == NULL){
2697
	perror_plus("malloc");
2698
	goto end;
2699
      }
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2700
      memcpy(interfaces_hooks, mc.interfaces, mc.interfaces_size);
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2701
      argz_stringify(interfaces_hooks, mc.interfaces_size, (int)',');
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2702
    }
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2703
    run_network_hooks("start", interfaces_hooks != NULL ?
2704
		      interfaces_hooks : "", delay);
237.16.16 by teddy at bsnet
* network-hooks.d/bridge: Use "/usr/sbin/brctl" explicitly.
2705
  }
2706
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2707
  if(not debug){
2708
    avahi_set_log_function(empty_log);
2709
  }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2710
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2711
  /* Initialize Avahi early so avahi_simple_poll_quit() can be called
2712
     from the signal handler */
2713
  /* Initialize the pseudo-RNG for Avahi */
2714
  srand((unsigned int) time(NULL));
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
2715
  simple_poll = avahi_simple_poll_new();
2716
  if(simple_poll == NULL){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2717
    fprintf_plus(stderr,
2718
		 "Avahi: Failed to create simple poll object.\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2719
    exitcode = EX_UNAVAILABLE;
24.1.135 by Björn Påhlsson
Earlier signal handling
2720
    goto end;
2721
  }
237.2.72 by Teddy Hogeborn
Merge from Björn:
2722
  
24.1.135 by Björn Påhlsson
Earlier signal handling
2723
  sigemptyset(&sigterm_action.sa_mask);
237.2.72 by Teddy Hogeborn
Merge from Björn:
2724
  ret = sigaddset(&sigterm_action.sa_mask, SIGINT);
2725
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2726
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2727
    exitcode = EX_OSERR;
237.2.72 by Teddy Hogeborn
Merge from Björn:
2728
    goto end;
2729
  }
2730
  ret = sigaddset(&sigterm_action.sa_mask, SIGHUP);
2731
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2732
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2733
    exitcode = EX_OSERR;
237.2.72 by Teddy Hogeborn
Merge from Björn:
2734
    goto end;
2735
  }
24.1.135 by Björn Påhlsson
Earlier signal handling
2736
  ret = sigaddset(&sigterm_action.sa_mask, SIGTERM);
2737
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2738
    perror_plus("sigaddset");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2739
    exitcode = EX_OSERR;
24.1.135 by Björn Påhlsson
Earlier signal handling
2740
    goto end;
2741
  }
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2742
  /* Need to check if the handler is SIG_IGN before handling:
2743
     | [[info:libc:Initial Signal Actions]] |
2744
     | [[info:libc:Basic Signal Handling]]  |
2745
  */
2746
  ret = sigaction(SIGINT, NULL, &old_sigterm_action);
2747
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2748
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2749
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2750
  }
2751
  if(old_sigterm_action.sa_handler != SIG_IGN){
2752
    ret = sigaction(SIGINT, &sigterm_action, NULL);
2753
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2754
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2755
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2756
      goto end;
2757
    }
2758
  }
2759
  ret = sigaction(SIGHUP, NULL, &old_sigterm_action);
2760
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2761
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2762
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2763
  }
2764
  if(old_sigterm_action.sa_handler != SIG_IGN){
2765
    ret = sigaction(SIGHUP, &sigterm_action, NULL);
2766
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2767
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2768
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2769
      goto end;
2770
    }
2771
  }
2772
  ret = sigaction(SIGTERM, NULL, &old_sigterm_action);
2773
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2774
    perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2775
    return EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2776
  }
2777
  if(old_sigterm_action.sa_handler != SIG_IGN){
2778
    ret = sigaction(SIGTERM, &sigterm_action, NULL);
2779
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2780
      perror_plus("sigaction");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2781
      exitcode = EX_OSERR;
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
2782
      goto end;
2783
    }
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
2784
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2785
  
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2786
  /* If no interfaces were specified, make a list */
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2787
  if(mc.interfaces == NULL){
237.7.247 by Teddy Hogeborn
Fix free() of possibly uninitialized pointer in mandos-client.
2788
    struct dirent **direntries = NULL;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2789
    /* Look for any good interfaces */
2790
    ret = scandir(sys_class_net, &direntries, good_interface,
2791
		  alphasort);
2792
    if(ret >= 1){
2793
      /* Add all found interfaces to interfaces list */
2794
      for(int i = 0; i < ret; ++i){
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2795
	ret_errno = argz_add(&mc.interfaces, &mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2796
			     direntries[i]->d_name);
2797
	if(ret_errno != 0){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2798
	  errno = ret_errno;
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2799
	  perror_plus("argz_add");
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2800
	  free(direntries[i]);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2801
	  continue;
2802
	}
2803
	if(debug){
2804
	  fprintf_plus(stderr, "Will use interface \"%s\"\n",
2805
		       direntries[i]->d_name);
2806
	}
237.7.263 by Teddy Hogeborn
mandos-client: Bug Fix: Fix some memory leaks.
2807
	free(direntries[i]);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2808
      }
2809
      free(direntries);
2810
    } else {
237.7.252 by Teddy Hogeborn
mandos-client: Fix some bugs on error conditions.
2811
      if(ret == 0){
2812
	free(direntries);
2813
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2814
      fprintf_plus(stderr, "Could not find a network interface\n");
2815
      exitcode = EXIT_FAILURE;
2816
      goto end;
2817
    }
2818
  }
2819
  
237.7.153 by Teddy Hogeborn
* plugins.d/mandos-client.c: Comment changes
2820
  /* Bring up interfaces which are down, and remove any "none"s */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2821
  {
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2822
    char *interface = NULL;
237.7.151 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): New "interfaces" and
2823
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2824
				 interface))){
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2825
      /* If interface name is "none", stop bringing up interfaces.
2826
	 Also remove all instances of "none" from the list */
2827
      if(strcmp(interface, "none") == 0){
2828
	argz_delete(&mc.interfaces, &mc.interfaces_size,
2829
		    interface);
2830
	interface = NULL;
2831
	while((interface = argz_next(mc.interfaces,
2832
				     mc.interfaces_size, interface))){
2833
	  if(strcmp(interface, "none") == 0){
2834
	    argz_delete(&mc.interfaces, &mc.interfaces_size,
2835
			interface);
2836
	    interface = NULL;
2837
	  }
2838
	}
2839
	break;
2840
      }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2841
      bool interface_was_up = interface_is_up(interface);
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2842
      errno = bring_up_interface(interface, delay);
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2843
      if(not interface_was_up){
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2844
	if(errno != 0){
237.7.315 by Teddy Hogeborn
plugins.d/mandos-client.c (main): See why it failed to bring up interface.
2845
	  fprintf_plus(stderr, "Failed to bring up interface \"%s\":"
2846
		       " %s\n", interface, strerror(errno));
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2847
	} else {
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
2848
	  errno = argz_add(&interfaces_to_take_down,
2849
			   &interfaces_to_take_down_size,
2850
			   interface);
2851
	  if(errno != 0){
237.7.214 by Teddy Hogeborn
Bug fix: Free all memory and give better messages when memory is full.
2852
	    perror_plus("argz_add");
2853
	  }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
2854
	}
2855
      }
2856
    }
2857
    if(debug and (interfaces_to_take_down == NULL)){
2858
      fprintf_plus(stderr, "No interfaces were brought up\n");
237.2.128 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Bug fix: Check result of setgid().
2859
    }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2860
  }
2861
  
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2862
  /* If we only got one interface, explicitly use only that one */
2863
  if(argz_count(mc.interfaces, mc.interfaces_size) == 1){
2864
    if(debug){
2865
      fprintf_plus(stderr, "Using only interface \"%s\"\n",
2866
		   mc.interfaces);
2867
    }
2868
    if_index = (AvahiIfIndex)if_nametoindex(mc.interfaces);
2869
  }
2870
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2871
  if(quit_now){
2872
    goto end;
2873
  }
2874
  
237.7.310 by Teddy Hogeborn
mandos-client: Add --dh-params FILE option.
2875
  ret = init_gnutls_global(pubkey, seckey, dh_params_file, &mc);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2876
  if(ret == -1){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2877
    fprintf_plus(stderr, "init_gnutls_global failed\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2878
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2879
    goto end;
2880
  } else {
2881
    gnutls_initialized = true;
2882
  }
2883
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2884
  if(quit_now){
2885
    goto end;
2886
  }
2887
  
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
2888
  /* Try /run/tmp before /tmp */
2889
  tempdir = mkdtemp(run_tempdir);
2890
  if(tempdir == NULL and errno == ENOENT){
2891
      if(debug){
2892
	fprintf_plus(stderr, "Tempdir %s did not work, trying %s\n",
2893
		     run_tempdir, old_tempdir);
2894
      }
2895
      tempdir = mkdtemp(old_tempdir);
2896
  }
2897
  if(tempdir == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
2898
    perror_plus("mkdtemp");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2899
    goto end;
2900
  }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2901
  
2902
  if(quit_now){
2903
    goto end;
2904
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2905
  
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2906
  if(not init_gpgme(pubkey, seckey, tempdir, &mc)){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2907
    fprintf_plus(stderr, "init_gpgme failed\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2908
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2909
    goto end;
2910
  } else {
2911
    gpgme_initialized = true;
2912
  }
2913
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2914
  if(quit_now){
2915
    goto end;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2916
  }
2917
  
2918
  if(connect_to != NULL){
2919
    /* Connect directly, do not use Zeroconf */
2920
    /* (Mainly meant for debugging) */
2921
    char *address = strrchr(connect_to, ':');
237.22.1 by Teddy Hogeborn
* plugins.d/mandos-client.c: Refactoring.
2922
    
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2923
    if(address == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2924
      fprintf_plus(stderr, "No colon in address\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2925
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2926
      goto end;
2927
    }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2928
    
2929
    if(quit_now){
2930
      goto end;
2931
    }
2932
    
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2933
    in_port_t port;
237.2.74 by Teddy Hogeborn
Overflows are not detected by sscanf(), so stop using it:
2934
    errno = 0;
2935
    tmpmax = strtoimax(address+1, &tmp, 10);
2936
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2937
       or tmpmax != (in_port_t)tmpmax){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
2938
      fprintf_plus(stderr, "Bad port number\n");
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2939
      exitcode = EX_USAGE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2940
      goto end;
2941
    }
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
2942
    
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2943
    if(quit_now){
2944
      goto end;
2945
    }
2946
    
237.7.145 by Teddy Hogeborn
* plugins.d/mandos-client.c: Don't use assert(). Use in_port_t for
2947
    port = (in_port_t)tmpmax;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2948
    *address = '\0';
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2949
    /* Colon in address indicates IPv6 */
2950
    int af;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2951
    if(strchr(connect_to, ':') != NULL){
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2952
      af = AF_INET6;
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2953
      /* Accept [] around IPv6 address - see RFC 5952 */
2954
      if(connect_to[0] == '[' and address[-1] == ']')
2955
	{
2956
	  connect_to++;
2957
	  address[-1] = '\0';
2958
	}
237.2.67 by Teddy Hogeborn
Four new interrelated features:
2959
    } else {
2960
      af = AF_INET;
2961
    }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2962
    address = connect_to;
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2963
    
2964
    if(quit_now){
2965
      goto end;
2966
    }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2967
    
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
2968
    while(not quit_now){
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
2969
      ret = start_mandos_communication(address, port, if_index, af,
2970
				       &mc);
24.1.163 by Björn Påhlsson
mandos-client: Added never ending loop for --connect
2971
      if(quit_now or ret == 0){
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
2972
	break;
2973
      }
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2974
      if(debug){
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
2975
	fprintf_plus(stderr, "Retrying in %d seconds\n",
2976
		     (int)retry_interval);
237.7.39 by teddy at bsnet
* plugins.d/mandos-client.c (avahi_loop_with_timeout): Fix warning.
2977
      }
237.7.168 by Teddy Hogeborn
* plugin-runner.c (main): Bug fix; do not ignore return value of
2978
      sleep((unsigned int)retry_interval);
237.7.40 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not even try to work around
2979
    }
2980
    
237.7.219 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
2981
    if(not quit_now){
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2982
      exitcode = EXIT_SUCCESS;
2983
    }
237.15.3 by Teddy Hogeborn
Intermediate commit - this does *not* work yet.
2984
    
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2985
    goto end;
2986
  }
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
2987
  
2988
  if(quit_now){
2989
    goto end;
2990
  }
2991
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
2992
  {
2993
    AvahiServerConfig config;
2994
    /* Do not publish any local Zeroconf records */
2995
    avahi_server_config_init(&config);
2996
    config.publish_hinfo = 0;
2997
    config.publish_addresses = 0;
2998
    config.publish_workstation = 0;
2999
    config.publish_domain = 0;
3000
    
3001
    /* Allocate a new server */
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
3002
    mc.server = avahi_server_new(avahi_simple_poll_get(simple_poll),
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3003
				 &config, NULL, NULL, &ret);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3004
    
3005
    /* Free the Avahi configuration data */
3006
    avahi_server_config_free(&config);
3007
  }
3008
  
3009
  /* Check if creating the Avahi server object succeeded */
3010
  if(mc.server == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3011
    fprintf_plus(stderr, "Failed to create Avahi server: %s\n",
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3012
		 avahi_strerror(ret));
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
3013
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3014
    goto end;
3015
  }
3016
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
3017
  if(quit_now){
3018
    goto end;
3019
  }
3020
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3021
  /* Create the Avahi service browser */
3022
  sb = avahi_s_service_browser_new(mc.server, if_index,
237.2.76 by Teddy Hogeborn
* plugins.d/mandos-client.c (browse_callback, main): Do not require
3023
				   AVAHI_PROTO_UNSPEC, "_mandos._tcp",
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
3024
				   NULL, 0, browse_callback,
3025
				   (void *)&mc);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3026
  if(sb == NULL){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3027
    fprintf_plus(stderr, "Failed to create service browser: %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
3028
		 avahi_strerror(avahi_server_errno(mc.server)));
237.2.162 by Teddy Hogeborn
* Makefile (BROKEN_PIE): Add comment.
3029
    exitcode = EX_UNAVAILABLE;
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3030
    goto end;
3031
  }
237.2.70 by Teddy Hogeborn
Merge from Björn:
3032
  
237.2.116 by Teddy Hogeborn
* plugins.d/mandos-client.c (quit_now): Move up declaration before
3033
  if(quit_now){
3034
    goto end;
3035
  }
3036
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3037
  /* Run the main loop */
3038
  
3039
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3040
    fprintf_plus(stderr, "Starting Avahi loop search\n");
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3041
  }
237.7.235 by Teddy Hogeborn
White space fix only.
3042
  
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
3043
  ret = avahi_loop_with_timeout(simple_poll,
237.7.150 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Moved to inside "main()".
3044
				(int)(retry_interval * 1000), &mc);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3045
  if(debug){
237.15.6 by Björn Påhlsson
replace calls to fprintf with fprintf_plus.
3046
    fprintf_plus(stderr, "avahi_loop_with_timeout exited %s\n",
237.16.9 by Teddy Hogeborn
* plugins.d/mandos-client.c: Merge unified printing system.
3047
		 (ret == 0) ? "successfully" : "with error");
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3048
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3049
  
40 by Teddy Hogeborn
* plugins.d/mandosclient.c (initgnutls): Moved "err" variable into its
3050
 end:
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3051
  
3052
  if(debug){
237.7.418 by Teddy Hogeborn
Show what signal, if any, made mandos-client exit.
3053
    if(signal_received){
3054
      fprintf_plus(stderr, "%s exiting due to signal %d: %s\n",
3055
		   argv[0], signal_received,
3056
		   strsignal(signal_received));
3057
    } else {
3058
      fprintf_plus(stderr, "%s exiting\n", argv[0]);
3059
    }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3060
  }
3061
  
3062
  /* Cleanup things */
237.7.152 by Teddy Hogeborn
* plugins.d/mandos-client (start_mandos_communication): Bug fix; skip
3063
  free(mc.interfaces);
3064
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3065
  if(sb != NULL)
3066
    avahi_s_service_browser_free(sb);
3067
  
3068
  if(mc.server != NULL)
3069
    avahi_server_free(mc.server);
3070
  
237.7.149 by Teddy Hogeborn
* plugins.d/mandos-client (mandos_context): Removed "simple_poll"
3071
  if(simple_poll != NULL)
3072
    avahi_simple_poll_free(simple_poll);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3073
  
3074
  if(gnutls_initialized){
3075
    gnutls_certificate_free_credentials(mc.cred);
3076
    gnutls_dh_params_deinit(mc.dh_params);
3077
  }
3078
  
3079
  if(gpgme_initialized){
3080
    gpgme_release(mc.ctx);
3081
  }
237.16.12 by Teddy Hogeborn
* plugins.d/mandos-client.c (runnable_hook): Add debug output.
3082
  
237.7.33 by Teddy Hogeborn
Merge from Björn.
3083
  /* Cleans up the circular linked list of Mandos servers the client
3084
     has seen */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3085
  if(mc.current_server != NULL){
3086
    mc.current_server->prev->next = NULL;
3087
    while(mc.current_server != NULL){
3088
      server *next = mc.current_server->next;
237.7.262 by Teddy Hogeborn
mandos-client: Fix mem free bug.
3089
#ifdef __GNUC__
3090
#pragma GCC diagnostic push
3091
#pragma GCC diagnostic ignored "-Wcast-qual"
3092
#endif
3093
      free((char *)(mc.current_server->ip));
3094
#ifdef __GNUC__
3095
#pragma GCC diagnostic pop
3096
#endif
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3097
      free(mc.current_server);
3098
      mc.current_server = next;
3099
    }
3100
  }
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3101
  
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3102
  /* Re-raise privileges */
237.16.8 by Teddy Hogeborn
* plugins.d/mandos-client.c (run_network_hooks): New.
3103
  {
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3104
    ret = raise_privileges();
3105
    if(ret != 0){
3106
      errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3107
      perror_plus("Failed to raise privileges");
3108
    } else {
3109
      
3110
      /* Run network hooks */
3111
      run_network_hooks("stop", interfaces_hooks != NULL ?
3112
			interfaces_hooks : "", delay);
3113
      
3114
      /* Take down the network interfaces which were brought up */
3115
      {
3116
	char *interface = NULL;
237.7.438 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
3117
	while((interface = argz_next(interfaces_to_take_down,
3118
				     interfaces_to_take_down_size,
3119
				     interface))){
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3120
	  ret = take_down_interface(interface);
3121
	  if(ret != 0){
3122
	    errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3123
	    perror_plus("Failed to take down interface");
3124
	  }
3125
	}
3126
	if(debug and (interfaces_to_take_down == NULL)){
3127
	  fprintf_plus(stderr, "No interfaces needed to be taken"
3128
		       " down\n");
3129
	}
3130
      }
3131
    }
237.7.228 by Teddy Hogeborn
Minor changes to minimize diff from last release.
3132
    
237.7.367 by Teddy Hogeborn
errno is of type int, not error_t
3133
    ret = lower_privileges_permanently();
3134
    if(ret != 0){
3135
      errno = ret;
237.7.220 by Teddy Hogeborn
Update GCC warning flags and function attributes to GCC 4.7.
3136
      perror_plus("Failed to lower privileges permanently");
3137
    }
237.22.4 by Teddy Hogeborn
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
3138
  }
3139
  
3140
  free(interfaces_to_take_down);
3141
  free(interfaces_hooks);
237.2.113 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Take down network interface on
3142
  
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3143
  void clean_dir_at(int base, const char * const dirname,
3144
		    uintmax_t level){
3145
    struct dirent **direntries = NULL;
3146
    int dret;
3147
    int dir_fd = (int)TEMP_FAILURE_RETRY(openat(base, dirname,
3148
						O_RDONLY
3149
						| O_NOFOLLOW
3150
						| O_DIRECTORY
3151
						| O_PATH));
3152
    if(dir_fd == -1){
3153
      perror_plus("open");
237.7.484 by Teddy Hogeborn
Client: Bug fix: Don't try to clean directory which fails to open
3154
      return;
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3155
    }
3156
    int numentries = scandirat(dir_fd, ".", &direntries,
3157
			       notdotentries, alphasort);
3158
    if(numentries >= 0){
3159
      for(int i = 0; i < numentries; i++){
3160
	if(debug){
3161
	  fprintf_plus(stderr, "Unlinking \"%s/%s\"\n",
3162
		       dirname, direntries[i]->d_name);
3163
	}
3164
	dret = unlinkat(dir_fd, direntries[i]->d_name, 0);
3165
	if(dret == -1){
3166
	  if(errno == EISDIR){
3167
	      dret = unlinkat(dir_fd, direntries[i]->d_name,
3168
			      AT_REMOVEDIR);
3169
	  }	    
3170
	  if((dret == -1) and (errno == ENOTEMPTY)
3171
	     and (strcmp(direntries[i]->d_name, "private-keys-v1.d")
3172
		  == 0) and (level == 0)){
3173
	    /* Recurse only in this special case */
3174
	    clean_dir_at(dir_fd, direntries[i]->d_name, level+1);
3175
	    dret = 0;
3176
	  }
237.7.482 by Teddy Hogeborn
Client: Don't print failures to remove nonexisting files.
3177
	  if((dret == -1) and (errno != ENOENT)){
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3178
	    fprintf_plus(stderr, "unlink(\"%s/%s\"): %s\n", dirname,
3179
			 direntries[i]->d_name, strerror(errno));
3180
	  }
3181
	}
3182
	free(direntries[i]);
3183
      }
3184
      
3185
      /* need to clean even if 0 because man page doesn't specify */
3186
      free(direntries);
3187
      dret = unlinkat(base, dirname, AT_REMOVEDIR);
3188
      if(dret == -1 and errno != ENOENT){
3189
	perror_plus("rmdir");
3190
      }
3191
    } else {
3192
      perror_plus("scandirat");
3193
    }
3194
    close(dir_fd);
3195
  }
3196
  
24.1.172 by Björn Påhlsson
using scandir instead of readdir
3197
  /* Removes the GPGME temp directory and all files inside */
237.7.221 by Teddy Hogeborn
Make mandos-client prefer /run/tmp over /tmp.
3198
  if(tempdir != NULL){
237.7.361 by Teddy Hogeborn
Client: Remove new key directory introduced in GnuPG 2.1
3199
    clean_dir_at(-1, tempdir, 0);
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3200
  }
3201
  
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3202
  if(quit_now){
237.2.120 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Do not handle ignored signals.
3203
    sigemptyset(&old_sigterm_action.sa_mask);
3204
    old_sigterm_action.sa_handler = SIG_DFL;
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
3205
    ret = (int)TEMP_FAILURE_RETRY(sigaction(signal_received,
3206
					    &old_sigterm_action,
3207
					    NULL));
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3208
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3209
      perror_plus("sigaction");
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3210
    }
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
3211
    do {
3212
      ret = raise(signal_received);
3213
    } while(ret != 0 and errno == EINTR);
3214
    if(ret != 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
3215
      perror_plus("raise");
237.2.137 by Teddy Hogeborn
* plugins.d/mandos-client.c (main): Try harder to raise signal on
3216
      abort();
3217
    }
3218
    TEMP_FAILURE_RETRY(pause());
237.2.117 by Teddy Hogeborn
* plugins.d/mandos-client.c (signal_received): New.
3219
  }
3220
  
237.2.56 by Teddy Hogeborn
* plugin-runner.c: Whitespace changes only.
3221
  return exitcode;
13 by Björn Påhlsson
Added following support:
3222
}