how to make ocserv do totp 2FA?

Wang Jian larkwang at gmail.com
Mon May 18 19:01:58 PDT 2015


2015-05-19 4:48 GMT+08:00 Kevin Cernekee <cernekee at gmail.com>:
> On Mon, May 18, 2015 at 1:17 PM, Nikos Mavrogiannopoulos
> <nmav at gnutls.org> wrote:
>> On Mon, 2015-05-18 at 13:13 -0700, Kevin Cernekee wrote:
>>
>>> BTW you'll probably want to make sure something in the login form
>>> (e.g. the password prompt) distinguishes between the alphanumeric
>>> password entry and the OTP entry.  Both for user interaction reasons,
>>> and because OpenConnect wants to be able to uniquely identify each
>>> form field in order to save passwords locally.
>>
>> That cannot be really done with PAM, or I can't think of a simple way to
>> do it. You only get prompts with a message, and you don't know if PAM
>> asks the same password again or a new one. What may be distinct in the
>> form that ocserv sends is the <message/> field.
>
> I might be misinterpreting your response, but it looks like pam_oath
> does use a distinctive prompt for the OTP:
>
> http://spod.cx/blog/two-factor-ssh-auth-with-pam_oath-google-authenticator.shtml
>
> username at host:~$ ssh securehost
> Password:
> One-time password (OATH) for `username':
> Last login: Wed Jul 10 22:38:53 2013 from somehost.example.com
> username at securehost:~$
>
> Or for pam_google_authenticator:
>
> https://wiki.archlinux.org/index.php/Google_Authenticator#Testing

PAM is mostly for tty usage. For tty applications, it's easy to show
prompt verbatim.

For VPN GUI, whether suitable to send prompt verbatim is depending.

Look at pam.c of ocserv,

static int ocserv_conv(int msg_size, const struct pam_message **msg,
                struct pam_response **resp, void *uptr)
{
...
                        case PAM_PROMPT_ECHO_OFF:
                        case PAM_PROMPT_ECHO_ON:
                                syslog(LOG_DEBUG, "PAM-auth conv:
echo-%s, sent: %d",
(msg[i]->msg_style==PAM_PROMPT_ECHO_ON)?"on":"off", pctx->sent_msg);

                                if (pctx->sent_msg == 0) {
                                        /* no message, just asking for
password */
                                        str_reset(&pctx->msg);
                                        pctx->sent_msg = 1;
                                }
                                pctx->state = PAM_S_WAIT_FOR_PASS;
                                pctx->cr_ret = PAM_SUCCESS;
                                co_resume();
                                pctx->state = PAM_S_INIT;

                                pctx->replies[i].resp = strdup(pctx->password);
                                pctx->sent_msg = 0;
                                break;
...
}

static int pam_auth_msg(void* ctx, void *pool, char** msg)
{
...
        if (msg != NULL) {
                if (pctx->msg.length == 0)
                        if (pctx->changing)
                                *msg = talloc_strdup(pool, "Please
enter the new password.");
                        else
                                *msg = talloc_strdup(pool, "Please
enter your password.");
                else {
                        if (str_append_data(&pctx->msg, "\0", 1) < 0)
                                return -1;

                        *msg = talloc_strdup(pool, (char*)pctx->msg.data);
                }
        }
...
}

It seems that this can be improved.



More information about the openconnect-devel mailing list