Page 1 of 2

[ANSWERED]Restful and password

PostPosted: Tue Dec 31, 2013 1:56 am
by DomoPat
I am trying to have an I/O board to communicate with Indigo using HTTP commands notifications. But that board does not support the "user:password" identification scheme in the URL, so it cannot control a device or variable in Indigo through the restful API and port 8176.

If I try without the password in Indigo the commands are received and executed, but I cannot remove the password as I need the access from the outside to be protected !

Is there a way to circumvent this problem ? another port ? another solution to keep the password but give access to the restful API to the internal network without password ?

Thank you,

Patrick

Re: Restful and password

PostPosted: Thu Jan 02, 2014 4:36 pm
by matt (support)
Hi Patrick,

There isn't a great way to circumvent the authentication. Probably the cleanest approach would be to create an Indigo plugin that starts its own Web server (I'd look into using twisted or CherryPy). You could then have it perform the authentication to the real Indigo Web Server while only allowing RESTful APIs through.

Re: [REVISITED]Restful and password

PostPosted: Sat Apr 19, 2014 8:19 am
by marceltrapman
I am more or less in the same boat using an Arduino board but I am not really sure.

This is all pretty new to me so I would like to know the following:

1. When creating a restful request I can set a header.
As far as I understand I should be able to use the header to but I tried using "Authorization: Basic user:password" without success.
Question(s):
1. Am I correct that I can use a header for authorization?
2. Is 'Basic' authorization correct or should it be something else?
3. can user:password be clear or should they be encoded and, if so, how should they be encoded.

2. If this is really not possible is there an example (or plugin) that shows me how to create a plugin that starts my own webserver?

BTW, what I am not clear on is that while browsing for this I read that a string (should) be returned with something like "WWW-Authenticate: ....." but I don't see that :(

Thanks for your help in advance,

Marcel

Re: [ANSWERED]Restful and password

PostPosted: Sat Apr 19, 2014 10:33 am
by marceltrapman
After (a lot) more reading I found that I should use Digest.

I know that, without authentication my code works.
With authorization and without authorization header a 401 status is returned.
With authorization and with authorization header a 500 status is returned :(

This is what I use (Arduino stuff):
Code: Select all
//generate the MD5 hash for our string
unsigned char* authHash = MD5::make_hash("username:Indigo Control Server:password");
//generate the digest (hex encoding) of our hash
char* authValue = MD5::make_digest(authHash, 16);

Re: [ANSWERED]Restful and password

PostPosted: Tue Apr 22, 2014 7:20 am
by matt (support)
You can enable HTTP Basic (instead of Digest) authentication by following the instructions on this post. There are security implications of doing so, but depending on your setup it may be okay.

Digest authentication is more complex than Basic. The client has to reply with a hash that considers the nonce and qop, in addition to the realm (and on user side username:realm:password). I'm not sure about all the details off the top of my head -- I've never has to implement my own version of the client side of HTTP Digest (Indigo just does the server side). Indigo Touch relies on iOS provided APIs to handle it, so I've never had to get into the nuts and bolts of it.

Re: [ANSWERED]Restful and password

PostPosted: Tue Apr 22, 2014 8:21 am
by marceltrapman
Hi Matt,

This is new to me (as well) but shouldn't the server provide 'me' with the nonce and qop or am I wrong here?
If so, how do I get hold of these values?

Security is not much of a concern yet but I think it is better to put a secure connection in place first.
Are there any known issues when I would set up a reverse proxy for the indigo web server?

Re: [ANSWERED]Restful and password

PostPosted: Tue Apr 22, 2014 10:19 am
by matt (support)
Correct, the server provides those but then the client has to use them in calculating its MD5 response value. I wasn't sure if you were taking all of those values into account with the HTTP request you were making.

Reverse proxy via Apache is an option. Forum users jamus has some relevant info documented here.

Re: [ANSWERED]Restful and password

PostPosted: Tue Apr 22, 2014 1:41 pm
by marceltrapman
OK, thanks for your help.

Strange thing is that I experience unexpected behaviour from both Indigo Touch and Remote Patrol (SecuritySpy) now.
Funny thing is that Remote Patrol will not connect to SecuritySpy anymore but connects to Indigo just fine and Indigo Touch won't connect to Indigo anymore.
I guess that this red flag tells me to do some more digging :)

Re: [ANSWERED]Restful and password

PostPosted: Tue Apr 22, 2014 2:23 pm
by matt (support)
Take a look at this forum thread for info on reverse proxy and Indigo Touch.

Re: [ANSWERED]Restful and password

PostPosted: Tue Apr 22, 2014 3:42 pm
by marceltrapman
Apologies, I should have been more clear.

I use a self signed certificate (generated using OS X Server) and it is not accepted by Indigo Touch.

Re: [ANSWERED]Restful and password

PostPosted: Thu May 01, 2014 10:18 pm
by matlock
Matt: quick followup question on this...

Is there anyway for an IWS plugin to specify the authentication type for everything under its path? In other words, I'd like digest for everything EXCEPT my IWS plugin (since the remote host doing the web calls isn't intelligent enough to understand digest).

