[Home]

Summary:ASTERISK-06468: Wrong account selected for inbound calls
Reporter:Thorsten Lockert (tholo)Labels:
Date Opened:2006-03-03 12:40:59.000-0600Date Closed:2006-05-05 14:21:50
Priority:MinorRegression?No
Status:Closed/CompleteComponents:Core/General
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:
Description:When there are multiple accounts defined in iax.conf (all of type=user) with the same remote peer (an Asterisk instance with multiple virtual PBXes on it), calls from the remote Asterisk instances come in to the wrong account.

****** ADDITIONAL INFORMATION ******

On the remote Asterisk instance, iax.conf entries are defined as:

[general]
register => custa:secret-for-a@1.2.3.4
register => custb:secret-for-b@1.2.3.4
register => custc:secret-for-c@1.2.3.4

[a]
type=peer
auth=md5
secret=secret-for-a
host=1.2.3.4
qualify=yes
notransfer=yes

[b]
type=peer
auth=md5
secret=secret-for-b
host=1.2.3.4
qualify=yes
notransfer=yes

[c]
type=peer
auth=md5
secret=secret-for-c
host=1.2.3.4
qualify=yes
notransfer=yes


In their dialplan they use this like so:

[macro-dial-a]
exten => s,1,Dial(IAX2/custa@a/${ARG1})
exten => s,n,Goto(s-${DIALSTATUS},1)

exten => s-BUSY,1,Busy
exten => s-NOANSWER,1,Hangup
exten => _s-.,1,Congestion

[macro-dial-b]
exten => s,1,Dial(IAX2/custb@b/${ARG1})
exten => s,n,Goto(s-${DIALSTATUS},1)

exten => s-BUSY,1,Busy
exten => s-NOANSWER,1,Hangup
exten => _s-.,1,Congestion

[macro-dial-c]
exten => s,1,Dial(IAX2/custc@c/${ARG1})
exten => s,n,Goto(s-${DIALSTATUS},1)

exten => s-BUSY,1,Busy
exten => s-NOANSWER,1,Hangup
exten => _s-.,1,Congestion


The Asterisk instance in the receiving end has the following matching entries in iax.conf:

[custa]
type=user
auth=md5
secret=secret-for-a
notransfer=yes
context=inbound
accountcode=customer-a

[custa]
type=peer
auth=md5
secret=secret-for-a
notransfer=yes
host=dynamic

[custb]
type=user
auth=md5
secret=secret-for-b
notransfer=yes
accountcode=customer-b

[custb]
type=peer
auth=md5
secret=secret-for-b
notransfer=yes
host=dynamic

[custc]
type=user
auth=md5
secret=secret-for-c
notransfer=yes
accountcode=customer-c

[custc]
type=peer
auth=md5
secret=secret-for-c
notransfer=yes
host=dynamic


Now, all calls coming from the remote system will come in to "custc", regardless of which username is actually passed in the IAX2 stream -- I have verified that this actually happens.

Is this expected behaviour?  Even though it uses a different entry from iax.conf than the one identified in the IAX2 packet?

Am I just confused about how this is supposed to work?
Comments:By: Olle Johansson (oej) 2006-03-29 18:46:55.000-0600

That's not expected behaviour... Did you accidentally leave out contexts on the other users?

By: Aaron Yourk (ayourk) 2006-04-16 13:33:48

I have experienced the same issue with version 1.2.6 & 1.2.7.1.  What happens is, the last iax peer in iax.conf overwrites the settings of the prior iax peer's entry settings.  This is most easily recognized as a different context being used instead of the context selected for that peer.  All of my iax peers have a context specified.



By: Aaron Yourk (ayourk) 2006-04-16 14:06:12

Steps used to reproduce:
1.  On HostA, create 2 iax peers.  One for HostB and one for HostC.
2.  Each host will have its own context: HostA; context=HostA, etc.
Each host has a static IP assigned to it in its host= line.  For this example, we will use type=friend for both iax entries.  AccountCode=HostA, etc.
3.  Make sure that the HostB definition comes BEFORE HostC.
4.  In extensions.conf, make sure [HostB] context has an 's' extension (DateTime) and [HostC] context does not.  Make sure 'set verbose 5' is set on the HostA console.
5.  From HostB, have an extension Dial(IAX2/HostA).  You will see it attempt to dial s@HostC instead of s@HostB on the HostA console.
6.  Swap the order of the HostB and HostC definitions in iax.conf.  You will now see that a Dial(IAX2/HostA) from HostB works as expected on the HostA console.



