Page 1 of 1

Some Very Basic Questions about urls and Sockets

Posted: Tue Jun 15, 2010 4:20 pm
by edgore
I am still working through how to best query LDAP in this little application I am trying to write,

It looks like using LDAP URLS, which my server supports, is the easiest way to do it - I don't have to write a full ldap client that way.

What I am not sure about is how, exactly, I should be sending those urls to the server so it will accept them. I have looked through various RFCs, but it almost seems like I am missing something so basic they they don't even talk about it...

Here is what I have so far:

I open the socket to the server, and send the url ldap://directory.xxxxx.com/ou=people,o=xxxxx,c=us??sub?(uid=1234567) to the the server, then read the socket. Since I wasn't sure if read Socket accepted "until eof", I figured I would just try reading a 1000 chars and see what I got. What I get is eof in the result, nothing in "it", and the socket is closed, I assume by the server since I am annoying it with junk requests.

I am assuming that what I am doing wrong is something basic - like I am not supposed to send the entire url, or I am not supposed to urlencode all of it, or it's supposed to be binary encoded for sending or something. I have tried several variations, but none of them seem to work.

I have tested the url I am sending using explorer and firefox, and which return the expected data. According according to the RFC it's html text, though it looks like the mimetype is set the vcard, since it opens in Windows address book. Names x'ed out to protect my employer.

At first I thought that maybe the processing of the URL had to be done on the client end and parsed into standard LDAP requests, but the documentation for the LDAP server we are using clearly states that it accepts LDAP URLS and returns HTML text.

Here is the script that I am currently trying - it's basic and needs work - I am just trying to get something to work first - but I figured it might be useful to see

This is the stack script - I send the messages openLdapSocket, sendLdapRequest and LdapDisconnect using buttons on the stack's only card.

Code: Select all

local lLDAPsocket

on openLdapSocket
   put "directory.xxxxx.com:389" &"|LDAP" into lLDAPsocket
   open socket to lLDAPsocket with message "ldapConnected"
end openldapsocket

on socketTimeout theID
  answer error "The connnection is not responding." with "Keep Trying" or "Cancel"
  if it is "Cancel" then close socket theID
end socketTimeout

on LdapDisconnect
   close socket lLDAPsocket
   disable the target
   enable button "connectLDAP"
   set the visible of field "connected2LDAP" to false
   put empty into lLDAPsocket
end LdapDisconnect

on sendLdapRequest
   put "ldap://directory.xxxxx.com/ou=people,o=xxxxx,c=us??sub?(uid=1234567)" into theLdapRequest
   put urlencode(theLdapRequest) into theLdapRequest
   write theLdapRequest to socket lLDAPsocket with message "LDAPresponse"
   put the result
end sendLDAPRequest

on ldapConnected
   --this just provides feedback that the connection succeeds
   if the opensockets contains lLDAPsocket then
      set the visible of field "connected2LDAP" to true
      disable button "connectLdap"
      enable button "disconnectLdap"
   end if
end ldapConnected
   
on LDAPresponse
   read from socket lLDAPsocket for 1000 chars
   put the result
   put it into field "LDAPResponse"
end LDAPresponse
As always, any help is much appreciated.

Re: Some Very Basic Questions about urls and Sockets

Posted: Tue Jun 15, 2010 5:03 pm
by bn
Ed,
I don't know nothing about sockets. But what strikes me in your script is that you declare a script local varible "lLDAPsocket" and than you make calls to "gLDAPsocket" in the "sendLdapRequest" and "ldapResponse" handler. Either you are referring to lLDAPsocket you would have to change the variable names in the later handlers, or you would have to declare the gLDAPsocket as global somewhere.

regards
Bernd

Re: Some Very Basic Questions about urls and Sockets

Posted: Tue Jun 15, 2010 6:16 pm
by edgore
It looks like I made a couple of mistakes when I retranscribed this for the board. I have edited the post above and it now matches what I am using, except for the x'ed out domain info.

Re: Some Very Basic Questions about urls and Sockets

Posted: Tue Jun 15, 2010 11:47 pm
by edgore
So, I am slowly learning more as I try to figure this out...

LDAP port 389 is described as a plain text port. This means, I assume, that I don't have to do any binary encoding.

URL encoding is only used when for reserved characters when they are being used outside of their special role. Since "=" "," and "?" are all part of the url specification for ldap urls, I'm assuming that they should not be encoded. Based on what I have been able to learn from looking up stuff about encoding, the parens don't reuiqre encoding either, since they are in the range 032-064 of ISO 8859-1 and not the quote, ampersand, less than and greater than characters. So, in the sample url I provided, nothing should be url encoded.

Based on this I have modified my script to no longer url encode.

I also changed the LDAPresponse, which tries to read from the socket, to provide a little more info - it now tries to read fromt eh socket one character at a time, and if it doesn't get a response it provides a little more info about what it found. Right now on my system I get the empty response in the msg, which indicates there was no data to read from the socket.

I also added some stuff to try to detect socket errors, but I don't seem to ever get a socket error message.

Oh, and all output goes to the message box now.

Here is the new stack script:

Code: Select all

local lLDAPsocket

on openLdapSocket
   put "directory.fedex.com:389" &"|LDAP" into lLDAPsocket
   open socket to lLDAPsocket with message "ldapConnected"
end openldapsocket

on socketError theID, theError
   put msg & cr & theError
   close socket theID
end socketError

on socketTimeout theID
  answer error "The connnection is not responding." with "Keep Trying" or "Cancel"
  if it is "Cancel" then close socket theID
