Use 2 modules to auth together.

luckydog xf luckydogxf at
Wed Nov 28 01:56:34 CET 2018

Let me complete this topic. Feel free to correct me if I'm wrong. LOL

In short,

1. MS AD != OTP and MS AD != PAP.

2. MS AD = MSCHAP( and MSCHAP v2, not sure CHAP)


Long explaination:

1. It won't be User-Password as MS-CHAP2-Response Attribute  in
Access-Request packet has the password you input encoded and
encrypted. In other words, MSCHAP does have password but in another
form which FreeRadius cannot and won't check it either, and it's

That's the way how MSCHAP works,

see (page 14-15)

NO user-password, no OTP, b/c there is no way to know your orginal
OTP, it is in MS-CHAP2-Responsed.

2. user-password in AD schema is write-only, you cannot use Freeradius
LDAP module to revitive it, and any other LDAPclient, like LDAPadmins.
So this means NO known good password, which also means NO PAP.

3. MS AD is mschap only, as far as I know. Guess it's challeng and
response change everytine, so it's security, just a guess.

4. LDAP means PAP and OTP, as User-Password is available.

That's all.


Hi, here is my access-request from radiusd -fX

Only an extra State is added comparing to the 1st auth.

# Access-Challenge
Ready to process requests
(6) Received Access-Request Id 13 from
to172.16.237.52:1812 length 205
(6)   NAS-Identifier = "Artisan_FW"
(6)   State = 0x654e6c7472756d474c576c6a61584b37
(6)   User-Name = "someone"
(6)   MS-CHAP2-Response =
(6)   MS-CHAP-Challenge = 0x680d6e49baa9e6f4b4f622042f0917f6
(6)   NAS-IP-Address =
(6)   NAS-Port-Type = Virtual
(6)   Called-Station-Id = ""
(6)   Acct-Session-Id = "033ac507"
(6)   Connect-Info = "admin-login"
(6)   Fortinet-Vdom-Name = "root"
(6) session-state: No cached attributes
(6) # Executing section authorize from file /etc/raddb/sites-enabled/default

As you can see there is NO User-Password attribute, which is OTP. It
seems that it's caused by mschap authentication, there is no such
attribute in mschap.

Is there any way to input User-Password( in other words, OTP)? or my
own auth method would fail to auth as there is no OTP.


On Nov 26, 2018, at 8:42 AM, luckydog xf <luckydogxf at

Find a challenge-support Device and test it out. Let me answer it.

1. Not every NAS supports Access-Challenge, they may just ignore it
and treat it as access-reject. According to my test.

2. my way of raise challeng is correct, it's built-in way of FreeRADIUS.

3. else part seesm correct, too, though I haven't hanle my own auth
method, it's just a fake one.

Thank Alan again.

On Nov 26, 2018, at 12:42 AM, luckydog xf <luckydogxf at

Thank, Alan, you enlighten me.

Turns out  NAS( my VPN) does not support Access-Challenge.  Googled and
found  that Challenge seems to be a speical access-request  packet with the
Code field set to 11. So can I make the conclusion that  it would send an
access-quest again?  in other words, start a new authentication process
like another normal request with an exception that State attribute exists.

Let me suppose my VPN supports Access-Challenge, so my configuation is
something like:

authorize {
      # The first auth does not have any State attribute.
      if (!State) {
                # MS-CHAP has no User-Password, so it's true.
                if (!User-Password )  {
                        # If !State and User-Password is null, then
goes to MS-CHAP:
                        update  {
                                &control:Auth-Type := MS-CHAP

              else { reject }

      # Make sure it does not contain any other attributes except State.

     else {

            update {

             # IS THIS PART CORRECT ? I think so, as a new request is
issued by challage, so it would start over from top to buttom to walk
throught the entire process.

                &control:Auth-Type := MY_OWN_OTP_AUTH



authentication {

      Auth-Type MS-CHAP {
               if (ok) {
                       update reply {
                               # Create a random State attribute:
                               State := "%{randstr:XXXXXXXXXXXXX}"
                               Reply-Message := "Please type your OTP:"
                       # Return Access-Challenge, goes to the 2nd auth.

                       # IS IT the correct way to raise a challange?


 Please help me to take a look at  configuration above, two questions:

1. Is else part correct?  which will use my own python auth module
2. Is it correct to raise a challenge using 'challenge' filter of

Thanks again.

On Mon, Nov 26, 2018 at 8:10 PM Alan DeKok <aland

>*** On Nov 26, 2018, at 2:42 AM, luckydog xf <luckydogxf at <> < <>> < <> < <>>>> wrote:
***>* >   Our user is in AD and VPN will do an MSCHAP authentication first and
*>* > filter property of  User-Name from access request,  then call an
*>* > access-challenge to verify against  the other module whose logic is as
*>* > simple as starting a http request via http://XXX/check/username=
*>* > <http://xxx/check/username=
<http://xxx/check/username=>><USER-NAME>&OTP=<xxxxxx>, if return 200,
*>* it's
*>* > ok.
*>>*   That's really just more authorization.
*>>* >   Basically, I want to auth a single login against two modules, only both
*>* > of them are successful, the auth could be deemed as OK.
*>>*    That's possible, subject to certain caveats.
*>>* > # ### authentication #####
*>* > authentication {
*>* >       Auth-Type MS-CHAP {
*>* >                mschap
*>* >                if (ok) {
*>* >                        update reply {
*>* >                                # Create a random State attribute:
*>* >                                State := "%{randstr:XXXXXXXXXXXXX}"
*>* >                                Reply-Message := "Please type your OTP:"
*>* >                        }
*>* >                        # Return Access-Challenge, goes to the 2nd auth.
*>* >                        challenge
*>>*   That's good, but it likely won't work due to the NAS.  Doing OTP like
*>* that requires support from the NAS.  Does the NAS support doing MS-CHAP and
*>* then receiving an Access-Challenge?
*>>*   If it does, then your next step is to write down what you want to
*>* happen, like this:
*>>* 1) packet 1 contains MS-CHAP
*>* 2) it authenticates agains MS-CHAP
*>* 3) if MS-CHAP is successful, it returns a State, challenge, and reply
*>* message
*>* 4) when the next packet comes in with a state attribute, authenticate the
*>* OTP
*>>*   Note that the packet in step 4 *should not* contain any MS-CHAP
*>* attributes.  It should just contain the response to the OTP.
*>>*   So your freeradius configuration is:
*>>* 1) run MS-CHAP like normal
*>* 2) do state / reply-message / challenge in "Auth-Type MS-CHAP"
*>>*   As a *separate* item:
*>>* 3) if packet contains State
*>* 4) do OTP verification
*>>*   The only thing tying the two packets together is the State attribute.
*>* They are otherwise completely independent.
*>>*   Alan DeKok.
*>>>>* -
*>* List info/subscribe/unsubscribe? See

More information about the Freeradius-Users mailing list