Custom authentication script fails with > ExternalAuthPriority not defined, please check your configuration file

Hi all,

I’m writing a PHP application (a cloud self-service application that lets developers create testing environments and so on) for the company where I also installed RT. For the authentication part, I thought to authenticate users against RT, since the users of my PHP app are a subset of RT’s users.
So, I’m down to writing a script (attached) that authenticates a user against RT, to be called from a PHP script.
On RT I have RT-Authen-ExternalAuth that connects to LDAP.
So in my perl script I’ve had to make two tries: first RT::Authen::ExternalAuth::DoAuth (for domain users); then, if it fails, $user->IsPassword($pass) (for local users).
The problem is with RT::Authen::ExternalAuth::DoAuth; instead, the auth of local users with IsPassword always works.
If I execute the script as root, it goes smooth.
But for security reasons I want to execute it as another user (I created the Unix user “selfservice”, as well as the RT user “selfservice”). Executing the script as this Unix user, DoAuth fails with the following message:

ExternalAuthPriority not defined, please check your configuration file.

What am I missing?

Thank you very much!

Regards

Alberto Scotto

Blue Reply
Via Cardinal Massaia, 83
10147 - Torino - ITALY
phone: +39 011 29100
al.scotto@reply.it
www.reply.it

[Blue Reply]

The information transmitted is intended for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

rt-auth-user (1000 Bytes)

But for security reasons I want to execute it as another user (I created the Unix user
"selfservice", as well as the RT user “selfservice”). Executing the script as this Unix user,
DoAuth fails with the following message:

ExternalAuthPriority not defined, please check your configuration file.

Does the selfservice user have access to read your Configuration files
and all the RT libraries?

-kevin

Oh, thank you, my saviour!

I was guessing it was about my lack of knowledge of the library (missing some parameters), so didn’t think of the obvious…

Btw, I just had to give my ‘selfservice’ user read permissions for etc/ files

Happy new year to all of you,
and thank you all for your support and sharing!!
(bestpractical guys in particular; Kevin, in very particular!)

Cheers

Da: rt-users-bounces@lists.bestpractical.com [rt-users-bounces@lists.bestpractical.com] per conto di Kevin Falcone [falcone@bestpractical.com]
Inviato: giovedì 27 dicembre 2012 20.18
A: rt-users@lists.bestpractical.com
Oggetto: Re: [rt-users] Custom authentication script fails with > ExternalAuthPriority not defined, please check your configuration fileOn Thu, Dec 20, 2012 at 11:56:44AM +0000, Scotto Alberto wrote:

But for security reasons I want to execute it as another user (I created the Unix user
“selfservice”, as well as the RT user “selfservice”). Executing the script as this Unix user,
DoAuth fails with the following message:

ExternalAuthPriority not defined, please check your configuration file.

Does the selfservice user have access to read your Configuration files
and all the RT libraries?

-kevin

Alberto Scotto

Blue Reply
Via Cardinal Massaia, 83
10147 - Torino - ITALY
phone: +39 011 29100
al.scotto@reply.it
www.reply.it

The information transmitted is intended for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

I’ve just shared my script on rt wikia :slight_smile:

http://requesttracker.wikia.com/wiki/Rt-auth-user

Any improvements are welcome.

For example, I suspect there’s a better way to do it (it = authenticating against external auths first, and then the local RT’s DB).
I’d expect to call only DoAuth, and then it should fall to IsPassword by itself, shouldn’t it?

Alberto Scotto

Blue Reply
Via Cardinal Massaia, 83
10147 - Torino - ITALY
phone: +39 011 29100
al.scotto@reply.it
www.reply.it

The information transmitted is intended for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

I’ve just shared my script on rt wikia :slight_smile:

http://requesttracker.wikia.com/wiki/Rt-auth-user

Any improvements are welcome.

For example, I suspect there’s a better way to do it (it =
authenticating against external auths first, and then the local RT’s
DB). I’d expect to call only DoAuth, and then it should fall to
IsPassword by itself, shouldn’t it?