Also, I'm glad I found this post, with the link to IndigoWebServer.conf .. I was manually editing IndigoWebServer.py each time, not realizing it had semi-hidden configuration file. doh. :)

Re: [ANSWERED]Restful and password

PostPosted: Fri May 02, 2014 10:41 am
by matt (support)
That might be possible. I believe another user did something similar in one of their plugins. I'll email him and see if he can chime in here with what he did.

Re: [ANSWERED]Restful and password

PostPosted: Fri May 02, 2014 11:02 am
by jay (support)
Just a warning here - the IWS Plugin API is very likely to be deprecated in the major next release of Indigo in favor of a replacement that will use the IOM. Just don't want you to spend significant time on something that will likely not work in the next major release... ;)

Re: [ANSWERED]Restful and password

PostPosted: Fri May 02, 2014 6:29 pm
by bschollnick2
matlock wrote:
Matt: quick followup question on this...
Is there anyway for an IWS plugin to specify the authentication type for everything under its path? In other words, I'd like digest for everything EXCEPT my IWS plugin (since the remote host doing the web calls isn't intelligent enough to understand digest).

Also, I'm glad I found this post, with the link to IndigoWebServer.conf .. I was manually editing IndigoWebServer.py each time, not realizing it had semi-hidden configuration file. doh. :)


Matlock,

It is possible, but I am sure that it is certainly unsupported by Matt / Indigo / Perceptive Automation.

I have gotten this to work under the RFID plugin, but it's a little bit of voodoo.

I hope this helps.
Code: Select all
      def __init__(self, logFunc, debugLogFunc):
         BaseRequestHandler.__init__(self, logFunc, debugLogFunc)
         self.JSON.__dict__['exposed'] = True
         self.HOME.__dict__['JSON'] = self.JSON
         import threading
         postLoadTimer = threading.Timer (0.50, lambda:self.postLoad())
         postLoadTimer.start()

      def   postLoad ( self ):
          # Config overrides that should be merged on to the /rfid path only:
   
         #   Partially modeled after,
         # http://pydoc.net/Python/CherryPy/3.1.0beta3/cherrypy.test.test_httpauth/          
         #
         
         bottle = self.load_bottle ()
         
         if bottle <> ({},):
            rfid_config = {}
            if bottle [0][ u"misc"] [u"Preferences_Username"] <> "":
               username = bottle [0][ u"misc"][u'Preferences_Username']
               password = bottle [0][ u"misc"][u'Preferences_Password']
               
               rfid_config = {   r'/': {   'tools.digest_auth.on'      : True,
                                 'tools.digest_auth.realm'   : u"Indigo Control Server",
                                 'tools.digest_auth.users'   : {'%s' % username:  md5.new("%s:%s:%s" % (username, u"Indigo Control Server", password)).hexdigest() },
#                                 'tools.staticdir.dir'      : icon_target,
                           },
                               r'/HOME/IMAGE': {   'tools.digest_auth.on'      : True,
                                             'tools.digest_auth.realm'   : u"Indigo Control Server",
                                             'tools.digest_auth.users'   : {'%s' % username:  md5.new("%s:%s:%s" % (username, u"Indigo Control Server", password)).hexdigest() },
                                             'tools.staticdir.on'      : True,
                                             'tools.staticdir.dir'      : icon_target},
                                 }
            else:
               rfid_config = {       r'/HOME/IMAGE': {   'tools.staticdir.on'      : True,
                                             'tools.staticdir.dir'      : icon_target},
                                 }
            
#           '/'      : {'tools.staticdir.root': os.path.join (current_dir, 'media')},
#           '/css'   : {'tools.staticdir.on': True,'tools.staticdir.dir' : 'css'},
#          '/js'    : {'tools.staticdir.on': True, 'tools.staticdir.dir': 'js'},
#         '/images': {'tools.staticdir.on': True,'tools.staticdir.dir' : 'images'}
#        }
                  #   http://tools.cherrypy.org/wiki/AuthenticationAndAccessRestrictions
      
            # allow custom app path name for users wanting to use a proxy
            app_root_path = cherrypy.config.get('app_root_path', "")
            module_path = r"%s/RFID/" % (app_root_path)

            target_app_url = cherrypy.tree.script_name(module_path)
            target_app = cherrypy.tree.apps[target_app_url]
            target_app.merge(rfid_config)

            # And the password hash used by HTTP digest (as defined in RFC2617) is shown below. You'll
            # use that in your _RfidPasswordLookup callback.


Re: [ANSWERED]Restful and password

PostPosted: Tue Jul 28, 2015 7:25 am
by wickey
marceltrapman wrote:
After (a lot) more reading I found that I should use Digest.

I know that, without authentication my code works.
With authorization and without authorization header a 401 status is returned.
With authorization and with authorization header a 500 status is returned :(

This is what I use (Arduino stuff):
Code: Select all
//generate the MD5 hash for our string
unsigned char* authHash = MD5::make_hash("username:Indigo Control Server:password");
//generate the digest (hex encoding) of our hash
char* authValue = MD5::make_digest(authHash, 16);



Will be able to share a code example for this. because I am also struggling with this from few days.