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