Active TopicsActive Topics  Display List of Forum MembersMemberlist  Search The ForumSearch  HelpHelp
  RegisterRegister  LoginLogin
PowerHome General
 PowerHome Messageboard : PowerHome General
Subject Topic: Ugh 2.1.4 broke my app Post ReplyPost New Topic
Author
Message << Prev Topic | Next Topic >>
MrGibbage
Super User
Super User
Avatar

Joined: October 23 2006
Location: United States
Online Status: Offline
Posts: 513
Posted: October 25 2011 at 22:35 | IP Logged Quote MrGibbage

My android app that I am developing used commands like
http://myPhWebServer:8080/ph-cgi/eval?formula=ph_getglobal_s ('ELK_ALARM_STATE_AREA1')
Using java on android, I would authenticate like this:

String password = db.getWebPassword();
String username = db.getWebUsername();
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
((AbstractHttpClient) client).getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), creds);
HttpGet httpGet = new HttpGet(url);
HttpResponse execute = client.execute(httpGet);

It worked fine until tonight when I upgraded from 2.1b to 2.14. Previously on 2.1b that code would return just the value of that global
variable. Now when I run it from my app, something like this is returned:
powerhome redirectlocation.replace('/ph-cgi/clogin?nexturl=%2fph-cgi%2 feval%3fformula%3dph_getglobal_s(%27elk_arm_status_area1%27) ')

When I try that url from a web browser, I an authentication rendered within the web page rather than the usual popup that asks for the
user/pass, which is what used to happen on 2.1b.

Any ideas as to what is going on?


__________________
Skip
Back to Top View MrGibbage's Profile Search for other posts by MrGibbage
 
dhoward
Admin Group
Admin Group
Avatar

Joined: June 29 2001
Location: United States
Online Status: Offline
Posts: 4447
Posted: October 25 2011 at 22:39 | IP Logged Quote dhoward

Skip,

In PowerHome Explorer under PowerHome|Setup|Web, change
Authentication method from Cookie to Basic. This will
revert you back to pre 2.1.4 authentication.

Hope this helps,

Dave.
Back to Top View dhoward's Profile Search for other posts by dhoward Visit dhoward's Homepage
 
MrGibbage
Super User
Super User
Avatar

Joined: October 23 2006
Location: United States
Online Status: Offline
Posts: 513
Posted: October 26 2011 at 19:15 | IP Logged Quote MrGibbage

Whoo hoo, Dave. Thanks!

Do you have any idea how I could configure my app so I can use either method? Is
there a way for me to tell how a user has their PH webserver configured? Should I
just try both? Or should I force users to use Basic authentication?

__________________
Skip
Back to Top View MrGibbage's Profile Search for other posts by MrGibbage
 
dhoward
Admin Group
Admin Group
Avatar

Joined: June 29 2001
Location: United States
Online Status: Offline
Posts: 4447
Posted: October 26 2011 at 20:30 | IP Logged Quote dhoward

Skip,

I would definitely try to support both. The basic
authentication is pretty weak.

Not sure if there is a method to determine how the
webserver is configured (remotely via the app) but I will
look at the code to make sure. I'll also try to document
how the cookie authentication works so that it could be
supported. Probably wont get to it until this weekend
though. In the meantime, if you're feeling adventurous,
it should be easy enough to figure out by viewing the
source of the cookie login page and then the javascript
file for subsequent page calls. Its basically just an
MD5 hash (if memory serves).

Dave.
Back to Top View dhoward's Profile Search for other posts by dhoward Visit dhoward's Homepage
 
MrGibbage
Super User
Super User
Avatar

Joined: October 23 2006
Location: United States
Online Status: Offline
Posts: 513
Posted: October 29 2011 at 09:08 | IP Logged Quote MrGibbage

Well, I am very close. I looked at the source of the login page and watch wireshark as I did some logins and I see how
it is supposed to work.

I need to POST directly to /ph-cgi/cauth with auth= MD5 hash of token:username:pass
My code works if I steal an auth from a web browser session. But the token changes each time the login page refreshes.
Without giving away too much of your backend security, how can I bypass the login page which would be presented to a
web user? By bypassing that page, I will not have an active token. Or do I just need to hit the login page, grab the
token, and use it within a certain amount of time? Does ph keep a database of recently presented tokens for future use
on the login page, and then expire them after a certain amount of time?

Edit:
I tried saving a token from a web session and then used in in my app about a minute later. It didn't work. I got an error about the
token being expired.

Edited by MrGibbage - October 29 2011 at 10:05


__________________
Skip
Back to Top View MrGibbage's Profile Search for other posts by MrGibbage
 
MrGibbage
Super User
Super User
Avatar

Joined: October 23 2006
Location: United States
Online Status: Offline
Posts: 513
Posted: October 29 2011 at 12:58 | IP Logged Quote MrGibbage

Nevermind. I figured it out. I had to first put the token at the front of the auth string and then
I had to convert it to uppercase. Seems to be working now.

__________________
Skip
Back to Top View MrGibbage's Profile Search for other posts by MrGibbage
 
dhoward
Admin Group
Admin Group
Avatar

Joined: June 29 2001
Location: United States
Online Status: Offline
Posts: 4447
Posted: October 29 2011 at 13:09 | IP Logged Quote dhoward

Skip,

