Ticket #538: 0001-pkcs11-Workaround-to-make-PKCS-11-PIN-token-work-wit.patch

File 0001-pkcs11-Workaround-to-make-PKCS-11-PIN-token-work-wit.patch, 7.6 KB (added by David Sommerseth, 6 years ago)

[Alternative patch] pkcs11: Workaround to make PKCS#11 PIN token work with systemd

  • src/openvpn/console.h

    From 612c9279dadebf832b69c97acfc43cf60f2400a7 Mon Sep 17 00:00:00 2001
    From: David Sommerseth <davids@openvpn.net>
    Date: Thu, 6 Sep 2018 11:57:02 +0200
    Subject: [PATCH] pkcs11: Workaround to make PKCS#11 PIN token work with
     systemd
    
    Due to an issue in the pkcs11-helper library, the systemd query
    mechanism makes OpenVPN go into a halt.  This is simply a workaround to
    force using the built-in user query mechanism for the PKCS#11 token PIN,
    regardless if systemd is used or not.
    
    Signed-off-by: David Sommerseth <davids@openvpn.net>
    ---
     src/openvpn/console.h         | 36 +++++++++++++++++++----------------
     src/openvpn/console_systemd.c |  2 +-
     src/openvpn/misc.c            | 20 ++++++++++++++-----
     src/openvpn/misc.h            |  1 +
     src/openvpn/pkcs11.c          |  6 ++++--
     5 files changed, 41 insertions(+), 24 deletions(-)
    
    diff --git a/src/openvpn/console.h b/src/openvpn/console.h
    index 5a70e5fd..b5f1ffaa 100644
    a b struct _query_user { 
    4242#define QUERY_USER_NUMSLOTS 10
    4343extern struct _query_user query_user[];  /**< Global variable, declared in console.c */
    4444
     45typedef enum {
     46                QUERYUSER_NO_ECHO,        /**< hide user input, used for passwords */
     47                QUERYUSER_FORCE_BUILTIN   /**< Force using the builtin query mechanism
     48                                               (pkcs11-helper workaround) */
     49} QueryFlags;
     50
    4551/**
    4652 * Wipes all data put into all of the query_user structs
    4753 *
    void query_user_add(char *prompt, size_t prompt_len, 
    7581bool query_user_exec_builtin(void);
    7682
    7783
    78 #if defined(ENABLE_SYSTEMD)
    7984/**
    8085 * Executes a configured setup, using the compiled method for querying the user
    8186 *
    bool query_user_exec_builtin(void); 
    8388 *
    8489 * @return True if executing all the defined steps completed successfully
    8590 */
    86 bool query_user_exec(void);
    87 
    88 #else  /* ENABLE_SYSTEMD not defined*/
    89 /**
    90  * Wrapper function enabling query_user_exec() if no alternative methods have
    91  * been enabled
    92  *
    93  */
    94 static bool
    95 query_user_exec(void)
     91static inline bool
     92query_user_exec(bool force_builtin)
    9693{
    97     return query_user_exec_builtin();
     94#ifdef ENABLE_SYSTEMD
     95        bool query_user_exec_systemd(void); /* console_systemd.c */
     96        if (!force_builtin)
     97        {
     98                return query_user_exec_systemd();
     99        }
     100#endif
     101        return query_user_exec_builtin();
    98102}
    99 #endif  /* defined(ENABLE_SYSTEMD) */
    100103
    101104
    102105/**
    query_user_exec(void) 
    109112static inline bool
    110113query_user_SINGLE(char *prompt, size_t prompt_len,
    111114                  char *resp, size_t resp_len,
    112                   bool echo)
     115                  QueryFlags flags)
    113116{
    114117    query_user_clear();
    115     query_user_add(prompt, prompt_len, resp, resp_len, echo);
    116     return query_user_exec();
     118    query_user_add(prompt, prompt_len, resp, resp_len,
     119                   (flags & QUERYUSER_NO_ECHO));
     120    return query_user_exec(flags & QUERYUSER_FORCE_BUILTIN);
    117121}
    118122
    119123#endif /* ifndef CONSOLE_H */
  • src/openvpn/console_systemd.c

    diff --git a/src/openvpn/console_systemd.c b/src/openvpn/console_systemd.c
    index e7a72ae3..af15f234 100644
    a b get_console_input_systemd(const char *prompt, const bool echo, char *input, cons 
    9595 *
    9696 */
    9797bool
    98 query_user_exec(void)
     98query_user_exec_systemd(void)
    9999{
    100100    bool ret = true;  /* Presume everything goes okay */
    101101    int i;
  • src/openvpn/misc.c

    diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c
    index 71fa2135..cd1d0684 100644
    a b get_user_pass_cr(struct user_pass *up, 
    186186
    187187            buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
    188188            if (!query_user_SINGLE(BSTR(&user_prompt), BLEN(&user_prompt),
    189                                    up->password, USER_PASS_LEN, false))
     189                                   up->password, USER_PASS_LEN,
     190                                   QUERYUSER_NO_ECHO))
    190191            {
    191192                msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
    192193            }
    get_user_pass_cr(struct user_pass *up, 
    285286                    buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text);
    286287                    buf_set_write(&packed_resp, (uint8_t *)up->password, USER_PASS_LEN);
    287288
     289                    QueryFlags qryflag = 0;
     290                    if (BOOL_CAST(ac->flags&CR_ECHO))
     291                    {
     292                        qryflag |= QUERYUSER_NO_ECHO;
     293                    }
    288294                    if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
    289                                            response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO)))
     295                                           response, USER_PASS_LEN, qryflag))
    290296                    {
    291297                        msg(M_FATAL, "ERROR: could not read challenge response from stdin");
    292298                    }
    get_user_pass_cr(struct user_pass *up, 
    320326                                   up->password, USER_PASS_LEN, false);
    321327                }
    322328
    323                 if (!query_user_exec() )
     329                if (!query_user_exec((flags & GET_USER_PASS_FORCE_BUILTIN)) )
    324330                {
    325331                    msg(M_FATAL, "ERROR: Failed retrieving username or password");
    326332                }
    get_user_pass_cr(struct user_pass *up, 
    343349                    challenge = alloc_buf_gc(14+strlen(auth_challenge), &gc);
    344350                    buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);
    345351
     352                    QueryFlags qryflag = QUERYUSER_NO_ECHO;
     353                    if (BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO))
     354                    {
     355                        qryflag = 0;
     356                    }
    346357                    if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge),
    347                                            response, USER_PASS_LEN,
    348                                            BOOL_CAST(flags & GET_USER_PASS_STATIC_CHALLENGE_ECHO)))
     358                                           response, USER_PASS_LEN, qryflag))
    349359                    {
    350360                        msg(M_FATAL, "ERROR: could not retrieve static challenge response");
    351361                    }
  • src/openvpn/misc.h

    diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h
    index 14abb0f3..e08a8739 100644
    a b struct static_challenge_info {}; 
    126126#define GET_USER_PASS_STATIC_CHALLENGE_ECHO  (1<<9) /* SCRV1 protocol -- echo response */
    127127
    128128#define GET_USER_PASS_INLINE_CREDS (1<<10)  /* indicates that auth_file is actually inline creds */
     129#define GET_USER_PASS_FORCE_BUILTIN (1<<11) /* force using the built-in query_user function */
    129130
    130131bool get_user_pass_cr(struct user_pass *up,
    131132                      const char *auth_file,
  • src/openvpn/pkcs11.c

    diff --git a/src/openvpn/pkcs11.c b/src/openvpn/pkcs11.c
    index 93f8580a..fa64af82 100644
    a b _pkcs11_openvpn_pin_prompt( 
    257257            &token_pass,
    258258            NULL,
    259259            prompt,
    260             GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL
     260            GET_USER_PASS_MANAGEMENT | GET_USER_PASS_PASSWORD_ONLY
     261             | GET_USER_PASS_NOFATAL | GET_USER_PASS_FORCE_BUILTIN
    261262            )
    262263        )
    263264    {
    _pkcs11_openvpn_show_pkcs11_ids_pin_prompt( 
    814815
    815816    buf_printf(&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
    816817    if (!query_user_SINGLE(BSTR(&pass_prompt), BLEN(&pass_prompt),
    817                            pin, pin_max, false))
     818                           pin, pin_max,
     819                           (QUERYUSER_NO_ECHO | QUERYUSER_FORCE_BUILTIN)))
    818820    {
    819821        msg(M_FATAL, "Could not retrieve the PIN");
    820822    }