By: Joshua C. Colp (jcolp) 2006-04-17 18:28:16

ayourk - your steps used to reproduce is very confusing and has given me a headache... can you please post applicable dialplan logic, iax.conf, console output? I believe it's a configuration issue and not a bug in chan_iax2

By: Aaron Yourk (ayourk) 2006-04-18 01:42:34

Sure why not:  See http://www.voip-info.org/wiki/view/Asterisk+cmd+Dial   Example 6
iaxhost1 runs Asterisk v1.2.7.1
iaxhost2 runs Asterisk v1.2.4
iaxhost3 runs Asterisk v1.2.7.1
Below are the relevant modifications to recreate this bug.

--- iax-host1.conf ---
[value1]
type=friend
secret=value2 ; <-- VERY important with friend types to get this to work properly
auth=plaintext
host=172.16.5.1 ; Example private address space
context=iaxhost2-in ; Always nice to be able to control access rights.
qualify=yes ; Optional, but usually a good idea.

[value5]
type=friend
secret=value6 ; <-- VERY important with friend types to get this to work properly
auth=plaintext
host=172.16.5.3 ; Example private address space
context=iaxhost3-in ; Always nice to be able to control access rights.
qualify=yes ; Optional, but usually a good idea.

--- extensions-host1.conf ---
[default]
...
include => iaxhost1-out ; Always a good idea to seperate contexts
...

[iaxhost2-in]
exten => s,1,DateTime() ; DateTime() is always good for testing
exten => 99104,1,DateTime() ; DateTime() is always good for testing
exten => 98104,1,NoOp(${EXTEN})
exten => 98104,2,DateTime() ; DateTime() is always good for testing

[iaxhost3-in]
exten => 99104,1,DateTime() ; DateTime() is always good for testing
exten => 98104,1,NoOp(${EXTEN})
exten => 98104,2,DateTime() ; DateTime() is always good for testing

[iaxhost1-out]
exten => 99205,1,Dial(IAX2/value3:value4@value1/99105)
; A more complicated extension example:
exten => 982XX,1,Dial(IAX2/value3:value4@value1/991${EXTEN:3})

--- end snips ---
Please note that iaxhost2-in has an 's' extension, whereas iaxhost3-in does NOT.

Ran a dial from iaxhost2 as Dial(IAX2/value3) and got this error from iaxhost1's console:
Apr 18 01:36:31 NOTICE[pid]: chan_iax2.c:7215 socket_read: Rejected connect attempt from 172.16.5.2, request 's@iaxhost3-in' does not exist



By: Serge Vecher (serge-v) 2006-05-04 16:36:06

is this an issue with latest stable? If so, please upload new iax debug.

By: Joshua C. Colp (jcolp) 2006-05-04 16:51:43

If I am reading this right... you are not specifying a username to send to authenticate as. The authentication system then tries to get the "best" match it can which is a peer entry using the IP address. Then it sends the call to the context specified.

By: Aaron Yourk (ayourk) 2006-05-05 01:35:48

Joshnet:  Correct, but shouldn't the best match code be more intelligent than that, like at least match against inbound/outbound IP address and port combination?  I noticed something else that I hadn't noticed before.  The secret for both hosts in my iax.conf is the same.  I doubt that this should matter much in the test case.

vechers:  Isn't 1.2.7.1 the latest stable?  I'm unsure of what _exact command_ output you are looking for.  I haven't used asterisk long enough to know all of the different debugging available to me.  The most useful debug info I've discovered so far (without being obtrusive) is 'set verbose 5'.

I'm willing to try any patch provided.  I'm not scared to get my hands dirty with coding.  I've done some coding before, but I'm just not familiar enough with the Asterisk code base to do anything.  Experience with the asterisk code here is the kicker.



By: Serge Vecher (serge-v) 2006-05-05 08:55:50