Your PHP example has a serious security flaw in it since you use
unescaped user input in the call to shell_exec(). Any username which
passes your check may be followed by a password which runs arbitrary
shell code on your server.

Hi Thomas.

First of all, Thank you for your feedback!

You are right.
Actually, in my mind, that function was supposed to have input validated by some other methods (around the View layer), as a precondition.

Now, I think it’s a matter of design.
Whether

  • to keep things strictly separate (only the high-level class charged with the input validation)
    or
  • to have validation in both layers (maybe with a strong validation in the high-level class and a minimum validation in the function auth_rt)

Don’t know what is the best. I think using preconditions is a strong practice that gives you freedom and lets you avoid duplicate checks. Actually, the preconditions must be documented…

So I think that I may go for documenting the precondition in the wiki page (also for simplicity).

What do you think?

AS

PS: Happy New Year :slight_smile:

Da: rt-users-bounces@lists.bestpractical.com [rt-users-bounces@lists.bestpractical.com] per conto di Thomas Sibley [trs@bestpractical.com]
Inviato: lunedì 31 dicembre 2012 22.44
A: rt-users@lists.bestpractical.com
Oggetto: Re: [rt-users] R: Custom authentication script fails with > ExternalAuthPriority not defined, please check your configuration fileOn 12/27/2012 04:57 PM, Scotto Alberto wrote:

I’ve just shared my script on rt wikia :slight_smile:

http://requesttracker.wikia.com/wiki/Rt-auth-user

Any improvements are welcome.

For example, I suspect there’s a better way to do it (it =
authenticating against external auths first, and then the local RT’s
DB). I’d expect to call only DoAuth, and then it should fall to
IsPassword by itself, shouldn’t it?

Your PHP example has a serious security flaw in it since you use
unescaped user input in the call to shell_exec(). Any username which
passes your check may be followed by a password which runs arbitrary
shell code on your server.

Alberto Scotto

Blue Reply
Via Cardinal Massaia, 83
10147 - Torino - ITALY
phone: +39 011 29100
al.scotto@reply.it
www.reply.it

The information transmitted is intended for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Don’t know what is the best. I think using preconditions is a strong
practice that gives you freedom and lets you avoid duplicate checks.
Actually, the preconditions must be documented…

So I think that I may go for documenting the precondition in the wiki
page (also for simplicity).

What do you think?

Relying on the input being validated before handed to the function is
asking for trouble as soon as the function starts being used in multiple
places, some of which may not validate the input. The function should
be a black box, and you shouldn’t need to know that it’s going to pass
provided arguments to shell_exec(). Fix problems at the source, not at
some more distant location. You’ll end up playing whack a mole otherwise.

Thomas

Hi,

why not just call in you PHP app
https://your-rt-server-url/REST/1.0/
with user and pass as post parameter and check the first line of the
response for the status

  • “200 Ok” = successful login
  • “401 Credentials required” = not successful login

ChrisAm 20.12.2012 12:56, schrieb Scotto Alberto:

Hi all,

I�m writing a PHP application (a cloud self-service application that
lets developers create testing environments and so on) for the company
where I also installed RT. For the authentication part, I thought to
authenticate users against RT, since the users of my PHP app are a
subset of RT�s users.

So, I�m down to writing a script (attached) that authenticates a user
against RT, to be called from a PHP script.

On RT I have RT-Authen-ExternalAuth that connects to LDAP.

So in my perl script I�ve had to make two tries: first
RT::Authen::ExternalAuth::DoAuth (for domain users); then, if it fails,
$user->IsPassword($pass) (for local users).

The problem is with RT::Authen::ExternalAuth::DoAuth; instead, the auth
of local users with IsPassword always works.

If I execute the script as root, it goes smooth.

But for security reasons I want to execute it as another user (I created
the Unix user �selfservice�, as well as the RT user �selfservice�).
Executing the script as this Unix user, DoAuth fails with the following
message:

/ExternalAuthPriority not defined, please check your configuration file./

What am I missing?

Thank you very much!

Regards

Alberto Scotto

Yep! That’s something I was mumbling about.

