| Author | 
         | 
         
      
        
         
         MrGibbage Super User 
          
  
  Joined: October 23 2006 Location: United States
 Online Status: Offline Posts: 513
          | 
        
         
          
           | Posted: October 25 2011 at 22:35 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
         | 
       
       
       
        |   | 
      
        
         
         dhoward Admin Group 
          
  
  Joined: June 29 2001 Location: United States
 Online Status: Offline Posts: 4447
          | 
        
         
          
           | Posted: October 25 2011 at 22:39 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
          
         | 
       
       
       
        |   | 
      
        
         
         MrGibbage Super User 
          
  
  Joined: October 23 2006 Location: United States
 Online Status: Offline Posts: 513
          | 
        
         
          
           | Posted: October 26 2011 at 19:15 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
         | 
       
       
       
        |   | 
      
        
         
         dhoward Admin Group 
          
  
  Joined: June 29 2001 Location: United States
 Online Status: Offline Posts: 4447
          | 
        
         
          
           | Posted: October 26 2011 at 20:30 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
          
         | 
       
       
       
        |   | 
      
        
         
         MrGibbage Super User 
          
  
  Joined: October 23 2006 Location: United States
 Online Status: Offline Posts: 513
          | 
        
         
          
           | Posted: October 29 2011 at 09:08 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
         | 
       
       
       
        |   | 
      
        
         
         MrGibbage Super User 
          
  
  Joined: October 23 2006 Location: United States
 Online Status: Offline Posts: 513
          | 
        
         
          
           | Posted: October 29 2011 at 12:58 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
         | 
       
       
       
        |   | 
      
        
         
         dhoward Admin Group 
          
  
  Joined: June 29 2001 Location: United States
 Online Status: Offline Posts: 4447
          | 
        
         
          
           | Posted: October 29 2011 at 13:09 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
          
         | 
       
       
       
        |   | 
      
        
         
         MrGibbage Super User 
          
  
  Joined: October 23 2006 Location: United States
 Online Status: Offline Posts: 513
          | 
        
         
          
           | Posted: October 29 2011 at 13:19 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
         | 
       
       
       
        |   | 
      
        
         
         MrGibbage Super User 
          
  
  Joined: October 23 2006 Location: United States
 Online Status: Offline Posts: 513
          | 
        
         
          
           | Posted: October 29 2011 at 15:57 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
         | 
       
       
       
        |   | 
      
        
         
         dhoward Admin Group 
          
  
  Joined: June 29 2001 Location: United States
 Online Status: Offline Posts: 4447
          | 
        
         
          
           | Posted: October 30 2011 at 22:45 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
          
         | 
       
       
       
        |   | 
      
        
         
         MrGibbage Super User 
          
  
  Joined: October 23 2006 Location: United States
 Online Status: Offline Posts: 513
          | 
        
         
          
           | Posted: October 31 2011 at 06:14 | IP Logged
		     | 
                    
            		  
           | 
           
          
           
  | 
           
          
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 | 
         
          
         | 
       
       
       
        |   |