Compare commits

...

8 Commits

Author SHA1 Message Date
Chris Down 80cc3e3eab virt: Detect proot virtualisation by ptrace metadata
proot provides userspace-powered emulation of chroot and mount --bind,
lending it to be used on environments without unprivileged user
namespaces, or in otherwise restricted environments like Android.

In order to achieve this, proot makes use of the kernel's ptrace()
facility, which we can use in order to detect its presence. Since it
doesn't use any kind of namespacing, including PID namespacing, we don't
need to do any tricks when trying to get the tracer's metadata.

For our purposes, proot is listed as a "container", since we mostly use
this also as the bucket for non-container-but-container-like
technologies like WSL. As such, it seems like a good fit for this
section as well.
2020-04-15 18:36:35 +01:00
Lennart Poettering 6ab2e1178e
Merge pull request #15431 from poettering/lock-and-key-emoji
display lock/key emoji when prompting for passwords
2020-04-15 17:55:21 +02:00
Lennart Poettering f4ff71b360 man: update os-release(5) to use 24bit ANSI color in example
Given that ANSI_COLOR= is mostly about branding it probably makes sense
to use RGB rather than paletted colors for them, so that the colors
match the project design as close as possible. Hence, provide a 25bit
RGB example for ANSI_COLOR, and update the overall example to something
newer.

Also see: https://bugzilla.redhat.com/show_bug.cgi?id=1823099
2020-04-15 16:30:57 +02:00
Zbigniew Jędrzejewski-Szmek 3614df0575 meson,resolved: make default LLMNR= and MulticastDNS= values configurable
For https://fedoraproject.org/wiki/Changes/systemd-resolved.
2020-04-15 14:37:21 +02:00
Lennart Poettering e3ac53a27d ask-password-api: reword some debug messages
Otherwise, seeing this in the log output is confusing since we don't
know what kind of timeout or what kind if key we are adjusting here.
2020-04-15 12:04:35 +02:00
Lennart Poettering 52d199e318 ask-password: prefix password questions with lock and key emoji
It's pretty, and it highlights that the pw prompt is kinda special and
needs user input.

We suppress the emoji entirel if there's no emoji support (i.e. this
means we suppress the ASCII replacement), since it carries no additional
information, it is just decoration to highlight a line.
2020-04-15 12:04:23 +02:00
Lennart Poettering 539ee0989e locale-util: export emoji_enable() for other code to use 2020-04-15 12:04:08 +02:00
Lennart Poettering 48d70b4ac9 locale-util: add support for lock+key emoji
It looks pretty nice on gnome-terminal at least, let's make use of it
when asking for passwords.
2020-04-15 12:03:31 +02:00
13 changed files with 92 additions and 26 deletions

View File