Thanks to you, I’ve just given it a try.
It’s not that easy peasy: REST returns 200 even if you are not authenticated. But you can deduce if you have been auth’d from the HTML page you get, searching for 'span id=“not-logged-in” ', for example.

What about the security point of view of the two methods of auth (my script vs REST)?
Assuming RT is reachable via https, can it be any worse than executing a script via ssh?

Da: Christian Loos [cloos@netsandbox.de]
Inviato: mercoledì 2 gennaio 2013 23.10
A: Scotto Alberto
Oggetto: Re: Custom authentication script fails with > ExternalAuthPriority not defined, please check your configuration file

Hi,

why not just call in you PHP app
https://your-rt-server-url/REST/1.0/
with user and pass as post parameter and check the first line of the
response for the status

  • “200 Ok” = successful login
  • “401 Credentials required” = not successful login

ChrisAm 20.12.2012 12:56, schrieb Scotto Alberto:

Hi all,

I’m writing a PHP application (a cloud self-service application that
lets developers create testing environments and so on) for the company
where I also installed RT. For the authentication part, I thought to
authenticate users against RT, since the users of my PHP app are a
subset of RT’s users.

So, I’m down to writing a script (attached) that authenticates a user
against RT, to be called from a PHP script.

On RT I have RT-Authen-ExternalAuth that connects to LDAP.

So in my perl script I’ve had to make two tries: first
RT::Authen::ExternalAuth::DoAuth (for domain users); then, if it fails,
$user->IsPassword($pass) (for local users).

The problem is with RT::Authen::ExternalAuth::DoAuth; instead, the auth
of local users with IsPassword always works.

If I execute the script as root, it goes smooth.

But for security reasons I want to execute it as another user (I created
the Unix user “selfservice”, as well as the RT user “selfservice”).
Executing the script as this Unix user, DoAuth fails with the following
message:

/ExternalAuthPriority not defined, please check your configuration file./

What am I missing?

Thank you very much!

Regards

Alberto Scotto

Alberto Scotto

Blue Reply
Via Cardinal Massaia, 83
10147 - Torino - ITALY
phone: +39 011 29100
al.scotto@reply.it
www.reply.it

The information transmitted is intended for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Yep! That’s something I was mumbling about.

Thanks to you, I’ve just given it a try.
It’s not that easy peasy: REST returns 200 even if you are not authenticated. But you can deduce if you have been auth’d from the HTML page you get, searching for 'span id=“not-logged-in” ', for example.

REST should never return HTML. Try an existing endpoint under
/REST/1.0/ instead of just that top level dir.

What about the security point of view of the two methods of auth (my script vs REST)?
Assuming RT is reachable via https, can it be any worse than executing a script via ssh?

  1. You don’t have to replicate the RT::Authen::ExternalAuth handling,
    since it’ll all Just Work if you treat the web interface as an auth
    endpoint.

  2. You won’t suffer arbitrary code execution vulnerabilities in your ssh
    exec wrapper.

  3. It doesn’t require your PHP app to live on the same server as RT’s
    source code and config.

Alberto Scotto

Blue Reply
Via Cardinal Massaia, 83
10147 - Torino - ITALY
phone: +39 011 29100
al.scotto@reply.it
www.reply.it

Don’t know what is the best. I think using preconditions is a strong
practice that gives you freedom and lets you avoid duplicate checks.
Actually, the preconditions must be documented…

So I think that I may go for documenting the precondition in the wiki
page (also for simplicity).

What do you think?

Relying on the input being validated before handed to the function is
asking for trouble as soon as the function starts being used in multiple
places, some of which may not validate the input. The function should
be a black box, and you shouldn’t need to know that it’s going to pass
provided arguments to shell_exec(). Fix problems at the source, not at
some more distant location. You’ll end up playing whack a mole otherwise.

Thomas

Thanks for your contribution.

Fix problems at the source
Exactly.
From my point of view, the “source” is who/what generates the input: the user who fills in a form. So, this is why I say that the input validation should be done around the View layer, while in the back (“rt_auth” function) I should assume with a precondition that the input is not evil anymore.