end socketTimeout

on LdapDisconnect
   close socket lLDAPsocket
   disable the target
   enable button "connectLDAP"
   set the visible of field "connected2LDAP" to false
   put empty into lLDAPsocket
end LdapDisconnect

on sendLdapRequest
   put "ldap://directory.fedex.com/ou=people,o=fedex,c=us??sub?(uid=751889)" into theLdapRequest
   write theLdapRequest to socket lLDAPsocket with message "LDAPresponse"
   put msg & cr & the result
end sendLDAPRequest

on ldapConnected
   --this just provides feedback that the connection succeeds
   if the opensockets contains lLDAPsocket then
      set the visible of field "connected2LDAP" to true
      disable button "connectLdap"
      enable button "disconnectLdap"
   end if
end ldapConnected
   
on LDAPresponse
   --tried the following based on the user note on Read from Socket in the dictionary
   --read from socket lLDAPsocket for 0 --didn't work
   
   -- try to read the socket char by char
   --this also also based on the user note in read from socket
   put empty into tSocketResponse
   
   repeat forever
      read from socket lLDAPsocket for 1
      put it into tSocketChar
      switch tSocketChar
         case empty
            if tSocketResponse is empty then
               put msg & cr & "No data was read from the socket - empty"
               exit repeat
            else
               put msg & cr & tSocketResponse
               exit repeat
            end if
            break
         case eof
            if tSocketResponse is empty then
               put msg & cr & "No data was read from the socket - eof"
               exit repeat
            else
               put msg & cr & tSocketResponse
               exit repeat
            end if
            break
         case null
            if tSocketResponse is empty then
               put msg & cr & "No data was read from the socket - null"
               exit repeat
            else
               put msg & cr & tSocketResponse
               exit repeat
            end if
            break
         default
            put tSocketChar & it into tSocketChar
      end switch     
   end repeat
end LDAPresponse
Thanks!

Re: Some Very Basic Questions about urls and Sockets

Posted: Wed Jun 16, 2010 10:01 pm
by edgore
Still not having any luck with this. I have put together a stack you can look at to see what I am doing. It's at http://www.edgore.com/rev/LDAPtest.zip

I have modified it so it tries to look up someone in the umich.edu public LDAP directory, so this should work for anyone, anywhere, without modifications.

The Attempt LDAP button tries to look up the url hardcoded into the script (which works in firefox and explorer). I have tried to put as much error detection and debugging info into the script as I could - everything get's narrated in the message box as it happens, and I frequently check the socket and report on it's status. The SHow open sockets button does just that. The disconnect LDAP button closes the connection - not that you should ever need to, but it's there. The radio buttons allowed me to try various combinations of things to try terminating the rul with when I send it, and various terminators to look for in the response. The edit script button opens the stack script, which is where everything happens.

I have also rewritten everything related to the sending and recieving of the url into a single, blocking script, just in case that was a problem before. Still not luck - I keep getting an empty socket when I try to read.

Thanks for any help you can give,

Edwin

Re: Some Very Basic Questions about urls and Sockets

Posted: Thu Jun 17, 2010 4:44 pm
by edgore
I was able to get a look at the logs for my corporate ldap server and it shows the connection opening and closing, but no record of any url being recived. Like I said, I am missing something very basic here. Any help appreciated.

This is the log entry for the connection -

[17/Jun/2010:10:28:03 -0500] conn=5669125 op=-1 msgId=-1 - fd=162 slot=162 LDAP connection from 10.10.35.135 to 146.18.228.71
[17/Jun/2010:10:28:03 -0500] conn=5669125 op=-1 msgId=-1 - closing - B1
[17/Jun/2010:10:28:03 -0500] conn=5669125 op=-1 msgId=-1 - closed.

The error message B1 is defined as:

B1=Corrupt BER tag encountered or BER tag is longer than the nsslapd-maxbersize attribute value. For further information about this configuration attribute, see "nsslapd-maxbersize (Maximum Message Size)".

If BER tags, which encapsulate data being sent over the wire, are corrupt when they are received, a B1 connection code is logged to the access log. BER tags can be corrupted due to physical layer network problems or bad LDAP client operations, such as an LDAP client aborting before receiving all request results.

Our server is set the the default of 2 megabytes for the message size, so it can't be that. I am assuming that it must be corrupt then, but no idea how the fix that.

Re: Some Very Basic Questions about urls and Sockets

Posted: Tue Jul 06, 2010 4:15 pm
by edgore
I have finally given up and resorted to just screen-scraping from our intranet's people directory pages. Obviously this is not ideal, but it's getting me what I need for today. If anyone has any ideas about how I might go about creating an actual LDAP client though I would love to hear them!

Re: Some Very Basic Questions about urls and Sockets

Posted: Tue Jul 06, 2010 11:26 pm
by mwieder
Edwin-

LDAP packet payloads are in binary format. You can get a simple idea of the format from http://tools.ietf.org/html/rfc4532. You'll have to create the header information yourself, then follow it with a hex byte containing length(command string) and then the command string itself.

You might want to pick up one of the open-source LDAP tools and a sniffer program to see a valid transaction in progress. My favorite sniffers are ngrep for Windows and Wireshark for OSX, but YMMV.

Re: Some Very Basic Questions about urls and Sockets

Posted: Wed Jul 07, 2010 4:50 pm
by edgore
Thanks - I will take a look at that RFC and fool around with the windows tool that you mentioned and see what I can puzzle out.