=== modified file 'debian/control'
--- debian/control 2020-03-21 16:23:36 +0000
+++ debian/control 2020-11-30 16:25:32 +0000
@@ -11,7 +11,7 @@
xsltproc, pkg-config, libnl-route-3-dev, systemd
Build-Depends-Indep: python3 (>= 3), python3-dbus, python3-gi,
po-debconf
-Standards-Version: 4.5.0
+Standards-Version: 4.5.1
Vcs-Bzr: https://ftp.recompile.se/pub/mandos/trunk
Vcs-Browser: https://bzr.recompile.se/loggerhead/mandos/trunk/files
Homepage: https://www.recompile.se/mandos
=== modified file 'debian/mandos-client.templates'
--- debian/mandos-client.templates 2019-08-05 21:00:35 +0000
+++ debian/mandos-client.templates 2020-11-30 16:19:48 +0000
@@ -1,6 +1,6 @@
Template: mandos-client/key_id
Type: note
-_description: New client option "${key_id}" is REQUIRED on server
+_Description: New client option "${key_id}" is REQUIRED on server
A new "key_id" client option is REQUIRED in the server's clients.conf
file, otherwise this computer most likely will not reboot unattended.
This option:
=== modified file 'dracut-module/password-agent.c'
--- dracut-module/password-agent.c 2020-07-04 11:58:52 +0000
+++ dracut-module/password-agent.c 2020-11-29 22:54:26 +0000
@@ -1193,8 +1193,8 @@
bool *const password_is_read = task.password_is_read;
/* We use the GLib "Key-value file parser" functions to parse the
- question file. See for specification of contents */
+ question file. See for
+ specification of contents */
__attribute__((nonnull))
void cleanup_g_key_file(GKeyFile **key_file){
if(*key_file != NULL){
@@ -1490,8 +1490,8 @@
not. You may but don't have to include a final NUL byte in
your message.
- — (Wed 08 Oct 2014 02:14:28 AM UTC)
+ — (Tue, 15 Sep 2020
+ 14:24:20 GMT)
*/
send_buffer[0] = '+'; /* Prefix with "+" */
/* Always add an extra NUL */
@@ -1502,7 +1502,7 @@
errno = 0;
ssize_t ssret = send(fd, send_buffer, send_buffer_length,
MSG_NOSIGNAL);
- const error_t saved_errno = errno;
+ const error_t saved_errno = (ssret < 0) ? errno : 0;
#if defined(__GLIBC_PREREQ) and __GLIBC_PREREQ(2, 25)
explicit_bzero(send_buffer, send_buffer_length);
#else
@@ -1526,8 +1526,8 @@
/* Retry, below */
break;
case EMSGSIZE:
- error(0, 0, "Password of size %" PRIuMAX " is too big",
- (uintmax_t)password->length);
+ error(0, saved_errno, "Password of size %" PRIuMAX
+ " is too big", (uintmax_t)password->length);
#if __GNUC__ < 7
/* FALLTHROUGH */
#else
@@ -1535,7 +1535,9 @@
#endif
case 0:
if(ssret >= 0 and ssret < (ssize_t)send_buffer_length){
- error(0, 0, "Password only partially sent to socket");
+ error(0, 0, "Password only partially sent to socket %s: %"
+ PRIuMAX " out of %" PRIuMAX " bytes sent", filename,
+ (uintmax_t)ssret, (uintmax_t)send_buffer_length);
}
#if __GNUC__ < 7
/* FALLTHROUGH */
@@ -5807,7 +5809,7 @@
char write_data[PIPE_BUF];
{
/* Construct test password buffer */
- /* Start with + since that is what the real procotol uses */
+ /* Start with + since that is what the real protocol uses */
write_data[0] = '+';
/* Set a special character at string end just to mark the end */
write_data[sizeof(write_data)-2] = 'y';
@@ -5958,9 +5960,6 @@
test_fixture *fixture,
__attribute__((unused))
gconstpointer user_data){
-#ifndef __amd64__
- g_test_skip("Skipping EMSGSIZE test on non-AMD64 platform");
-#else
__attribute__((cleanup(cleanup_close)))
const int epoll_fd = epoll_create1(EPOLL_CLOEXEC);
g_assert_cmpint(epoll_fd, >=, 0);
@@ -5968,31 +5967,68 @@
char *const filename = strdup("/nonexistent/socket");
__attribute__((cleanup(string_set_clear)))
string_set cancelled_filenames = {};
- const size_t oversized = 1024*1024; /* Limit seems to be 212960 */
- __attribute__((cleanup(cleanup_buffer)))
- buffer password = {
- .data=malloc(oversized),
- .length=oversized,
- .allocated=oversized,
+ int socketfds[2];
+
+ /* Find a message size which triggers EMSGSIZE */
+ __attribute__((cleanup(cleanup_string)))
+ char *message_buffer = NULL;
+ size_t message_size = PIPE_BUF + 1;
+ for(ssize_t ssret = 0; ssret >= 0; message_size += 1024){
+ if(message_size >= 1024*1024*1024){ /* 1 GiB */
+ g_test_skip("Skipping EMSGSIZE test: Will not try 1GiB");
+ return;
+ }
+ free(message_buffer);
+ message_buffer = malloc(message_size);
+ if(message_buffer == NULL){
+ g_test_skip("Skipping EMSGSIZE test");
+ g_test_message("Failed to malloc() %" PRIuMAX " bytes",
+ (uintmax_t)message_size);
+ return;
+ }
+ /* Fill buffer with 'x' */
+ memset(message_buffer, 'x', message_size);
+ /* Create a new socketpair for each message size to avoid having
+ to empty the pipe by reading the message to a separate buffer
+ */
+ g_assert_cmpint(socketpair(PF_LOCAL, SOCK_DGRAM
+ | SOCK_NONBLOCK | SOCK_CLOEXEC, 0,
+ socketfds), ==, 0);
+ ssret = send(socketfds[1], message_buffer, message_size,
+ MSG_NOSIGNAL);
+ error_t saved_errno = errno;
+ g_assert_cmpint(close(socketfds[0]), ==, 0);
+ g_assert_cmpint(close(socketfds[1]), ==, 0);
+
+ if(ssret < 0){
+ if(saved_errno != EMSGSIZE) {
+ g_test_skip("Skipping EMSGSIZE test");
+ g_test_message("Error on send(): %s", strerror(saved_errno));
+ return;
+ }
+ } else if(ssret != (ssize_t)message_size){
+ g_test_skip("Skipping EMSGSIZE test");
+ g_test_message("Partial send(): %" PRIuMAX " of %" PRIdMAX
+ " bytes", (uintmax_t)ssret,
+ (intmax_t)message_size);
+ return;
+ }
+ }
+ g_test_message("EMSGSIZE triggered by %" PRIdMAX " bytes",
+ (intmax_t)message_size);
+
+ buffer password = {
+ .data=message_buffer,
+ .length=message_size - 2, /* Compensate for added '+' and NUL */
+ .allocated=message_size,
};
- g_assert_nonnull(password.data);
if(mlock(password.data, password.allocated) != 0){
g_assert_true(errno == EPERM or errno == ENOMEM);
}
- /* Construct test password buffer */
- /* Start with + since that is what the real procotol uses */
- password.data[0] = '+';
- /* Set a special character at string end just to mark the end */
- password.data[oversized-3] = 'y';
- /* Set NUL at buffer end, as suggested by the protocol */
- password.data[oversized-2] = '\0';
- /* Fill rest of password with 'x' */
- memset(password.data+1, 'x', oversized-3);
__attribute__((cleanup(cleanup_queue)))
task_queue *queue = create_queue();
g_assert_nonnull(queue);
- int socketfds[2];
g_assert_cmpint(socketpair(PF_LOCAL, SOCK_DGRAM
| SOCK_NONBLOCK | SOCK_CLOEXEC, 0,
socketfds), ==, 0);
@@ -6019,7 +6055,6 @@
g_assert_cmpuint((unsigned int)queue->length, ==, 0);
g_assert_true(string_set_contains(cancelled_filenames,
question_filename));
-#endif
}
static void test_send_password_to_socket_retry(__attribute__((unused))
=== modified file 'dracut-module/password-agent.xml'
--- dracut-module/password-agent.xml 2019-11-16 15:56:49 +0000
+++ dracut-module/password-agent.xml 2020-11-29 21:54:00 +0000
@@ -2,7 +2,7 @@
-
+
%common;
]>
@@ -113,9 +113,9 @@
be a systemd1Password
Agent (See Password Agents). The aim of this program is therefore
- to acquire and then send a password to some other program which
+ url="https://systemd.io/PASSWORD_AGENTS/">Password
+ Agents). The aim of this program is therefore to
+ acquire and then send a password to some other program which
will use the password to unlock the encrypted root disk.
@@ -146,9 +146,8 @@
Specify a different agent directory. The default is
/run/systemd/ask-password as per the
- Password Agents specification.
+ Password
+ Agents specification.
@@ -270,8 +269,8 @@
responsible for getting a password from the Mandos client
program itself, and to send that password to whatever is
currently asking for a password using the systemd Password Agents mechanism.
+ url="https://systemd.io/PASSWORD_AGENTS/">Password
+ Agents mechanism.
To accomplish this, &COMMANDNAME; runs the
mandos-client program (which is the actual
@@ -281,9 +280,8 @@
password is acquired from the
MANDOS_CLIENT program, sends that
password (as per the Password Agents specification) to all currently
- unanswered password questions.
+ url="https://systemd.io/PASSWORD_AGENTS/">Password Agents
+ specification) to all currently unanswered password questions.
This program should be started (normally as a systemd service,
@@ -330,9 +328,9 @@
The default directory to watch for password questions as
per the Password Agents specification; can be changed
- by the option.
+ url="https://systemd.io/PASSWORD_AGENTS/">Password
+ Agents specification; can be changed by the
+ option.
@@ -446,9 +444,8 @@
- Password Agents
+ Password
+ Agents
=== modified file 'intro.xml'
--- intro.xml 2019-08-04 12:42:49 +0000
+++ intro.xml 2020-11-29 21:54:00 +0000
@@ -1,7 +1,7 @@
+
%common;
]>
@@ -403,11 +403,11 @@
As for systemd1 in particular, it has
its own Password Agents system. Mandos uses this via its
+ url="https://systemd.io/PASSWORD_AGENTS/">Password
+ Agents system. Mandos uses this via its
password-agent8mandos program, which
- is run instead of 8mandos program, which is
+ run instead of plugin-runner8mandos when systemd1
=== modified file 'mandos'
--- mandos 2020-07-04 13:00:37 +0000
+++ mandos 2020-08-14 20:34:56 +0000
@@ -524,7 +524,8 @@
class AvahiServiceToSyslog(AvahiService):
def rename(self, *args, **kwargs):
"""Add the new name to the syslog messages"""
- ret = super(AvahiServiceToSyslog, self).rename(*args, **kwargs)
+ ret = super(AvahiServiceToSyslog, self).rename(*args,
+ **kwargs)
syslogger.setFormatter(logging.Formatter(
'Mandos ({}) [%(process)d]: %(levelname)s: %(message)s'
.format(self.name)))
@@ -774,7 +775,8 @@
x509_crt_fmt_t = ctypes.c_int
- # All the function declarations below are from gnutls/abstract.h
+ # All the function declarations below are from
+ # gnutls/abstract.h
pubkey_init = _library.gnutls_pubkey_init
pubkey_init.argtypes = [ctypes.POINTER(pubkey_t)]
pubkey_init.restype = _error_code
@@ -794,7 +796,8 @@
pubkey_deinit.argtypes = [pubkey_t]
pubkey_deinit.restype = None
else:
- # All the function declarations below are from gnutls/openpgp.h
+ # All the function declarations below are from
+ # gnutls/openpgp.h
openpgp_crt_init = _library.gnutls_openpgp_crt_init
openpgp_crt_init.argtypes = [ctypes.POINTER(openpgp_crt_t)]
@@ -806,9 +809,13 @@
openpgp_crt_fmt_t]
openpgp_crt_import.restype = _error_code
- openpgp_crt_verify_self = _library.gnutls_openpgp_crt_verify_self
- openpgp_crt_verify_self.argtypes = [openpgp_crt_t, ctypes.c_uint,
- ctypes.POINTER(ctypes.c_uint)]
+ openpgp_crt_verify_self = \
+ _library.gnutls_openpgp_crt_verify_self
+ openpgp_crt_verify_self.argtypes = [
+ openpgp_crt_t,
+ ctypes.c_uint,
+ ctypes.POINTER(ctypes.c_uint),
+ ]
openpgp_crt_verify_self.restype = _error_code
openpgp_crt_deinit = _library.gnutls_openpgp_crt_deinit
@@ -2468,11 +2475,12 @@
buf = ctypes.create_string_buffer(32)
buf_len = ctypes.c_size_t(len(buf))
# Get the key ID from the raw public key into the buffer
- gnutls.pubkey_get_key_id(pubkey,
- gnutls.KEYID_USE_SHA256,
- ctypes.cast(ctypes.byref(buf),
- ctypes.POINTER(ctypes.c_ubyte)),
- ctypes.byref(buf_len))
+ gnutls.pubkey_get_key_id(
+ pubkey,
+ gnutls.KEYID_USE_SHA256,
+ ctypes.cast(ctypes.byref(buf),
+ ctypes.POINTER(ctypes.c_ubyte)),
+ ctypes.byref(buf_len))
# Deinit the certificate
gnutls.pubkey_deinit(pubkey)
@@ -2723,7 +2731,8 @@
address = request[3]
for c in self.clients.values():
- if key_id == "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855":
+ if key_id == ("E3B0C44298FC1C149AFBF4C8996FB924"
+ "27AE41E4649B934CA495991B7852B855"):
continue
if key_id and c.key_id == key_id:
client = c
@@ -2781,20 +2790,22 @@
def rfc3339_duration_to_delta(duration):
"""Parse an RFC 3339 "duration" and return a datetime.timedelta
- >>> rfc3339_duration_to_delta("P7D") == datetime.timedelta(7)
- True
- >>> rfc3339_duration_to_delta("PT60S") == datetime.timedelta(0, 60)
- True
- >>> rfc3339_duration_to_delta("PT60M") == datetime.timedelta(0, 3600)
- True
- >>> rfc3339_duration_to_delta("PT24H") == datetime.timedelta(1)
- True
- >>> rfc3339_duration_to_delta("P1W") == datetime.timedelta(7)
- True
- >>> rfc3339_duration_to_delta("PT5M30S") == datetime.timedelta(0, 330)
- True
- >>> rfc3339_duration_to_delta("P1DT3M20S") == datetime.timedelta(1, 200)
- True
+ >>> timedelta = datetime.timedelta
+ >>> rfc3339_duration_to_delta("P7D") == timedelta(7)
+ True
+ >>> rfc3339_duration_to_delta("PT60S") == timedelta(0, 60)
+ True
+ >>> rfc3339_duration_to_delta("PT60M") == timedelta(0, 3600)
+ True
+ >>> rfc3339_duration_to_delta("PT24H") == timedelta(1)
+ True
+ >>> rfc3339_duration_to_delta("P1W") == timedelta(7)
+ True
+ >>> rfc3339_duration_to_delta("PT5M30S") == timedelta(0, 330)
+ True
+ >>> rfc3339_duration_to_delta("P1DT3M20S") == timedelta(1, 200)
+ True
+ >>> del timedelta
"""
# Parsing an RFC 3339 duration with regular expressions is not