Still planning to look at the code in depth for you
(hopefully have something for you tonight) but from
memory, you'll definitely need to hit the login page and
scrape the token. PowerHome has a database table that
stores the tokens and they do expire. Once you're
scraped the token, perform the MD5 hash of the token,
username, pass and make the call (needs to be done fairly
quickly because it does expire). The database will then
be updated that the token is authenticated and then
you'll be able to use the cookie for all future calls.
You can set when tokens expire on the web server
configuration page.

I'll dig into it and give you further details.

Hope this helps for now.

Dave.
Back to Top View dhoward's Profile Search for other posts by dhoward Visit dhoward's Homepage
 
MrGibbage
Super User
Super User
Avatar

Joined: October 23 2006
Location: United States
Online Status: Offline
Posts: 513
Posted: October 29 2011 at 13:19 | IP Logged Quote MrGibbage

Two quick questions:

1. How can I invalidate a cookie on the server? Or all
cookies/sessions? I wan tto make sure my app correctly
handles a situation where I have a cookie but it is
expired/disabled/whatever on the server and that it tries
to get a new one.
2. Is there a function that I can run to change the
authentication method for the web server between basic and
cookie?

__________________
Skip
Back to Top View MrGibbage's Profile Search for other posts by MrGibbage
 
MrGibbage
Super User
Super User
Avatar

Joined: October 23 2006
Location: United States
Online Status: Offline
Posts: 513
Posted: October 29 2011 at 15:57 | IP Logged Quote MrGibbage

Dave,
Thanks for the help so far. I think I have it all figured out. I do scrape the token from the login
page and use that to compute the auth key. One thing I have seen though is sometimes when I refresh
the login page, the token is set to "" (empty string). It doesn't do it every time, but it does
happen. I haven't decided what I will do when that happens. Maybe retry one or two times before
giving up.

Anyway, I don't think there is anything else I need you to do right now (except maybe answer my
question 2 in my post above).

Seriously, thanks for all the help on this. I hope to have a new version of my app out this weekend
which will add socket server support and basic and cookie authentication for web access.


__________________
Skip
Back to Top View MrGibbage's Profile Search for other posts by MrGibbage
 
dhoward
Admin Group
Admin Group
Avatar

Joined: June 29 2001
Location: United States
Online Status: Offline
Posts: 4447
Posted: October 30 2011 at 22:45 | IP Logged Quote dhoward

Skip,

Dug into the code and pasting my notes below. Sorry if they're a little jumbled.

A program should make a request as normal (no authentication). If any request returns a redirect to <html><head><title>PowerHome Redirect</title><script>location.replace('/ph-cg i/clogin?nexturl=%2f')</script> then cookie authentication is being used vs basic authentication. Basic authentication will return a different message (didnt get a chance to look this up but should be easy to see if your server is set basic authentication). This is the only way to distinguish the authentication the server uses. Also, anytime the redirect to clogin is returned, a new token should be requested.

If cookie authentication is being used and a new token is needed, a call should be made to

http://phwebserver/ph-cgi/clogin

You now have 5 minutes to create the MD5 hash and make the next call. If you don't make the call in time, you'll get a token expired message.

Search the HTML returned for:

<input type="hidden" name="token" value="THETOKEN">

The token will always be 8 hex characters. Make auth string using token:userid:password. MD5 hash this string. Now prepend the token to the front of the MD5. This is the authstring.

Now authenticate the token by calling

http://phwebserver/ph-cgi/cauth?auth=authstring&persist=yes& nexturl=/ph-cgi/main

Verify you get a 200 OK return and a Set-Cookie line. This ensures that the webtokens table has been properly updated and the token activated.
For all future requests, just include the cookie: phauth=authstring

The program should store the token once one is received and authenticated. If any request returns a redirect to <html><head><title>PowerHome Redirect</title><script>location.replace('/ph-cg i/clogin?nexturl=%2f')</script> </head>
</html> then the old token should be discarded and a new one received by the method above.

Tokens are stored in the webtokens table. When a token is first requested via /ph-cgi/clogin, a token is randomly generated and inserted into the table. The active field will be assigned a value of 0. If the token isnt authenticated within 5 minutes, it will be deleted from the table. When /ph-cgi/cauth is called and the token is authenticated, the active field will be changed to either 1 or 2. If persist is set to no, then the active field will be 1 and then token will expire in 24 hours. If persist is set to yes and the cookiepersistdays > 0, then the active field will be set to 2 and the token will expire in however many days you've configured for the token to persist in the webserver settings.

The only way to view the existing webtokens is via SQL in the PowerHome Multi-editor in SQL mode (shift-F5). You can see everything by typing

select * from webtokens

In the to do list is a new screen to manage the web tokens table.

Hope this helps and if you have any questions, I should be prepared to answer them now.

Dave.
Back to Top View dhoward's Profile Search for other posts by dhoward Visit dhoward's Homepage
 
MrGibbage
Super User
Super User
Avatar

Joined: October 23 2006
Location: United States
Online Status: Offline
Posts: 513
Posted: October 31 2011 at 06:14 | IP Logged Quote MrGibbage

This is awesome, Dave, and incredibly helpful. I have just about finished up the work I wanted to do over
the weekend on the app and I will be test driving it for a day or two before uploading it. This has enabled
me to add a lot of functionality to the app and I think I will be able to release it to the market Real
Soon.

__________________
Skip
Back to Top View MrGibbage's Profile Search for other posts by MrGibbage
 

If you wish to post a reply to this topic you must first login
If you are not already registered you must first register

  Post ReplyPost New Topic
Printable version Printable version

Forum Jump
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot delete your posts in this forum
You cannot edit your posts in this forum
You cannot create polls in this forum
You cannot vote in polls in this forum