The information transmitted is intended for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Fix problems at the source

Exactly. From my point of view, the “source” is who/what generates
the input: the user who fills in a form. So, this is why I say that
the input validation should be done around the View layer, while in
the back (“rt_auth” function) I should assume with a precondition
that the input is not evil anymore.

It’s far too easy for the backend function to start being used somewhere
where the validation doesn’t happen first, and then you’re vulnerable
again. The backend is a single point to fix, whereas validation might
need to happen across multiple views and interfaces.

The path of shoving the shell_exec() validation up into the view is
lined with awful websites which prohibit special characters in passwords.

Hi All,

On RT 3.6.8 I had a scrip which notified requestors upon ticket move to a particular queue.

We run a few queues here, initially all tickets land in Triage and they’re then moved into queue Support once reviewed.

The autoreply seems to have stopped working on RT4.0.8 when tickets are moved from Triage to Support. If I manually create a ticket within the queue directly, all works as it should.

From reading ‘rt.log’, I fail to see see the scrip being called.

Scrip setup:

Description: On create auto reply
Condition: On create
Action: Autoreply to requestors
Template: Autoreply-custom
Stage: TransactionCreate

Would anyone be able to suggest potential reasons for the issue?

Many Thanks,

Nick
Nick Fennell
ApplianSys Support Team Leader

ApplianSys Limited
University of Warwick Science Park
Business Innovation Centre
Harry Weston Road
Coventry CV3 2TX

t: +44 (0) 870 7707 789
s: nick-fennell

Our sales team sells by referral:
Less time looking for customers, more time looking after them

Subscribe: http://eepurl.com/ibKtY

Hi Nick,

Hi All,

On RT 3.6.8 I had a scrip which notified requestors upon ticket move
to a particular queue.

We run a few queues here, initially all tickets land in Triage and
they’re then moved into queue Support once reviewed.

The autoreply seems to have stopped working on RT4.0.8 when tickets
are moved from Triage to Support. If I manually create a ticket
within the queue directly, all works as it should.

From reading ‘rt.log’, I fail to see see the scrip being called.

Scrip setup:

Description: On create auto reply
Condition: On create
Action: Autoreply to requestors
Template: Autoreply-custom
Stage: TransactionCreate

Would anyone be able to suggest potential reasons for the issue?

Many Thanks,

Nick

is “Condition: On Queue change” right for you.

Cheers,

Björn

Hi Björn.

I had considered that although, we’re sometimes required to move tickets from Queue: Support to queue: RMA and vice-versa.

Having ‘On queue change’ would result in auto-replies being sent whenever tickets are moved into the Support queue.

Is there a Custom Condition I can apply so that the scrip is only effective when source queue = Triage?

Many Thanks,

NIck
Nick Fennell
ApplianSys Support Team Leader

ApplianSys Limited
University of Warwick Science Park
Business Innovation Centre
Harry Weston Road
Coventry CV3 2TX

t: +44 (0) 870 7707 789
s: nick-fennell

Our sales team sells by referral:
Less time looking for customers, more time looking after them

Subscribe: EepURL - A Mailchimp Service 7 Jan 2013, at 13:20, Björn Schulz bjoern.schulz@desy.de wrote:

Hi Nick,

Hi All,

On RT 3.6.8 I had a scrip which notified requestors upon ticket move
to a particular queue.

We run a few queues here, initially all tickets land in Triage and
they’re then moved into queue Support once reviewed.

The autoreply seems to have stopped working on RT4.0.8 when tickets
are moved from Triage to Support. If I manually create a ticket
within the queue directly, all works as it should.

From reading ‘rt.log’, I fail to see see the scrip being called.

Scrip setup:

Description: On create auto reply
Condition: On create
Action: Autoreply to requestors
Template: Autoreply-custom
Stage: TransactionCreate

Would anyone be able to suggest potential reasons for the issue?

Many Thanks,

Nick

is “Condition: On Queue change” right for you.

Cheers,

Björn

I had considered that although, we’re sometimes required to move tickets from Queue: Support to queue: RMA and vice-versa.
Having ‘On queue change’ would result in auto-replies being sent whenever tickets are moved into the Support queue.
Is there a Custom Condition I can apply so that the scrip is only effective when source queue = Triage?

You need to make a User Defined condition that includes the 1 line of
code from QueueChange.pm along with a simple check that OldValue was
the old Queue’s id.

-kevin

Hey Kevin/All.

I’ve been trying with;

return 0 unless $self->TransactionObj->Type eq “Set”;
return 0 unless $self->TransactionObj->Field eq “Queue”;
return 0 unless $self->TransactionObj->OldValue eq ‘QueueName’;

but not having much luck.

Anyone able to advise further?

Thanks,

Nick
Nick Fennell
ApplianSys Support Team Leader

ApplianSys Limited
University of Warwick Science Park
Business Innovation Centre
Harry Weston Road
Coventry CV3 2TX

t: +44 (0) 870 7707 789
s: nick-fennell

Our sales team sells by referral:
Less time looking for customers, more time looking after them

Subscribe: EepURL - A Mailchimp Service 7 Jan 2013, at 22:53, Kevin Falcone falcone@bestpractical.com wrote:

On Mon, Jan 07, 2013 at 04:40:39PM +0000, Nick Fennell wrote:

I had considered that although, we’re sometimes required to move tickets from Queue: Support to queue: RMA and vice-versa.
Having ‘On queue change’ would result in auto-replies being sent whenever tickets are moved into the Support queue.
Is there a Custom Condition I can apply so that the scrip is only effective when source queue = Triage?

You need to make a User Defined condition that includes the 1 line of
code from QueueChange.pm along with a simple check that OldValue was
the old Queue’s id.

-kevin

Hey Kevin/All.

I’ve been trying with;

return 0 unless $self->TransactionObj->Type eq “Set”;
return 0 unless $self->TransactionObj->Field eq “Queue”;
return 0 unless $self->TransactionObj->OldValue eq ‘QueueName’;

but not having much luck.

Anyone able to advise further?

You need to return 1 at some point. The condition doesn’t default to true.

If my understand is accurate, would something like the below be correct?

return 0 unless $self->TransactionObj->Type eq “Set”;
return 0 unless $self->TransactionObj->Field eq “Queue”;
return 1 unless $self->TransactionObj->OldValue eq ‘QueueName’;

I’m assuming here that the condition will result in ‘1’ (fail) if the OldValue does not evaluate to be ‘QueueName’.

If OldValue does evaluate to be QueueName then the condition returns ‘0’ resulting in the Scrip running.

Nick Fennell
ApplianSys Support Team Leader

ApplianSys Limited
University of Warwick Science Park
Business Innovation Centre
Harry Weston Road
Coventry CV3 2TX

t: +44 (0) 870 7707 789
s: nick-fennell

Our sales team sells by referral:
Less time looking for customers, more time looking after them

Subscribe: EepURL - A Mailchimp Service 8 Jan 2013, at 18:49, Thomas Sibley trs@bestpractical.com wrote:

On 01/08/2013 10:08 AM, Nick Fennell wrote:

Hey Kevin/All.

I’ve been trying with;

return 0 unless $self->TransactionObj->Type eq “Set”;
return 0 unless $self->TransactionObj->Field eq “Queue”;
return 0 unless $self->TransactionObj->OldValue eq ‘QueueName’;

but not having much luck.

Anyone able to advise further?

You need to return 1 at some point. The condition doesn’t default to true.

I’m assuming here that the condition will result in ‘1’ (fail) if the
OldValue does not evaluate to be ‘QueueName’.

If OldValue does evaluate to be QueueName then the condition returns
’0’ resulting in the Scrip running.

Returning 1 (a true value) doesn’t make the scrip fail, it causes it to
run. Return 0 (a false value) doesn’t make the scrip run, it causes it
to fail. You have it backwards. Try this:

return 0 unless $self->TransactionObj->Type eq “Set”;
return 0 unless $self->TransactionObj->Field eq “Queue”;
return 0 unless $self->TransactionObj->OldValue eq ‘QueueName’;
return 1;