Home AMX User Forum NetLinx Studio

Q: IP-String with password

hi together

i have a problem to control a password protected device on ip.

when i control the device with my webbrowser so i must type in a
user and password. (it's not possible to deactivate this!).
now when i will control this device with ip-communication from my master, it doesn't work, because i don't know how must i send the login on ip.

is there anyone how can send me a hint?

thanks a lot
john

Comments

  • In HTTP it's possible to put username & password into the Link:
    http://myname:mypass@www.somewhere.de
    It also may work with ftp
    ftp://suer:pass@ftp.somewhere.de

    AFAIK Internet Explorer doesn't support that any longer, but Opera browser will.

    In what protocol does the device be controlled? http, telnet, any other ip port, etc? If you have to control it by http, I'm not sure if every http GET or SET must be sent with user/pass.
  • hi Marc

    thanks for the answer.
    i will it control by http. i will test your hint.
    thanks
    john


    In what protocol does the device be controlled? http, telnet, any other ip port, etc? If you have to control it by http, I'm not sure if every http GET or SET must be sent with user/pass.[/QUOTE]
  • Chip MoodyChip Moody Posts: 727
    If you're doing this over HTTP, you're trying to pass a GET command to make things work, correct? If so, I'll post some code and HTTP header stuff that will help.

    - Chip
  • hi chip

    thanks, yes the GET command is included.

    thanks
    john
    Chip Moody wrote:
    If you're doing this over HTTP, you're trying to pass a GET command to make things work, correct? If so, I'll post some code and HTTP header stuff that will help.

    - Chip
  • Chip MoodyChip Moody Posts: 727
    Sorry - didn't get to check the boards all day Friday - on the road & just getting in now. I'll post some stuff for you tomorrow. (Okay, later today, technically)

    - Chip
  • Chip MoodyChip Moody Posts: 727
    Without authentication, you're basically trying to make a HTTP request header with a single line that contains the GET command. To add authentication, you need to add some more to your header. Here's what I'd suggest:
    SEND_STRING TCPport,"'GET ',PathNFilename,' HTTP/1.1',crlf"
    SEND_STRING TCPport,"'Host: ',HostName,crlf"
    SEND_STRING TCPport,"'Connection: close',crlf"
    SEND_STRING TCPport,"'Authorization: Basic ',Base64("UN,':',PW"),crlf"
    SEND_STRING TCPport,"'crlf'"  // indicate end of header
    

    If you're just doing this to equipment on your private LAN, you can probably skip the 'Host: ' line. If you ever try to do this with a resource on the web, you'll need to include this. HostName is the same string you passed to IP_CLIENT_OPEN for the server address.

    'Connection: close' is more for HTTP 1.1 compliance than anything else, but if you're making just a single request and not needing the connection beyond that, you'll want to include this. Some servers (Like the NetLinx master webserver) will leave the connection open and let it timeout if you don't include this line while making a HTTP 1.1 request.

    The 'Authrization: Basic' is the one you're most concerned with. On this line, you need to include a Base64 encoded version of your username & password, seperated by a colon.

    And no, I'm not going to tease you by letting you hang without a Base64 encoder block. That's in the next message. :)

    Oh yeah, I include "crlf[2] = {$0D,$0A}" in DEFINE_CONSTANT in about 99 percent of my programs. It's just too damn handy.


    - Chip

    John_Glove wrote:
    hi chip

    thanks, yes the GET command is included.

    thanks
    john
  • Chip MoodyChip Moody Posts: 727
    Here's the Base64 encoder:
    DEFINE_FUNCTION CHAR[255] Base64 (CHAR Source[])
    {
      LOCAL_VAR CHAR    Uncode[255]      // Password protected sites require that the
      LOCAL_VAR CHAR    Coded[255]       // username & password get encoded together in
      LOCAL_VAR CHAR    Munch[3]         // Base64 format.  Don't know what Base64 is?
      LOCAL_VAR CHAR    Chew[4]          // Neither did I until I looked at
      LOCAL_VAR INTEGER Step             // http://freesoft.org/CIE/RFC/2065/56.htm
                                         // and http://freesoft.org/CIE/RFC/1521/7.htm
      Coded = ''
      Chew = '    '
      Uncode = Source
      WHILE (LENGTH_STRING(Uncode) >= 3)
      {
        Munch = GET_BUFFER_STRING(Uncode,3)
        Chew[1] = Munch[1]
        Chew[1] = Chew[1] / 4    
        Chew[2] = ((Munch[1] * 16) BAND $30)
        Chew[2] = Chew[2] + ((Munch[2] / 16) BAND $F)    
        Chew[3] = ((Munch[2]*4) BAND $3C)
        Chew[3] = Chew[3] + ((Munch[3] / 64) BAND $3)    
        Chew[4] = Munch[3] BAND $3F
        Coded = "Coded,Chew"
      }
      SELECT
      {
        ACTIVE (LENGTH_STRING(Uncode) = 2):
        {
          Munch = "GET_BUFFER_STRING(Uncode,2)"
          Chew[1] = Munch[1]
          Chew[1] = Chew[1] / 4      
          Chew[2] = ((Munch[1] * 16) BAND $30)
          Chew[2] = Chew[2] + ((Munch[2] / 16) BAND $F)        
          Chew[3] = ((Munch[2]*4) BAND $3C)      
          Chew[4] = 64
          Coded = "Coded,Chew"         
        }
        ACTIVE (LENGTH_STRING(Uncode) = 1):
        {
          Munch = GET_BUFFER_STRING(Uncode,1)
          Chew[1] = Munch[1]
          Chew[1] = Chew[1] / 4      
          Chew[2] = ((Munch[1] * 16) BAND $30)      
          Chew[3] = 64
          Chew[4] = 64
          Coded = "Coded,Chew"  
        }
      }
      FOR (Step = 1;Step <= LENGTH_STRING(Coded);Step++)
      {
        SELECT
        {
          ACTIVE (Coded[Step] <= 25): Coded[Step] = Coded[Step] + 65
          ACTIVE (Coded[Step] <= 51): Coded[Step] = Coded[Step] + 71
          ACTIVE (Coded[Step] <= 61): Coded[Step] = Coded[Step] - 4
          ACTIVE (Coded[Step] = 62):  Coded[Step] = '+'
          ACTIVE (Coded[Step] = 63):  Coded[Step] = '/'
          ACTIVE (coded[Step] = 64):  Coded[Step] = '='
        }
      }
      RETURN Coded
    }
    
  • Chip MoodyChip Moody Posts: 727
    Hey John - how are you making out with this? All working?!

    - Chip
  • John_GloveJohn_Glove Posts: 95
    hi chip

    yes, thanks very much. all working!

    thanks

    John
  • Thank you!

    Chip,
    Thanks for the base64 function. This solved my issue with controlling an IP camera. We previously just displayed the image, and now they have full directional and preset control.

    Thanks!

    Chris
  • DHawthorneDHawthorne Posts: 4,584
    I had been using the Base64 function in the i!-EquipmentMonitorOut include, but recently had the need to decode base64 as well as encode it, so I re-wrote the AMX Base64 (basically just cleaned it up a tad) and added a decoder to my own axi. I was intending to post it in any case, then saw this thread and figured it was a good spot to share it.

    One caveat to using Base64 is that you really have to remember it's not a security encryption method. It's intent is to encode binary values in printable ASCII for things like e-mail. It can serve to obscure sensitive data, but as a widely known method, it's not very secure.

    If you weren't using it for an authentification header, you could kind of roll your own by scrambling the character set in the lookup table. I'm sure any cryptologist worth his or her salt could crack it, but it would probably stymie most hackers just using any of the half-zillion base64 decoders out there. But, as I said elsewhere, if you still have to send it base64 somewhere along the line, it would be like locking the front door and leaving the back with just a hook latch.

    In any case, here's an encoder and decoder for base64.
  • Cool and thanks

    Thanks for this, Chip and Dave. It saves a few hours work coding and testing.

    Cheers,
    Ron
Sign In or Register to comment.