@ -192,13 +192,11 @@
<varlistentry> <varlistentry>
<term><varname>ANSI_COLOR=</varname></term> <term><varname>ANSI_COLOR=</varname></term>
<listitem><para>A suggested presentation color when showing <listitem><para>A suggested presentation color when showing the OS name on the console. This should
the OS name on the console. This should be specified as string be specified as string suitable for inclusion in the ESC [ m ANSI/ECMA-48 escape code for setting
suitable for inclusion in the ESC [ m ANSI/ECMA-48 escape code graphical rendition. This field is optional. Example: <literal>ANSI_COLOR="0;31"</literal> for red,
for setting graphical rendition. This field is optional. <literal>ANSI_COLOR="1;34"</literal> for light blue, or
Example: <literal>ANSI_COLOR="0;31"</literal> for red, or <literal>ANSI_COLOR="0;38;2;60;110;180"</literal> for Fedora blue.</para></listitem>
<literal>ANSI_COLOR="1;34"</literal> for light
blue.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -347,14 +345,24 @@
<title>Example</title> <title>Example</title>
<programlisting>NAME=Fedora <programlisting>NAME=Fedora
VERSION="17 (Beefy Miracle)" VERSION="32 (Workstation Edition)"
ID=fedora ID=fedora
VERSION_ID=17 VERSION_ID=32
PRETTY_NAME="Fedora 17 (Beefy Miracle)" PRETTY_NAME="Fedora 32 (Workstation Edition)"
ANSI_COLOR="0;34" ANSI_COLOR="0;38;2;60;110;180"
CPE_NAME="cpe:/o:fedoraproject:fedora:17" LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:32"
HOME_URL="https://fedoraproject.org/" HOME_URL="https://fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"</programlisting> DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f32/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=32
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=32
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Workstation Edition"
VARIANT_ID=workstation</programlisting>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@ -167,6 +167,11 @@
<entry><varname>wsl</varname></entry> <entry><varname>wsl</varname></entry>
<entry><ulink url="https://docs.microsoft.com/en-us/windows/wsl/about">Windows Subsystem for Linux</ulink></entry> <entry><ulink url="https://docs.microsoft.com/en-us/windows/wsl/about">Windows Subsystem for Linux</ulink></entry>
</row> </row>
<row>
<entry><varname>proot</varname></entry>
<entry><ulink url="https://proot-me.github.io/">proot</ulink> userspace chroot/bind mount emulation</entry>
</row>
</tbody> </tbody>
</tgroup> </tgroup>
</table> </table>

View File

@ -1170,6 +1170,7 @@
<literal>podman</literal>, <literal>podman</literal>,
<literal>rkt</literal>, <literal>rkt</literal>,
<literal>wsl</literal>, <literal>wsl</literal>,
<literal>proot</literal>,
<literal>acrn</literal> to test <literal>acrn</literal> to test
against a specific implementation, or against a specific implementation, or
<literal>private-users</literal> to check whether we are running in a user namespace. See <literal>private-users</literal> to check whether we are running in a user namespace. See

View File

@ -1302,6 +1302,16 @@ conf.set('DEFAULT_DNS_OVER_TLS_MODE',
'DNS_OVER_TLS_' + default_dns_over_tls.underscorify().to_upper()) 'DNS_OVER_TLS_' + default_dns_over_tls.underscorify().to_upper())
substs.set('DEFAULT_DNS_OVER_TLS_MODE', default_dns_over_tls) substs.set('DEFAULT_DNS_OVER_TLS_MODE', default_dns_over_tls)
default_mdns = get_option('default-mdns')
conf.set('DEFAULT_MDNS_MODE',
'RESOLVE_SUPPORT_' + default_mdns.to_upper())
substs.set('DEFAULT_MDNS_MODE', default_mdns)
default_llmnr = get_option('default-llmnr')
conf.set('DEFAULT_LLMNR_MODE',
'RESOLVE_SUPPORT_' + default_llmnr.to_upper())
substs.set('DEFAULT_LLMNR_MODE', default_llmnr)
want_repart = get_option('repart') want_repart = get_option('repart')
if want_repart != 'false' if want_repart != 'false'
have = (conf.get('HAVE_OPENSSL') == 1 and have = (conf.get('HAVE_OPENSSL') == 1 and
@ -3354,6 +3364,8 @@ status = [
'default DNSSEC mode: @0@'.format(default_dnssec), 'default DNSSEC mode: @0@'.format(default_dnssec),
'default DNS-over-TLS mode: @0@'.format(default_dns_over_tls), 'default DNS-over-TLS mode: @0@'.format(default_dns_over_tls),
'default mDNS mode: @0@'.format(default_mdns),
'default LLMNR mode: @0@'.format(default_llmnr),
'default cgroup hierarchy: @0@'.format(default_hierarchy), 'default cgroup hierarchy: @0@'.format(default_hierarchy),
'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme), 'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme),
'default KillUserProcesses setting: @0@'.format(kill_user_processes), 'default KillUserProcesses setting: @0@'.format(kill_user_processes),

View File

@ -230,6 +230,14 @@ option('default-dns-over-tls', type : 'combo',
description : 'default DNS-over-TLS mode', description : 'default DNS-over-TLS mode',
choices : ['yes', 'opportunistic', 'no'], choices : ['yes', 'opportunistic', 'no'],
value : 'no') value : 'no')
option('default-mdns', type : 'combo',
choices : ['yes', 'resolve', 'no'],
description : 'default MulticastDNS mode',
value : 'yes')
option('default-llmnr', type : 'combo',
choices : ['yes', 'resolve', 'no'],
description : 'default LLMNR mode',
value : 'yes')
option('dns-over-tls', type : 'combo', choices : ['auto', 'gnutls', 'openssl', 'true', 'false'], option('dns-over-tls', type : 'combo', choices : ['auto', 'gnutls', 'openssl', 'true', 'false'],
description : 'DNS-over-TLS support') description : 'DNS-over-TLS support')
option('dns-servers', type : 'string', option('dns-servers', type : 'string',

View File

@ -305,7 +305,7 @@ out:
return (bool) cached_answer; return (bool) cached_answer;
} }
static bool emoji_enabled(void) { bool emoji_enabled(void) {
static int cached_emoji_enabled = -1; static int cached_emoji_enabled = -1;
if (cached_emoji_enabled < 0) { if (cached_emoji_enabled < 0) {
@ -357,6 +357,7 @@ const char *special_glyph(SpecialGlyph code) {
[SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = ":-(", [SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = ":-(",
[SPECIAL_GLYPH_UNHAPPY_SMILEY] = ":-{", [SPECIAL_GLYPH_UNHAPPY_SMILEY] = ":-{",
[SPECIAL_GLYPH_DEPRESSED_SMILEY] = ":-[", [SPECIAL_GLYPH_DEPRESSED_SMILEY] = ":-[",
[SPECIAL_GLYPH_LOCK_AND_KEY] = "o-,"
}, },
/* UTF-8 */ /* UTF-8 */
@ -392,12 +393,15 @@ const char *special_glyph(SpecialGlyph code) {
[SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = "\360\237\231\201", /* 🙁 (actually called: SLIGHTLY FROWNING FACE) */ [SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = "\360\237\231\201", /* 🙁 (actually called: SLIGHTLY FROWNING FACE) */
[SPECIAL_GLYPH_UNHAPPY_SMILEY] = "\360\237\230\250", /* 😨 (actually called: FEARFUL FACE) */ [SPECIAL_GLYPH_UNHAPPY_SMILEY] = "\360\237\230\250", /* 😨 (actually called: FEARFUL FACE) */
[SPECIAL_GLYPH_DEPRESSED_SMILEY] = "\360\237\244\242", /* 🤢 (actually called: NAUSEATED FACE) */ [SPECIAL_GLYPH_DEPRESSED_SMILEY] = "\360\237\244\242", /* 🤢 (actually called: NAUSEATED FACE) */
/* This emoji is a single character cell glyph in Unicode, and three in ASCII */
[SPECIAL_GLYPH_LOCK_AND_KEY] = "\360\237\224\220", /* 🔐 (actually called: CLOSED LOCK WITH KEY) */
}, },
}; };
assert(code < _SPECIAL_GLYPH_MAX); assert(code < _SPECIAL_GLYPH_MAX);
return draw_table[code >= _SPECIAL_GLYPH_FIRST_SMILEY ? emoji_enabled() : is_locale_utf8()][code]; return draw_table[code >= _SPECIAL_GLYPH_FIRST_EMOJI ? emoji_enabled() : is_locale_utf8()][code];
} }
void locale_variables_free(char *l[_VARIABLE_LC_MAX]) { void locale_variables_free(char *l[_VARIABLE_LC_MAX]) {

View File

@ -54,19 +54,22 @@ typedef enum {
SPECIAL_GLYPH_LIGHT_SHADE, SPECIAL_GLYPH_LIGHT_SHADE,
SPECIAL_GLYPH_DARK_SHADE, SPECIAL_GLYPH_DARK_SHADE,
SPECIAL_GLYPH_SIGMA, SPECIAL_GLYPH_SIGMA,
_SPECIAL_GLYPH_FIRST_SMILEY, _SPECIAL_GLYPH_FIRST_EMOJI,
SPECIAL_GLYPH_ECSTATIC_SMILEY = _SPECIAL_GLYPH_FIRST_SMILEY, SPECIAL_GLYPH_ECSTATIC_SMILEY = _SPECIAL_GLYPH_FIRST_EMOJI,
SPECIAL_GLYPH_HAPPY_SMILEY, SPECIAL_GLYPH_HAPPY_SMILEY,
SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY, SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY,
SPECIAL_GLYPH_NEUTRAL_SMILEY, SPECIAL_GLYPH_NEUTRAL_SMILEY,
SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY, SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY,
SPECIAL_GLYPH_UNHAPPY_SMILEY, SPECIAL_GLYPH_UNHAPPY_SMILEY,
SPECIAL_GLYPH_DEPRESSED_SMILEY, SPECIAL_GLYPH_DEPRESSED_SMILEY,
SPECIAL_GLYPH_LOCK_AND_KEY,
_SPECIAL_GLYPH_MAX _SPECIAL_GLYPH_MAX
} SpecialGlyph; } SpecialGlyph;
const char *special_glyph(SpecialGlyph code) _const_; const char *special_glyph(SpecialGlyph code) _const_;
bool emoji_enabled(void);
const char* locale_variable_to_string(LocaleVariable i) _const_; const char* locale_variable_to_string(LocaleVariable i) _const_;
LocaleVariable locale_variable_from_string(const char *s) _pure_; LocaleVariable locale_variable_from_string(const char *s) _pure_;

View File

@ -441,6 +441,7 @@ static const char *const container_table[_VIRTUALIZATION_MAX] = {
[VIRTUALIZATION_PODMAN] = "podman", [VIRTUALIZATION_PODMAN] = "podman",
[VIRTUALIZATION_RKT] = "rkt", [VIRTUALIZATION_RKT] = "rkt",
[VIRTUALIZATION_WSL] = "wsl", [VIRTUALIZATION_WSL] = "wsl",
[VIRTUALIZATION_PROOT] = "proot",
}; };
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int); DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int);
@ -449,6 +450,7 @@ int detect_container(void) {
static thread_local int cached_found = _VIRTUALIZATION_INVALID; static thread_local int cached_found = _VIRTUALIZATION_INVALID;
_cleanup_free_ char *m = NULL; _cleanup_free_ char *m = NULL;
_cleanup_free_ char *o = NULL; _cleanup_free_ char *o = NULL;
_cleanup_free_ char *p = NULL;
const char *e = NULL; const char *e = NULL;
int r; int r;
@ -472,6 +474,22 @@ int detect_container(void) {
goto finish; goto finish;
} }
/* proot doesn't use PID namespacing, so we can just check if we have a matching tracer for this
* invocation without worrying about it being elsewhere.
*/
r = get_proc_field("/proc/self/status", "TracerPid", WHITESPACE, &p);
if (r == 0 && !streq(p, "0")) {
pid_t ptrace_pid;
r = parse_pid(p, &ptrace_pid);
if (r == 0) {
const char *pf = procfs_file_alloca(ptrace_pid, "comm");
_cleanup_free_ char *ptrace_comm = NULL;
r = read_one_line_file(pf, &ptrace_comm);
if (r >= 0 && startswith(ptrace_comm, "proot"))
return VIRTUALIZATION_PROOT;
}
}
if (getpid_cached() == 1) { if (getpid_cached() == 1) {
/* If we are PID 1 we can just check our own environment variable, and that's authoritative. /* If we are PID 1 we can just check our own environment variable, and that's authoritative.
* We distinguish three cases: * We distinguish three cases:
@ -660,6 +678,7 @@ static const char *const virtualization_table[_VIRTUALIZATION_MAX] = {
[VIRTUALIZATION_PODMAN] = "podman", [VIRTUALIZATION_PODMAN] = "podman",
[VIRTUALIZATION_RKT] = "rkt", [VIRTUALIZATION_RKT] = "rkt",
[VIRTUALIZATION_WSL] = "wsl", [VIRTUALIZATION_WSL] = "wsl",
[VIRTUALIZATION_PROOT] = "proot",
[VIRTUALIZATION_CONTAINER_OTHER] = "container-other", [VIRTUALIZATION_CONTAINER_OTHER] = "container-other",
}; };

View File

@ -34,6 +34,7 @@ enum {
VIRTUALIZATION_PODMAN, VIRTUALIZATION_PODMAN,
VIRTUALIZATION_RKT, VIRTUALIZATION_RKT,
VIRTUALIZATION_WSL, VIRTUALIZATION_WSL,
VIRTUALIZATION_PROOT,
VIRTUALIZATION_CONTAINER_OTHER, VIRTUALIZATION_CONTAINER_OTHER,
VIRTUALIZATION_CONTAINER_LAST = VIRTUALIZATION_CONTAINER_OTHER, VIRTUALIZATION_CONTAINER_LAST = VIRTUALIZATION_CONTAINER_OTHER,

View File

@ -581,8 +581,8 @@ int manager_new(Manager **ret) {
.dns_stub_tcp_fd = -1, .dns_stub_tcp_fd = -1,
.hostname_fd = -1, .hostname_fd = -1,
.llmnr_support = RESOLVE_SUPPORT_YES, .llmnr_support = DEFAULT_LLMNR_MODE,
.mdns_support = RESOLVE_SUPPORT_YES, .mdns_support = DEFAULT_MDNS_MODE,
.dnssec_mode = DEFAULT_DNSSEC_MODE, .dnssec_mode = DEFAULT_DNSSEC_MODE,
.dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE, .dns_over_tls_mode = DEFAULT_DNS_OVER_TLS_MODE,
.enable_cache = DNS_CACHE_MODE_YES, .enable_cache = DNS_CACHE_MODE_YES,

View File

@ -15,10 +15,10 @@
#DNS= #DNS=
#FallbackDNS=@DNS_SERVERS@ #FallbackDNS=@DNS_SERVERS@
#Domains= #Domains=
#LLMNR=yes
#MulticastDNS=yes
#DNSSEC=@DEFAULT_DNSSEC_MODE@ #DNSSEC=@DEFAULT_DNSSEC_MODE@
#DNSOverTLS=@DEFAULT_DNS_OVER_TLS_MODE@ #DNSOverTLS=@DEFAULT_DNS_OVER_TLS_MODE@
#MulticastDNS=@DEFAULT_MDNS_MODE@
#LLMNR=@DEFAULT_LLMNR_MODE@
#Cache=yes #Cache=yes
#DNSStubListener=yes #DNSStubListener=yes
#ReadEtcHosts=yes #ReadEtcHosts=yes

View File

@ -27,6 +27,7 @@
#include "format-util.h" #include "format-util.h"
#include "fs-util.h" #include "fs-util.h"
#include "io-util.h" #include "io-util.h"
#include "locale-util.h"
#include "log.h" #include "log.h"
#include "macro.h" #include "macro.h"
#include "memory-util.h" #include "memory-util.h"
@ -134,12 +135,12 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
if (keyctl(KEYCTL_SET_TIMEOUT, if (keyctl(KEYCTL_SET_TIMEOUT,
(unsigned long) serial, (unsigned long) serial,
(unsigned long) DIV_ROUND_UP(KEYRING_TIMEOUT_USEC, USEC_PER_SEC), 0, 0) < 0) (unsigned long) DIV_ROUND_UP(KEYRING_TIMEOUT_USEC, USEC_PER_SEC), 0, 0) < 0)
log_debug_errno(errno, "Failed to adjust timeout: %m"); log_debug_errno(errno, "Failed to adjust kernel keyring key timeout: %m");
/* Tell everyone to check the keyring */ /* Tell everyone to check the keyring */
(void) touch("/run/systemd/ask-password"); (void) touch("/run/systemd/ask-password");
log_debug("Added key to keyring as %" PRIi32 ".", serial); log_debug("Added key to kernel keyring as %" PRIi32 ".", serial);
return 1; return 1;
} }
@ -151,7 +152,7 @@ static int add_to_keyring_and_log(const char *keyname, AskPasswordFlags flags, c
r = add_to_keyring(keyname, flags, passwords); r = add_to_keyring(keyname, flags, passwords);
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to add password to keyring: %m"); return log_debug_errno(r, "Failed to add password to kernel keyring: %m");
return 0; return 0;
} }
@ -430,6 +431,9 @@ int ask_password_tty(
if (!message) if (!message)
message = "Password:"; message = "Password:";
if (emoji_enabled())
message = strjoina(special_glyph(SPECIAL_GLYPH_LOCK_AND_KEY), " ", message);
if (flag_file || ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname)) { if (flag_file || ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname)) {
notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK); notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
if (notify < 0) if (notify < 0)

View File

@ -67,7 +67,7 @@ static void test_keymaps(void) {
#define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x)) #define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
static void dump_special_glyphs(void) { static void dump_special_glyphs(void) {
assert_cc(SPECIAL_GLYPH_DEPRESSED_SMILEY + 1 == _SPECIAL_GLYPH_MAX); assert_cc(SPECIAL_GLYPH_LOCK_AND_KEY + 1 == _SPECIAL_GLYPH_MAX);
log_info("/* %s */", __func__); log_info("/* %s */", __func__);
@ -92,6 +92,7 @@ static void dump_special_glyphs(void) {
dump_glyph(SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY); dump_glyph(SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY);
dump_glyph(SPECIAL_GLYPH_UNHAPPY_SMILEY); dump_glyph(SPECIAL_GLYPH_UNHAPPY_SMILEY);
dump_glyph(SPECIAL_GLYPH_DEPRESSED_SMILEY); dump_glyph(SPECIAL_GLYPH_DEPRESSED_SMILEY);
dump_glyph(SPECIAL_GLYPH_LOCK_AND_KEY);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {