/mandos/release

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