On Sat, 2015-05-02 at 01:54 +0300, Alon Bar-Lev wrote:
> PKCS#11 explicitly states that C_Initialize must be called post 
> fork().

Hi Alon, thanks for the quick response and the citation from the spec;
I had looked briefly and not yet found that.

It's quite clear, as I had assumed, that your code in pkcs11-helper is
doing the right thing.

> > Firstly, OpenVPN is forking to spawn systemd-ask-password from
> > *within* the PIN request callback, which is expressly forbidden and
> > leads directly to a deadlock.
> 
> This is common misconception of what smartcards are.
> 1. On startup it is not guaranteed that smartcard is even inserted into 
> reader.
> 2. A smartcard can be removed during program execution.
> 3. A smartcard can be inserted into different reader (or dynamic reader).
> 4. Wrong smartcard can be inserted, and avoid to be locked.
> 5. PIN policy of card may differ, the exact point in time in which PIN
> is required is unknown.

That's why we have callbacks. You call back from pkcs11-helper into
the application when you need a PIN. As you say, the point in time
that such is required is unknown. Which is why we can't make life easy
by asking for it in advance.

I'm aware of the misconception you mention above, but I'm not sure why
you mention it here. OpenVPN doesn't seem to be guilty of it.

> not sure what systemd-ask-password is, but the proper interaction 
> with openvpn process in this case is via the management interface, 
> there is an example here[1].

It's a tool which gets spawned to ask the user (sysadmin) for a
password. I've never actually seen it working in practice, but I think
it's something vaguely similar to ssh-askpass.

I think it's designed to work even during a graphical boot sequence
before any real UI is present (for example for asking for root file
system encryption passphrases).

I am unfamiliar with the general design decisions around OpenVPN's
interaction with the user — I'm only trying to fix up the PKCS#11
support. But I think the management interface is *optional*.

> another issue is that most people running openvpn as root, hence
> smartcard interaction is performed using root, which is invalid, I
> recommend (and use) openvpn as non root process[2], in this method it
> is not required to run openvpn as daemon/background at all, and PIN
> entry is easier both when stdin/stdout are being used and when pin
> entry helper program is being used.

Users are seeing this particular issue even when OpenVPN is being run
in the foreground, and as non-root users. If I create a persistent tun
device and run as myself with --ifconfig-noexec, it still happens.

Perhaps one might argue this is simply a bug in OpenVPN — it
*shouldn't* be spawning the systemd password request tool in that
case. And that's 100% true for the PIN request, since the pkcs11
-helper documentation explicitly forbids the application from forking
in the PIN callback.

> what we do require is to move the entire processing of remote
> connection details, certificate enumeration and private key operations
> into the management interface, removing the PKCS#11 support from
> openvpn core, and move it into the management implementation, hence
> will always run at the user context. We discussed that in the past,
> not sure if someone promoted it.

I think the management interface has been able to provide a
certificate for a while. It's recently also gained the ability to
perform the signing step too, so we really can offload it all now.

Persuading the OpenVPN developers that such should be the *only*
possible mode of operation, however, is a different prospect :0

> > Secondly, even if we work around that by disabling systemd support, we
> > find that the OpenSC PKCS#11 module doesn't cope. It ends up confusing
> > pcscd by interacting with it over two separate connections, as
> > described at http://sourceforge.net/p/opensc/mailman/message/34073754/
> 
> this should be resolved by either OpenSC or pcscd (not sure where the
> problem is) to confirm with PKCS#11 spec.

Thanks for confirming that. I'll go back and resume that thread and
point the finger more squarely away from OpenVPN and pkcs11-helper :)

> > Third, the p11-kit-proxy.so module also doesn't cope, and suffers 
> > an
> > internal deadlock as described at
> > https://www.mail-archive.com/p11
> > -g...@lists.freedesktop.org/msg00126.html
> 
> again, if p11-kit-proxy violates the PKCS#11 spec it should be fixed.

Indeed. Thanks.

Although I do wonder how many other provider modules are going to
suffer similar issues, and it doesn't *hurt* to be defensive in
OpenVPN and use vfork() instead of fork(). I don't really see the down
-side.
 
> NAK my side, openvpn code is ok.

Well, not quite. Even apart from the 'be liberal in what you accept'
principle as discussed above, the systemd_ask_password handling is
clearly broken. And actually further testing shows that part is *not*
fixed by my patch, since I only modified openvpn_execve(). We can't
use vfork() in openvpn_popen() because that does other things between
the fork and the execve().

So we end up with this deadlock...

#0  0x00007f26e64a52c0 in __nanosleep_nocancel () at 
../sysdeps/unix/syscall-template.S:81
#1  0x00007f26e64d5b14 in usleep (useconds=<optimized out>) at 
../sysdeps/unix/sysv/linux/usleep.c:32
#2  0x00007f26e6ffb096 in _pkcs1h_threading_mutexLockAll () at 
pkcs11h-threading.c:306
#3  0x00007f26e64a5362 in __libc_fork () at ../sysdeps/nptl/fork.c:89
#4  0x00007f26e72224a5 in __fork () at pt-fork.c:25
#5  0x00007f26e8ff05e0 in openvpn_popen (a=a@entry=0x7ffdb20c87a0, 
es=es@entry=0x0) at misc.c:373
#6  0x00007f26e8ff23fd in get_console_input_systemd (capacity=4096, 
input=0x7ffdb20c9972 "", echo=<optimized out>, prompt=0x7f26e9e95d88 "Enter 
PIV_II (PIV Card Holder pin) token Password:") at console.c:172
#7  get_console_input (prompt=0x7f26e9e95d88 "Enter PIV_II (PIV Card Holder 
pin) token Password:", echo=echo@entry=false, input=input@entry=0x7ffdb20c9972 
"", capacity=capacity@entry=4096) at console.c:205
#8  0x00007f26e8fef7a8 in get_user_pass_cr (up=up@entry=0x7ffdb20c8970, 
auth_file=<optimized out>, auth_file@entry=0x0, 
prefix=prefix@entry=0x7ffdb20ca980 "PIV_II (PIV Card Holder pin) token", 
flags=flags@entry=21, auth_challenge=auth_challenge@entry=0x0) at misc.c:1146
#9  0x00007f26e8ffcfc8 in get_user_pass (flags=21, prefix=0x7ffdb20ca980 
"PIV_II (PIV Card Holder pin) token", auth_file=0x0, up=0x7ffdb20c8970) at 
misc.h:272
#10 _pkcs11_openvpn_pin_prompt (global_data=<optimized out>, 
user_data=<optimized out>, token=<optimized out>, retry=<optimized out>, 
pin=0x7ffdb20cadf0 "@\260\f\262\375\177", pin_max=1024) at pkcs11.c:235
#11 0x00007f26e6ffd0cb in _pkcs11h_session_login (session=0x7f26e9e41a30, 
is_publicOnly=is_publicOnly@entry=0, readonly=readonly@entry=1, user_data=0x0, 
mask_prompt=<optimized out>) at pkcs11h-session.c:1023

-- 
David Woodhouse                            Open Source Technology Centre
david.woodho...@intel.com                              Intel Corporation

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to