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