'iax debug' turns debugging of IAX channel on. If possible, make sure other peers are not talking at the same time to limit amount of information captured in the debug trace.

By: Joshua C. Colp (jcolp) 2006-05-05 09:03:48

I don't understand what you mean, how would you want it to authenticate? (using your example as reference)

By: Aaron Yourk (ayourk) 2006-05-05 09:44:21

Joshnet:  My understanding on how the authentication works is that the iax.conf has a series of unordered [peers] in some sort of weighted tree (the more conditions match, the higher the weight), with the priorities being host, host:port, host:port/secret, host/secret, secret.  I was under the impression that this was the authentication mechanism that ties to a specific [peer].  If you point me in the right direction of this "best match" code, I'm willing to see what I can do.

vechers:  I'll get the output of iax debug later tonight after work.



By: Joshua C. Colp (jcolp) 2006-05-05 09:52:24

I just looked at the function (it's called check_access in chan_iax2.c) and it looks like I am wrong, it doesn't look up peer information... I thought it did. Oh well, that function will show you how it all works! Have fun and if you still believe authentication should happen differently post another reply and we can open a discussion. As well - if you want to see how it works in that function, add some debugging calls to ast_verbose or ast_log!

By: Aaron Yourk (ayourk) 2006-05-05 10:10:11

Joshnet:  Thanks for the tip on the code.  I'll be examining that when I get more time.  I'm just curious how the path is supposed to work from what I'm seeing in the code.  How is it able to distinguish which context to use in extensions.conf for the appropriate peer?  From what I understand, this is the whole basis of this bug.  I'm not seeing all of what the fields in struct iax_ies are for (comments lacking).  Where does check_access check the iax.conf entries?

By: Joshua C. Colp (jcolp) 2006-05-05 10:19:34

I just had an idea of why you're seeing what you are. I'll lab it up and get back with an explanation soon.

By: Joshua C. Colp (jcolp) 2006-05-05 11:01:25

SO here is the way it's working, using my two boxes (neutrino and devel):

Relevant iax.conf portions on neutrino:
[devel]
type=friend
host=dynamic
secret=toast
disallow=all
allow=ulaw
context=devel-in

Relevant iax.conf portions on devel:
[neutrino-blah]
type=friend
host=neutrino
secret=toast
disallow=all
allow=ulaw
context=testing

1. Neutrino sends a call to devel using Dial(IAX2/devel)
2. Devel tries to find a match for the incoming call. The closest it can find is [neutrino-blah] because it is the baseline match. No other entries are closer, and no guest entry exists with no secret specified (if it was - the guest entry would override this baseline).
3. Devel then sends an authentication request back to Neutrino using the password specified.
4. Neutrino had no idea it had to authenticate, so it searches it's peers for a matching entry to get the password. It finds devel using it's IP address and uses it's password.
5. Neutrino sends back the authentication information.
6. Devel accepts the call as authentication was a success.

How's that?

By: Aaron Yourk (ayourk) 2006-05-05 13:17:55

You actually need 3 different Asterisk servers (or at least 2 different [peers] in iax.conf on devel).  Let's call devel as the main server where all of the debugging happens; Neutrino which makes the Test calls; and Centrino which may or may not make calls of any kind.  Let's have Neutrino positioned ABOVE Centrino in iax.conf under a different context than Centrino.  Try your test calls again.

--8<-- Devel's iax.conf --8<--
[neutrino-blah]
type=friend
host=neutrino
secret=toast
disallow=all
allow=ulaw
context=testing

[centrino-blah]
type=friend
host=centrino
secret=burnttoast
disallow=all
allow=ulaw
context=lastcontext



By: Joshua C. Colp (jcolp) 2006-05-05 13:23:21

It's all in the order in which you place it in iax.conf

If I do this:

[neutrino-blah]
type=friend
secret=toast
host=neutrino
context=testing

[neutrino-blah2]
type=friend
secret=toast
host=neutrino
context=testing

Then neutrino-blah2 will get matched. If I flip them around then neutrino-blah will get matched.

This is with neutrino-blah2 at the end of iax.conf:

May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4772 check_access: Trying neutrino-blah2
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4811 check_access: Authentication and no host access -- baseline - neutrino-blah2
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4772 check_access: Trying neutrino-blah
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4772 check_access: Trying neutrino2
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4772 check_access: Trying neutrino
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4772 check_access: Trying iaxfwd
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4772 check_access: Trying iaxtel
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:4902 check_access: Copied over secret
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:6952 socket_read: Authenticate request!
May  5 15:11:49 NOTICE[19051]: chan_iax2.c:7225 socket_read: Rejected connect attempt from 216.237.114.82, request 's@testing' does not exist

This is with neutrino-blah at the end:

May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4772 check_access: Trying neutrino-blah
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4811 check_access: Authentication and no host access -- baseline - neutrino-blah
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4772 check_access: Trying neutrino-blah2
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4772 check_access: Trying neutrino2
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4772 check_access: Trying neutrino
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4772 check_access: Trying iaxfwd
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4772 check_access: Trying iaxtel
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:4902 check_access: Copied over secret
May  5 15:14:05 NOTICE[19075]: chan_iax2.c:6952 socket_read: Authenticate request!
May  5 15:14:06 NOTICE[19075]: chan_iax2.c:7225 socket_read: Rejected connect attempt from 216.237.114.82, request 's@testing' does not exist

It's because the last entry in iax.conf will actually be at the front of the list of users, and because check_access starts out with no user selected - and no username specified, it grabs that entry until it finds a better match.

By: Aaron Yourk (ayourk) 2006-05-05 13:28:44

But by having both entries in iax.conf use the same context, you don't really see this bug rear its ugly head.  Change the context name to be DIFFERENT for each peer, then you'll start seeing what this bug is all about.

By: Joshua C. Colp (jcolp) 2006-05-05 13:32:20

Just humor me here - what exactly do you think it should be doing?

By: Aaron Yourk (ayourk) 2006-05-05 13:37:20

Calls coming in from Neutrino should be handled in context neutrino on Devel and calls from Centrino should be handled in context centrino on Devel.

By: Joshua C. Colp (jcolp) 2006-05-05 13:39:30

But you're not giving it a username to authenticate as, so it does not know that. How is it supposed to know to authenticate like that?

By: Aaron Yourk (ayourk) 2006-05-05 13:50:03

Ok, I think I'm starting to see in the code where the peers are referenced:
user = userl.users;
while (user) { ....
I also see ast_apply_ha(user->ha, sin), which (if I'm reading this correct) should be checking the source IP of Neutrino on Devel.  This leads me to believe that the 'bestscore' variable should equal 2 instead of 1 (based on your descriptions).

By: Joshua C. Colp (jcolp) 2006-05-05 13:51:56

Well, much to my talk earlier, peers are never referenced when checking inbound IAX2 access. What you're talking about is the ACL stuff:

deny=0.0.0.0/0.0.0.0
permit=192.168.2.1/255.255.255.0

For example.

What's happening in your case is that because no username is specified, check_access is grabbing the first user in the users list (which is actually the last user in iax.conf) until it can find a better match. Because no better match is found, that user is then used.

By: Aaron Yourk (ayourk) 2006-05-05 13:56:45

Ok, so then leaning in on this ACL stuff:  Then I need to explicitly add deny/permit to each [peer], right?

By: Joshua C. Colp (jcolp) 2006-05-05 13:57:56

Correct, if it works then we've all learned a valuable lesson about IAX2 authentication!

By: Aaron Yourk (ayourk) 2006-05-05 13:58:38

Please humor me here and test this in your lab environment, simulating 2 different [peers].

By: Joshua C. Colp (jcolp) 2006-05-05 14:06:59

Done.

I had two different peers calling the same box, with no username specified. They both found their right user entry using the ACL. One went to it's context, the other to it's own. This is because the ACL match is better then a baseline match.

By: Aaron Yourk (ayourk) 2006-05-05 14:09:06

Sounds like all that is left is to make this into a documentation update and call this bug closed?

By: Joshua C. Colp (jcolp) 2006-05-05 14:21:48

OKAY - Here we are folks.

If your issue still exists tholo you can find me on IRC always (I believe I did lab it up and could not recreate it).

As for the way authentication actually works, and the scoring system - it is now documented in trunk.