r3303 - in trunk/libmnetutil: . include include/libmnetutil m4 source
mikaelsv at minisip.org
mikaelsv at minisip.org
Tue Jun 12 10:48:39 CEST 2007
Author: mikaelsv
Date: 2007-06-12 10:48:39 +0200 (Tue, 12 Jun 2007)
New Revision: 3303
Added:
trunk/libmnetutil/include/libmnetutil/Downloader.h
trunk/libmnetutil/include/libmnetutil/HttpDownloader.h
trunk/libmnetutil/include/libmnetutil/LdapConnection.h
trunk/libmnetutil/include/libmnetutil/LdapCredentials.h
trunk/libmnetutil/include/libmnetutil/LdapDirectoryLocator.h
trunk/libmnetutil/include/libmnetutil/LdapEntry.h
trunk/libmnetutil/include/libmnetutil/LdapException.h
trunk/libmnetutil/source/Downloader.cxx
trunk/libmnetutil/source/HttpDownloader.cxx
trunk/libmnetutil/source/LdapConnection.cxx
trunk/libmnetutil/source/LdapEntry.cxx
trunk/libmnetutil/source/LdapException.cxx
Modified:
trunk/libmnetutil/Makefile.am
trunk/libmnetutil/configure.ac
trunk/libmnetutil/include/Makefile.am
trunk/libmnetutil/m4/libmnetutil.m4
Log:
Three new features have been added:
* Basic LDAP support
- This support is optional and included by adding the --enable-ldap command
when configuring the compilation.
- Requires OpenLDAP
- Supports strings and binary attribute values
* Downloading files using HTTP
- Does not support HTTPS, but since a StreamSocket can be used to tunnel
the HTTP messages (the StreamSocket is then supplied as an argument to
the HttpDownloader constructor) encryption can be achieved using such
work-around.
* The Downloader::create(std::string uri) function can be used to create
"downloaders" for any given URI (but right now only HTTP URIs are supported)
Modified: trunk/libmnetutil/Makefile.am
===================================================================
--- trunk/libmnetutil/Makefile.am 2007-06-11 14:24:32 UTC (rev 3302)
+++ trunk/libmnetutil/Makefile.am 2007-06-12 08:48:39 UTC (rev 3303)
@@ -11,7 +11,7 @@
lib_LTLIBRARIES = libmnetutil.la
# libmnetutil_la_CPPFLAGS =
libmnetutil_la_LDFLAGS = $(MINISIP_LIBRARY_LDFLAGS)
-libmnetutil_la_LIBADD = udns/libudns.la $(LTLIBOBJS) $(MINISIP_LIBS)
+libmnetutil_la_LIBADD = udns/libudns.la $(LTLIBOBJS) $(MINISIP_LIBS) $(LDAP_LIBS)
libmnetutil_la_DEPENDENCIES = $(LTLIBOBJS)
libmnetutil_la_SOURCES = $(mnetutil_src)
@@ -32,6 +32,14 @@
source/IP6ServerSocket.cxx
endif
+ldap_src =
+if ENABLE_LDAP
+ldap_src += \
+ source/LdapConnection.cxx \
+ source/LdapEntry.cxx \
+ source/LdapException.cxx
+endif
+
mnetutil_src = \
source/init.cxx \
source/DnsNaptr.cxx \
@@ -39,6 +47,7 @@
source/IP4Address.cxx \
source/IP4ServerSocket.cxx \
$(ipv6_src) \
+ $(ldap_src) \
source/NetworkException.cxx \
source/NetworkFunctions.cxx \
source/ServerSocket.cxx \
@@ -49,7 +58,9 @@
source/UDPSocket.cxx \
source/DatagramSocket.cxx \
$(win32_src) \
- source/StreamSocket.cxx
+ source/StreamSocket.cxx \
+ source/Downloader.cxx \
+ source/HttpDownloader.cxx
# maintainer rules
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
Modified: trunk/libmnetutil/configure.ac
===================================================================
--- trunk/libmnetutil/configure.ac 2007-06-11 14:24:32 UTC (rev 3302)
+++ trunk/libmnetutil/configure.ac 2007-06-12 08:48:39 UTC (rev 3303)
@@ -27,6 +27,19 @@
AC_CHECK_HEADERS([ifaddrs.h netdb.h sys/socket.h])
AM_MINISIP_CHECK_IPV6
+AC_ARG_ENABLE(ldap,
+ AS_HELP_STRING([--enable-ldap],
+ [enables LDAP support]),
+ [ if test "${enable_ldap}" = "yes"
+ then
+ AM_MINISIP_CHECK_LDAP
+ AC_DEFINE(ENABLE_LDAP, [], [LDAP support is enabled])
+ ENABLE_LDAP="yes"
+ fi
+ ])
+AM_CONDITIONAL(ENABLE_LDAP, test "${ENABLE_LDAP}" = "yes" )
+AC_SUBST(LDAP_LIBS)
+
AG_CHECK_POSIX_REGCOMP
AM_CONDITIONAL(HAVE_POSIX_REGCOMP, test "${ag_cv_posix_regcomp}" = "yes")
Modified: trunk/libmnetutil/include/Makefile.am
===================================================================
--- trunk/libmnetutil/include/Makefile.am 2007-06-11 14:24:32 UTC (rev 3302)
+++ trunk/libmnetutil/include/Makefile.am 2007-06-12 08:48:39 UTC (rev 3303)
@@ -1,4 +1,15 @@
+ldap_src =
+if ENABLE_LDAP
+ldap_src += \
+ libmnetutil/LdapConnection.h \
+ libmnetutil/LdapCredentials.h \
+ libmnetutil/LdapDirectoryLocator.h \
+ libmnetutil/LdapEntry.h \
+ libmnetutil/LdapException.h
+endif
+
pkginclude_HEADERS = \
+ $(ldap_src) \
libmnetutil/init.h \
libmnetutil/DnsNaptr.h \
libmnetutil/IPAddress.h \
@@ -12,7 +23,9 @@
libmnetutil/NetUtil.h \
libmnetutil/UDPSocket.h \
libmnetutil/DatagramSocket.h \
- libmnetutil/libmnetutil_config.h
+ libmnetutil/libmnetutil_config.h \
+ libmnetutil/Downloader.h \
+ libmnetutil/HttpDownloader.h
noinst_HEADERS = \
config.h \
Added: trunk/libmnetutil/include/libmnetutil/Downloader.h
===================================================================
--- trunk/libmnetutil/include/libmnetutil/Downloader.h (rev 0)
+++ trunk/libmnetutil/include/libmnetutil/Downloader.h 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef DOWNLOADER_H
+#define DOWNLOADER_H
+
+#include <libmutil/MemObject.h>
+#include <string>
+
+using namespace std;
+
+/**
+ * Creates objects for downloading documents specified by and URI.
+ *
+ * This class provides an easy interface for fetching files over the Internet
+ * using a variety of protocols. This class does not fetch any data but only
+ * creates an object that later can be used for fetching the actual data.
+ *
+ * The class is very generic, hence very limited and since it is abstract it
+ * cannot be instantiated by itself.
+ *
+ */
+class Downloader : public MObject {
+
+ public:
+ /**
+ * Uses the protocol portion of the specified URI to determine
+ * what type of object should be created to handle the download.
+ *
+ * Currently only supports HTTP download using the HttpDownloader class.
+ *
+ * @param uri Full URI for a remote document (e.g. "http://www.kth.se/index.html")
+ */
+ static MRef<Downloader*> create(string const uri);
+
+ virtual std::string getMemObjectType() const {return "Downloader";};
+
+ /**
+ * Returns the document in question. In order to support both
+ * textual and binary documents there is no function for
+ * retrieving the remote document as a string (this would not
+ * work well with binary data).
+ */
+ virtual const char* getChars() = 0;
+
+};
+
+
+#endif
Added: trunk/libmnetutil/include/libmnetutil/HttpDownloader.h
===================================================================
--- trunk/libmnetutil/include/libmnetutil/HttpDownloader.h (rev 0)
+++ trunk/libmnetutil/include/libmnetutil/HttpDownloader.h 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,212 @@
+/*
+ Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _HTTPDOWNLOAD_H_
+#define _HTTPDOWNLOAD_H_
+
+#include <libmutil/MemObject.h>
+#include <libmnetutil/StreamSocket.h>
+#include <libmnetutil/TCPSocket.h>
+#include <libmnetutil/Downloader.h>
+#include <string>
+#include <vector>
+#include <map>
+
+#define HTTP_METHOD_1_0 "HTTP/1.0"
+
+#define HTTP_RESPONSECODE_OK 200
+#define HTTP_RESPONSECODE_NOTFOUND 404
+#define HTTP_RESPONSECODE_MOVEDPERMANENTLY 301
+#define HTTP_RESPONSECODE_MOVEDTEMPORARILY 302
+#define HTTP_RESPONSECODE_SERVERERROR 500
+
+#define HTTP_HEADER_FROM "From"
+#define HTTP_HEADER_USERAGENT "User-Agent"
+#define HTTP_HEADER_SERVER "Server"
+#define HTTP_HEADER_HOST "Host"
+#define HTTP_HEADER_ACCEPTS "Accepts"
+#define HTTP_HEADER_CONTENTTYPE "Content-Type"
+#define HTTP_HEADER_CONTENTLENGTH "Content-Length"
+#define HTTP_HEADER_LASTMODIFIED "Last-Modified"
+
+#define HTTP_HEADER_CRLF "\r\n"
+
+using namespace std;
+
+/**
+ * This class is a very simple HTTP user agent that fetches web pages using the HTTP 1.0 (not 1.1) protocol.
+ *
+ * The implementation is, as mentioned, very simplified and has the following limitations:
+ * - The entire requested document is stored in memory, thus exhausting the available system memory if large files are fetched
+ * - The above limitation is however not relevant as only the first 32 KiB of the requested document are fetched
+ * - Cannot cope with multi-line headers
+ * - Cannot handle password protected resources
+ * - Only handles HTTP (not HTTPS)
+ *
+ * Usage:
+ * # Initialize the class instance by calling the constructor
+ * # Call either downloadToFile(string), downloadToString() or requestHeaders()
+ * # Work with the document using the functions getHeader(string), getBody() and getResponseCode()
+ *
+ * Constructors and descructors are defined in HEADER FILE!
+ *
+ * @author Mikael Svensson
+ */
+class HttpDownloader : public Downloader {
+ public:
+ /**
+ * Connects to HTTP server but does not fetch file.
+ *
+ * @param url File/document to fetch.
+ */
+ HttpDownloader(string url) : url (url), remotePort(80), respCode(-1), followRedirect(true), sock(NULL), internalSocketObject(false) {
+ parseUrl();
+ if (remotePort > 0 && remoteHostname != "") {
+ sock = new TCPSocket(remoteHostname, remotePort);
+ internalSocketObject = true;
+ }
+ }
+
+ /**
+ * This constructor is useful when tunneling HTTP over other protocols than pure TCP.
+ *
+ * Since the constructor HttpDownload(string) opens up an new TCP connection directly it is not
+ * useful when encryption is needed (e.g. when using the TlsSrpSocket). In these cases
+ * a StreamSocket object can be created outside the HttpDownloader object and passed to this
+ * constructor for use by the download functions later on.
+ *
+ * @note The StreamSocket sock will *not* be closed after usage, even though this is not an HTTP 1.1 compatible client.
+ * @param url File/document to fetch.
+ * @param sock Pre-existing socket to use for communicating with HTTP server.
+ */
+ HttpDownloader(string url, StreamSocket * sock): url (url), remotePort(80), respCode(-1), followRedirect(true), sock(sock), internalSocketObject(false) {
+ parseUrl();
+ }
+
+ /**
+ * The default constructor deallocates memory, if allocated.
+ */
+ ~HttpDownloader() {
+ if (internalSocketObject)
+ delete sock;
+ }
+
+
+ const char* getChars();
+ /**
+ * Fetch remote file and save as file on local computer.
+ */
+ bool downloadToFile(string filename);
+
+ /**
+ * Fetch remote file and return it as a single string
+ */
+ string downloadToString();
+
+ /**
+ * Fetch only HTTP headers for remote file.
+ *
+ * @return True on success, false otherwise.
+ */
+ bool downloadHeaders();
+
+ /**
+ * Return value of HTTP header.
+ *
+ * @note This function relies on that either downloadHeaders(), downloadToFile() or downloadToString() has been called prior.
+ * @param header Name of header to fetch.
+ */
+ string getHeader(string header);
+
+ /**
+ * Returns the response code.
+ *
+ * @note This function relies on that either downloadHeaders(), downloadToFile() or downloadToString() has been called prior.
+ */
+ int getResponseCode() const;
+
+ /**
+ * Sets whether or not redirection responses should be followed automatically.
+ *
+ * To prevent circular redirections (loops) a maximum of three redirections will be followed.
+ */
+ void setFollowRedirects(bool const val);
+ bool getFollowRedirects() const;
+
+ virtual std::string getMemObjectType() const {return "HttpDownloader";};
+
+ private:
+ // Variables
+ string url;
+ string remoteHostname;
+ string remoteProtocol;
+ string remoteFile;
+ int remotePort;
+ map<string, string> headers;
+ int respCode;
+ bool followRedirect;
+ StreamSocket * sock;
+ bool internalSocketObject;
+
+ // Functions
+ int fetch(string request, ostream & bodyStream);
+
+ /**
+ * Parse a line of the HTTP response and store the line as a key/value pair in the map of headers.
+ *
+ * Note that the header value is trimmed for white-space both from the right and left.
+ */
+ void parseHeader(string line);
+
+ /**
+ * Does not take into account the following things:
+ * - Header values might be split into multiple lines
+ * - Header lines can end with \\n instead of \\r\\n
+ */
+ int parseHeaders(stringstream & headers);
+
+ /**
+ * Used to parse the URL supplied in the constructor.
+ *
+ * The purpose is to pick out address, port and so on.
+ *
+ * Can probably not handle "Location: /index.php" but only "Location: http://full-server-name/index.php"
+ */
+ void parseUrl();
+
+ /**
+ * @deprecated Use the very similar split() from libmutil/stringutils.h instead.
+ * @param data String to be split
+ * @param token Separator
+ * @param res The string vector where the strings found will be stored
+ * @param maxChars The maximum number of characters of data that will be scanned (-1 disables feature and entire string is scanned).
+ * @author Erik Ehrlund
+ * @author Mikael Svensson
+ */
+ void split(string data, string token, vector<string> &res, int maxChars = -1); // Copyright Erik Ehrlund
+
+ /**
+ * This function removes any spaces, line feeds, carrige returns and tabs from the beginning and end of the specified string.
+ *
+ * @deprecated Use the very similar trim() from libmutil/stringutils.h instead.
+ */
+ string trim(string s);
+ string buildRequestString(string method, string file);
+};
+
+#endif
Added: trunk/libmnetutil/include/libmnetutil/LdapConnection.h
===================================================================
--- trunk/libmnetutil/include/libmnetutil/LdapConnection.h (rev 0)
+++ trunk/libmnetutil/include/libmnetutil/LdapConnection.h 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,110 @@
+/*
+ Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef LDAPCONNECTION_H_
+#define LDAPCONNECTION_H_
+
+#include <ldap.h>
+
+#include <libmutil/MemObject.h>
+#include <libmnetutil/LdapException.h>
+#include <libmnetutil/LdapCredentials.h>
+#include <libmnetutil/LdapEntry.h>
+
+#include <ldap.h>
+#include <string>
+#include <vector>
+
+/**
+ * Manages one connection to one LDAP server.
+ *
+ * @author Mikael Svensson
+ */
+class LdapConnection : public MObject {
+ public:
+ LdapConnection(std::string host, int port);
+ LdapConnection(std::string host, int port, MRef<LdapCredentials*> cred);
+ LdapConnection(std::string host);
+ LdapConnection(std::string host, MRef<LdapCredentials*> cred);
+ ~LdapConnection();
+
+ /**
+ * Connects AND binds to the specified server. Automatically disconnects
+ * any existing connection.
+ */
+ void connect() throw (LdapException);
+
+ /**
+ * Tests if a connection has been set up.
+ *
+ * @param alsoCheckBind If set the function checks both if a connection has been established and if the client is "bound".
+ */
+ bool isConnected(bool alsoCheckBind = false);
+
+ /**
+ * Disconnect from server (unbind).
+ */
+ bool disconnect();
+
+ /**
+ * Sends a query to the LDAP server and blocks until the entire response has been returned.
+ *
+ * @param baseDn The root path on the server where the search should commence.
+ * @param query The LDAP query filter to be used to select entries/objects.
+ * @param attrs String vector containing the attribute names to return.
+ * @param scope The scope of the search. Possible values: LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE or LDAP_SCOPE_ONE.
+ * @return A vector containing LdapEntry instances. Each LdapEntry represents a returned object and each instance is already populated with the appropriate values when returned.
+ */
+ std::vector<MRef<LdapEntry*> > find(std::string baseDn, std::string query, std::vector<std::string> & attrs, int scope = LDAP_SCOPE_SUBTREE) throw (LdapNotConnectedException, LdapException);
+
+ /**
+ * Determine the base DN of the connected server.
+ *
+ * This is done by requesting the namingContexts attribute of all objects in the directory root.
+ * This is, obviously, not a query that includes sub-folder in the LDAP tree.
+ *
+ * This feature is not supported by all servers. If the method cannot determine the base DN
+ * of the directory it will throw an LdapUnsupportedException.
+ */
+ std::string getBaseDn() throw (LdapNotConnectedException, LdapUnsupportedException);
+
+ /**
+ * Set the credentials to use. Currently only simple authentication with a username and password is supported.
+ */
+ void setCredentials(MRef<LdapCredentials*> cred);
+
+ MRef<LdapCredentials*> getCredentials();
+
+ /**
+ * Return raw LDAP object pointer.
+ */
+ //LDAP* getLdapObject();
+ private:
+ LDAP* ld;
+ std::string hostname;
+ int port;
+ MRef<LdapCredentials*> cred;
+
+ /**
+ * Used internally to determine whether or not the client has executed a bind operation.
+ */
+ bool isBound;
+
+};
+
+#endif
Added: trunk/libmnetutil/include/libmnetutil/LdapCredentials.h
===================================================================
--- trunk/libmnetutil/include/libmnetutil/LdapCredentials.h (rev 0)
+++ trunk/libmnetutil/include/libmnetutil/LdapCredentials.h 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef LDAPCREDENTIALS_H_
+#define LDAPCREDENTIALS_H_
+
+#include <libmutil/MemObject.h>
+#include <libmcrypto/cert.h>
+
+#include <string>
+
+/**
+ * Simple data class for storing credentials.
+ *
+ * @author Mikael Svensson
+ */
+class LdapCredentials : public MObject {
+ public:
+ MRef<certificate*> cert;
+ std::string username;
+ std::string password;
+
+ LdapCredentials(std::string usr,std::string pw) : username(usr), password(pw) {
+ }
+};
+
+#endif
Added: trunk/libmnetutil/include/libmnetutil/LdapDirectoryLocator.h
===================================================================
--- trunk/libmnetutil/include/libmnetutil/LdapDirectoryLocator.h (rev 0)
+++ trunk/libmnetutil/include/libmnetutil/LdapDirectoryLocator.h 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,37 @@
+/*
+ Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef LDAPDIRECTORYLOCATOR_H_
+#define LDAPDIRECTORYLOCATOR_H_
+
+#include <libmutil/MemObject.h>
+
+/**
+ * Provides a selection of methods for locating LDAP servers. NOT IMPLEMENTED!
+ *
+ * @author Mikael Svensson
+ */
+class LdapDirectoryLocator : public MObject {
+ public:
+ static std::string findDnsSrv();
+ static std::string findDnsAlias();
+ static std::string findUserConfig();
+ static std::string findUserCache();
+ static std::string find();
+};
+#endif
Added: trunk/libmnetutil/include/libmnetutil/LdapEntry.h
===================================================================
--- trunk/libmnetutil/include/libmnetutil/LdapEntry.h (rev 0)
+++ trunk/libmnetutil/include/libmnetutil/LdapEntry.h 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,108 @@
+/*
+ Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef LDAPENTRY_H_
+#define LDAPENTRY_H_
+
+#include <ldap.h>
+#include <lber.h>
+#include <libmnetutil/LdapException.h>
+#include <libmutil/MemObject.h>
+
+#include <string>
+#include <map>
+#include <vector>
+
+class certificate_pair {}; //Dummy entry
+
+/**
+ * Class used internally by LdapEntry
+ *
+ * @author Mikael Svensson
+ */
+class LdapEntryBinaryValue : public MObject {
+ public:
+ LdapEntryBinaryValue(char* v, int l) : length(l) {
+ value = new char[length];
+ memcpy(value, v, length);
+ }
+ ~LdapEntryBinaryValue() {
+ delete[] value;
+ }
+ char* value;
+ int length;
+};
+
+/**
+ * Represents one object in the LDAP directory, including its attribute values.
+ *
+ * When the class instance is created it read an entire entry from an LDAP repsonse message
+ * and stores all information internally. This means that once all the LdapEntry objects
+ * have been created it is safe to free the memory allocated by the response message itself.
+ *
+ * The class differentiates between binary and non-binary attribute values (anything that is
+ * not binary is stored as strings). The separation is made based on the returned attribute
+ * names as it is assumed that all binary attributes have name which end with ";binary".
+ *
+ * Binary attribute values are stored in LdapEntryBinaryValue object whereas all other values
+ * are stored as strings.
+ *
+ * @author Mikael Svensson
+ */
+class LdapEntry : public MObject {
+ public:
+ LdapEntry(LDAP* ld, LDAPMessage* entry);
+ //~LdapEntry();
+
+ /**
+ * Return THE FIRST string value for a given attribute.
+ */
+ std::string getAttrValueString(std::string attr) throw (LdapAttributeNotFoundException);
+
+ /**
+ * Return all binary values for a given attribute.
+ */
+
+ std::vector< MRef<LdapEntryBinaryValue*> > getAttrValuesBinary(std::string attr) throw (LdapAttributeNotFoundException);
+ /**
+ * Return ALL string values for a given attribute.
+ */
+ std::vector<std::string> getAttrValuesStrings(std::string attr) throw (LdapAttributeNotFoundException);
+
+ /**
+ * Specialized method that returns all certificate pair attribute values (given a specific attribute name).
+ */
+ std::vector<MRef<certificate_pair*> > getAttrValuesCertificatePairs(std::string attr) throw (LdapAttributeNotFoundException);
+
+ //std::string getDn();
+
+ /**
+ * Returns list of all attribute names.
+ */
+ std::vector<std::string> getAttrNames();
+
+ /**
+ * Tests if the directory entry/object has a specific attribute.
+ */
+ bool hasAttribute(std::string attr);
+ private:
+ std::map<std::string, std::vector<MRef<LdapEntryBinaryValue*> > > valuesBinary;
+ std::map<std::string, std::vector<std::string> > valuesStrings;
+};
+
+#endif
Added: trunk/libmnetutil/include/libmnetutil/LdapException.h
===================================================================
--- trunk/libmnetutil/include/libmnetutil/LdapException.h (rev 0)
+++ trunk/libmnetutil/include/libmnetutil/LdapException.h 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2005, 2004 Erik Eliasson, Johan Bilien
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef LDAPEXCEPTION_H_
+#define LDAPEXCEPTION_H_
+
+#include <libmutil/Exception.h>
+#include <libmnetutil/libmnetutil_config.h>
+#include <string>
+
+/**
+ * @author Mikael Svensson
+ * @author Erik Eliasson <eliasson at it.kth.se>
+ * @author Johan Bilien <jobi at via.ecp.fr>
+ */
+class LIBMNETUTIL_API LdapException : public Exception {
+ public:
+ LdapException();
+ LdapException(std::string message);
+ virtual ~LdapException() throw() {};
+ virtual const char *what() const throw();
+ protected:
+ std::string msg;
+};
+
+class LIBMNETUTIL_API LdapAttributeNotFoundException : public LdapException {
+ public:
+ LdapAttributeNotFoundException(std::string message);
+};
+
+class LIBMNETUTIL_API LdapNotConnectedException : public LdapException {
+ public:
+ LdapNotConnectedException();
+};
+
+class LIBMNETUTIL_API LdapUnsupportedException : public LdapException {
+ public:
+ LdapUnsupportedException(std::string feature);
+};
+
+#endif
Modified: trunk/libmnetutil/m4/libmnetutil.m4
===================================================================
--- trunk/libmnetutil/m4/libmnetutil.m4 2007-06-11 14:24:32 UTC (rev 3302)
+++ trunk/libmnetutil/m4/libmnetutil.m4 2007-06-12 08:48:39 UTC (rev 3303)
@@ -1,3 +1,16 @@
+# AM_MINISIP_CHECK_LDAP
+#-----------------------
+AC_DEFUN([AM_MINISIP_CHECK_LDAP], [
+ # PKG_CHECK_MODULES([LDAP], [libldap], [liblber])
+
+ mnetutil_save_LIBS="${LIBS}"
+ LDAP_LIBS="-lldap -llber"
+ LIBS="${LDAP_LIBS} ${LIBS}"
+ AC_CHECK_FUNCS([ldap_init],,[AC_MSG_ERROR([OpenLDAP not found])])
+ LIBS="${mnetutil_save_LIBS}"
+])
+
+
# AM_MINISIP_ENABLE_IPV6(VERSION)
# -------------------------------
AC_DEFUN([AM_MINISIP_ENABLE_IPV6],[
Added: trunk/libmnetutil/source/Downloader.cxx
===================================================================
--- trunk/libmnetutil/source/Downloader.cxx (rev 0)
+++ trunk/libmnetutil/source/Downloader.cxx 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,15 @@
+#include <libmnetutil/Downloader.h>
+#include <libmnetutil/HttpDownloader.h>
+#include <string>
+
+using namespace std;
+
+MRef<Downloader*> Downloader::create(string const uri) {
+ int pos = uri.find("://");
+ if (string::npos != pos) {
+ string protocol = uri.substr(0, pos);
+ if (protocol == "http")
+ return MRef<Downloader*>(dynamic_cast<Downloader*>(new HttpDownloader(uri)));
+ }
+ return MRef<Downloader*>();
+}
Added: trunk/libmnetutil/source/HttpDownloader.cxx
===================================================================
--- trunk/libmnetutil/source/HttpDownloader.cxx (rev 0)
+++ trunk/libmnetutil/source/HttpDownloader.cxx 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,366 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <libmutil/MemObject.h>
+#include <libmnetutil/HttpDownloader.h>
+#include <libmnetutil/StreamSocket.h>
+
+#include <fstream>
+#include <sstream>
+
+#include <string>
+#include <vector>
+#include <map>
+#include <iostream>
+
+/**
+ * The buffer size is set to a constant value to simplify the implementation. A production version of this class cannot have this limitation.
+ */
+#define BUFFERSIZE 4096
+
+using namespace std;
+
+const char* HttpDownloader::getChars() {
+ int tries = 3;
+ while (tries) {
+ ostringstream body;
+ int fetchRes = fetch(buildRequestString("GET ", remoteFile), body);
+ if (fetchRes == HTTP_RESPONSECODE_MOVEDPERMANENTLY || respCode == HTTP_RESPONSECODE_MOVEDTEMPORARILY) {
+ url = getHeader("Location");
+ parseUrl();
+ if (!followRedirect) {
+ return "";
+ }
+ } else if (fetchRes == HTTP_RESPONSECODE_OK) {
+ return body.str().c_str();
+ } else {
+ return "";
+ }
+ tries--;
+ }
+ return "";
+}
+
+
+int HttpDownloader::getResponseCode() const {
+ return respCode;
+}
+
+void HttpDownloader::setFollowRedirects(bool const val) {
+ followRedirect = val;
+}
+
+bool HttpDownloader::getFollowRedirects() const {
+ return followRedirect;
+}
+
+int HttpDownloader::fetch(string request, ostream & bodyStream) {
+
+ cerr << "(FETCH)" << endl;
+
+ if (sock == NULL) {
+ // TODO: Error check for socket object
+ }
+
+ stringstream headerStream;
+ int fp = 0;
+ unsigned int bytesWritten = 0, bytesRead = 0;
+ struct sockaddr_in remoteAddr;
+ /*
+ This is what the hostent struct looks like:
+
+ struct hostent
+ {
+ char *h_name; // official name of host
+ char **h_aliases; // alias list
+ int h_addrtype; // host address type
+ int h_length; // length of address
+ char **h_addr_list; // list of addresses from name server
+ #define h_addr h_addr_list[0] // address, for backward compatiblity
+ };
+ */
+ struct hostent *remoteHost;
+
+ /* Buffer for holding data read from the network stream */
+ char buffer[BUFFERSIZE];
+ memset(buffer, 0, sizeof(buffer)); // Zero out the buffer used when recieving data
+
+ /* Create socket */
+ fp = socket(AF_INET, SOCK_STREAM, 0);
+ if (fp == -1) {
+ cerr << "Error: Could not create socket" << endl;
+ return false;
+ }
+ //memset(remoteAddr, 0, sizeof(remoteAddr)); // Zero the data structure containing information about the remote host
+
+ /* Fetch information about the remote host */
+ remoteHost = gethostbyname(remoteHostname.c_str()); // Use host name stored in class instance
+ if (remoteHost == NULL) {
+ cerr << "Error: Could not resolve host name" << endl;
+ return false;
+ }
+ remoteAddr.sin_family = AF_INET;
+ remoteAddr.sin_port = htons(remotePort); // Use port number stored in class instance
+
+ // Copy information about remote host's IP address from one structure to another (to the one used by "connect()")
+ bcopy((char *)remoteHost->h_addr, (char *)&remoteAddr.sin_addr.s_addr, sizeof(remoteHost->h_length));
+
+ /* Send request */
+ bytesWritten = sock->write(request.c_str(), request.length());
+ if (bytesWritten < 0) {
+ cerr << "Error: Could not send request" << endl;
+ return false;
+ } else if (bytesWritten < request.length()) {
+ return false;
+ }
+
+
+ /* Read response */
+ bool headerMode = true;
+ int headerParseResult = 0;
+ while ((bytesRead = sock->read(buffer, BUFFERSIZE)) > 0) {
+ if (headerMode) {
+ // Search for headers/body boundary in lastly fetched data
+ char* bodyStr = strstr(buffer, "\r\n\r\n");
+ int bodyLen = buffer + bytesRead - bodyStr;
+
+ if (bodyStr != NULL) {
+ // Found boundary
+ headerStream.write(buffer, bodyStr - buffer);
+ // Error checking!
+ if (headerStream.fail()) {
+ return 0;
+ }
+
+ bodyStream.write(bodyStr+4, bodyLen-4);
+ // Error checking!
+ if (bodyStream.fail()) {
+ return 0;
+ }
+
+ headerMode = false;
+
+ headerParseResult = parseHeaders(headerStream);
+ switch (headerParseResult) {
+ case HTTP_RESPONSECODE_OK:
+ break;
+ default:
+ close(fp);
+ return headerParseResult;
+ break;
+
+ }
+ } else {
+ headerStream.write(buffer, bytesRead);
+ // Error checking!
+ if (headerStream.fail()) {
+ return 0;
+ }
+ }
+ } else {
+ bodyStream.write(buffer, bytesRead);
+ // Error checking!
+ if (bodyStream.fail()) {
+ return 0;
+ }
+ }
+ }
+ if (internalSocketObject)
+ sock->close();
+
+ if (bytesRead < 0) {
+ cerr << "Error: Could not receive response" << endl;
+ return 0;
+ }
+
+ return HTTP_RESPONSECODE_OK;
+}
+
+void HttpDownloader::parseUrl() {
+ int pos = 0;
+ int lastPos = 0;
+ // Find protocol
+ if ((pos = url.find("://", 0)) != string::npos) {
+ remoteProtocol = url.substr(lastPos, pos - lastPos);
+ lastPos = pos + 3;
+ }
+ // Find host (and possibly file on remote host, e.g. "index.html")
+ if ((pos = url.find("/", lastPos)) != string::npos) {
+ // At least the root of the webserver should be fetched (e.g. "http://www.sunet.se/", but more likely "http://www.sunet.se/index.html")
+ remoteHostname = url.substr(lastPos, pos - lastPos);
+ lastPos = pos;
+ remoteFile = url.substr(lastPos);
+ } else {
+ //Only host part specified (e.g. "http://www.sunet.se")
+ remoteHostname = url.substr(lastPos);
+ }
+ // Find remote port
+ if ((pos = remoteHostname.find(":", 0)) != string::npos) {
+ remoteHostname = remoteHostname.substr(0, pos);
+ remotePort = atoi(remoteHostname.substr(pos + 1).c_str());
+ }
+}
+
+void HttpDownloader::split(string data, string token, vector<string> &res, int maxChars)
+{
+ int count = 0;
+ int lastpos = 0;
+ int tokenlen = token.length();
+ int pos = data.find(token,lastpos);
+ while(string::npos != pos && ((maxChars > 0 && pos < maxChars) || maxChars <= 0))
+ {
+ count = pos - lastpos;
+ res.push_back(data.substr(lastpos,count));
+ lastpos = pos + tokenlen;
+ pos = data.find(token,lastpos);
+ }
+ /**
+ * If the entire string is to be scanned then we want to add the last part of the string/data
+ * to the result list. This splitis not necessary is there is an upper limit when no more characters
+ * are of interest.
+ */
+ if (maxChars <= 0) {
+ res.push_back(data.substr(lastpos));
+ }
+}
+
+string HttpDownloader::trim(string s) {
+ int trimLeftPos = s.find_first_not_of(" \n\t\r");
+ int trimRightPos = s.find_last_not_of(" \n\t\r");
+ int pos = 0;
+ int len = 0;
+
+ if (trimLeftPos != string::npos)
+ pos = trimLeftPos;
+
+ if (trimRightPos != string::npos)
+ len = trimRightPos + 1 - pos;
+ else
+ len = s.length() - pos;
+
+ return s.substr(pos, len);
+}
+bool HttpDownloader::downloadHeaders() {
+ int tries = 3;
+ while (tries) {
+ ostringstream body;
+ int fetchRes = fetch(buildRequestString("HEAD ", remoteFile), body);
+ if (fetchRes == HTTP_RESPONSECODE_MOVEDPERMANENTLY || respCode == HTTP_RESPONSECODE_MOVEDTEMPORARILY) {
+ url = getHeader("Location");
+ parseUrl();
+ if (!followRedirect) {
+ return false;
+ }
+ } else if (fetchRes == HTTP_RESPONSECODE_OK) {
+ return true;
+ } else {
+ return false;
+ }
+ tries--;
+ }
+ return false;
+}
+
+string HttpDownloader::downloadToString() {
+
+ int tries = 3;
+ while (tries) {
+ ostringstream body;
+ int fetchRes = fetch(buildRequestString("GET ", remoteFile), body);
+ if (fetchRes == HTTP_RESPONSECODE_MOVEDPERMANENTLY || respCode == HTTP_RESPONSECODE_MOVEDTEMPORARILY) {
+ url = getHeader("Location");
+ parseUrl();
+ if (!followRedirect) {
+ return "";
+ }
+ } else if (fetchRes == HTTP_RESPONSECODE_OK) {
+ return body.str();
+ } else {
+ return "";
+ }
+ tries--;
+ }
+ return "";
+}
+bool HttpDownloader::downloadToFile(string filename) {
+
+ int tries = 3;
+ while (tries) {
+
+ ofstream file(filename.c_str(), ios_base::out | ios_base::trunc);
+ if (!file) {
+ return false;
+ }
+
+ int fetchRes = fetch(buildRequestString("GET ", remoteFile), file);
+ if (fetchRes == HTTP_RESPONSECODE_MOVEDPERMANENTLY || respCode == HTTP_RESPONSECODE_MOVEDTEMPORARILY) {
+ url = getHeader("Location");
+ parseUrl();
+ if (!followRedirect) {
+ return false;
+ }
+ } else if (fetchRes == HTTP_RESPONSECODE_OK) {
+ return !file.fail();
+ } else {
+ return false;
+ }
+ tries--;
+ }
+ return false;
+}
+
+int HttpDownloader::parseHeaders(stringstream & headers) {
+ vector<string> lines;
+ vector<string> initialLine;
+ string bodySep = HTTP_HEADER_CRLF;
+ bodySep += HTTP_HEADER_CRLF;
+
+ split(headers.str(), HTTP_HEADER_CRLF, lines);
+ split(lines[0], " ", initialLine);
+
+ respCode = atoi(initialLine[1].c_str());
+
+ for (int i=1; i<lines.size(); i++) {
+ parseHeader(lines.at(i));
+ }
+
+ return respCode;
+}
+
+void HttpDownloader::parseHeader(string line) {
+ int pos = line.find(':');
+ if (pos != string::npos) {
+ cout << "Found header: [" << line.substr(0, pos) << " = " << trim(line.substr(pos+1)) << "]" << endl;
+ headers[line.substr(0, pos)] = trim(line.substr(pos+1));
+ } else {
+ cerr << "ERROR: Header \"" << line << "\" is not valid!" << endl;
+ }
+}
+
+string HttpDownloader::getHeader(string header) {
+ map<string, string>::iterator iter = headers.find(header);
+ if (iter != headers.end()) {
+ return iter->second;
+ } else {
+ return "";
+ }
+}
+string HttpDownloader::buildRequestString(string method, string file) {
+ string res = method + " " + file + " " + HTTP_METHOD_1_0;
+ res.append(HTTP_HEADER_CRLF);
+
+ res.append(HTTP_HEADER_FROM);
+ res.append(": anonymous at minisip.org");
+ res.append(HTTP_HEADER_CRLF);
+
+ res.append(HTTP_HEADER_USERAGENT);
+ res.append(": Minisip-FileDownloader/0.1");
+ res.append(HTTP_HEADER_CRLF);
+
+ res.append(HTTP_HEADER_CRLF);
+ //res.append(HTTP_HEADER_CRLF);
+
+ return res;
+}
Added: trunk/libmnetutil/source/LdapConnection.cxx
===================================================================
--- trunk/libmnetutil/source/LdapConnection.cxx (rev 0)
+++ trunk/libmnetutil/source/LdapConnection.cxx 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,150 @@
+#include <libmnetutil/LdapConnection.h>
+
+LdapConnection::LdapConnection(std::string host, int port) : hostname(host), port(port), ld(NULL), isBound(false) {
+}
+LdapConnection::LdapConnection(std::string host) : hostname(host), port(LDAP_PORT), ld(NULL), isBound(false) {
+}
+LdapConnection::LdapConnection(std::string host, int port, MRef<LdapCredentials*> cred) : hostname(host), port(port), ld(NULL), isBound(false) {
+ setCredentials(cred);
+ try {
+ connect();
+ } catch (LdapException & e) {
+ //std::cerr << e.what() << std::endl;
+ }
+}
+LdapConnection::LdapConnection(std::string host, MRef<LdapCredentials*> cred) : hostname(host), port(LDAP_PORT), ld(NULL), isBound(false) {
+ setCredentials(cred);
+ try {
+ connect();
+ } catch (LdapException & e) {
+ //std::cerr << e.what() << std::endl;
+ }
+}
+LdapConnection::~LdapConnection() {
+ disconnect();
+}
+
+bool LdapConnection::isConnected(bool alsoCheckBind) {
+ if (NULL == ld)
+ return false;
+ if (alsoCheckBind && !isBound)
+ return false;
+ return true;
+}
+void LdapConnection::setCredentials(MRef<LdapCredentials*> cred) {
+ this->cred = cred;
+}
+MRef<LdapCredentials*> LdapConnection::getCredentials() {
+ return cred;
+}
+/**
+ * Some of this code has been copied from an unknown source.
+ */
+void LdapConnection::connect() throw (LdapException) {
+ int auth_method = LDAP_AUTH_SIMPLE;
+ int desired_version = LDAP_VERSION3;
+
+ if (isConnected()) {
+ disconnect();
+ }
+ if (cred.isNull()) {
+ throw LdapException("Could not connect since no credentials have been specified");
+ }
+
+ // Initialize LDAP library and open connection
+ if ((ld = ldap_init(hostname.c_str(), port)) == NULL ) {
+ throw LdapException("Could not connect to server");
+ }
+
+ // Set protocol version
+ if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) {
+ throw LdapException("Could not set connection options after setting up connection");
+ }
+
+ // Create LDAP bind
+ if (ldap_bind_s(ld, cred->username.c_str(), cred->password.c_str(), auth_method) != LDAP_SUCCESS) {
+ throw LdapException("Could not bind to connected server");
+ }
+
+ isBound = true;
+}
+
+bool LdapConnection::disconnect() {
+ if (isBound) {
+ ldap_unbind(ld);
+ }
+}
+
+/**
+ * Some of this code has been copied from an unknown source.
+ */
+std::vector<MRef<LdapEntry*> > LdapConnection::find(std::string baseDn, std::string query, std::vector<std::string> & attrs, int scope) throw (LdapNotConnectedException, LdapException) {
+ LDAPMessage* msg;
+ std::vector<MRef<LdapEntry*> > entries = std::vector<MRef<LdapEntry*> >();
+ char* searchAttrs[attrs.size()+1];
+ LDAPMessage* entry;
+ char* attr;
+ int i=0;
+
+ // Test if client is connected
+ if (!isConnected()) {
+ throw LdapNotConnectedException();
+ }
+
+ // Convert vector of C++ strings to array of C-style strings
+ for(i = 0; i < attrs.size(); i++ ) {
+ searchAttrs[i] = const_cast<char*>(attrs.at(i).c_str());
+ }
+
+ // OpenLDAP requires that the last entry is NULL (my guess is to avoid needing an additional "length variable")
+ searchAttrs[attrs.size()] = NULL;
+
+ // Send query (note that it is blocking!)
+ if (ldap_search_s(ld, baseDn.c_str(), scope, query.c_str(), searchAttrs, 0, &msg) != LDAP_SUCCESS)
+ {
+ // Return empty list
+ throw LdapException("LdapException: Could not execute query");
+ }
+
+
+ // Push each returned object (entry) onto the result vector
+ for( entry = ldap_first_entry(ld, msg);entry != NULL; entry = ldap_next_entry(ld,entry))
+ {
+ // Parse the returned entry directly (don't wait until the user actually "needs" it)
+ entries.push_back(MRef<LdapEntry*>(new LdapEntry(ld, entry)));
+
+ }
+
+ // Clear up some memory
+ ldap_msgfree(msg);
+
+ return std::vector<MRef<LdapEntry*> >(entries);
+}
+
+std::string LdapConnection::getBaseDn() throw (LdapNotConnectedException, LdapUnsupportedException) {
+
+ if (!isConnected()) {
+ throw LdapNotConnectedException();
+ }
+
+ std::vector<MRef<LdapEntry*> > entries;
+ std::vector<std::string> attrs;
+
+ attrs.push_back("namingContexts");
+ entries = find("", "(objectclass=*)", attrs, LDAP_SCOPE_BASE);
+
+ if (0 == entries.size()) {
+ throw LdapUnsupportedException("Retrieving base DN");
+ } else {
+ try {
+ return entries.at(0)->getAttrValueString("namingContexts");
+ } catch (LdapAttributeNotFoundException & e) {
+ throw LdapUnsupportedException("Retrieving base DN");
+ }
+ }
+}
+/*
+LDAP* LdapConnection::getLdapObject() {
+ return ld;
+}
+*/
Added: trunk/libmnetutil/source/LdapEntry.cxx
===================================================================
--- trunk/libmnetutil/source/LdapEntry.cxx (rev 0)
+++ trunk/libmnetutil/source/LdapEntry.cxx 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,94 @@
+#include <libmnetutil/LdapEntry.h>
+#include <libmutil/stringutils.h>
+
+LdapEntry::LdapEntry(LDAP* ld, LDAPMessage* entry) {
+ BerElement* ber;
+ struct berval** binaries;
+ char* attr;
+ char** strings;
+ int i=0;
+
+ valuesBinary.clear();
+ valuesStrings.clear();
+
+ for( attr = ldap_first_attribute(ld, entry, &ber); attr != NULL; attr = ldap_next_attribute(ld, entry, ber)) {
+
+ std::string attrName(attr);
+
+ // Separate binary attributes from the rest simply to testing what the returned attribute is called. Simple and effective.
+ if (stringEndsWith(attr, ";binary")) {
+ // Process binary attributes
+ if ((binaries = ldap_get_values_len(ld, entry, attr)) != NULL) {
+ for (i=0; binaries[i] != NULL; i++) {
+ valuesBinary[attrName].push_back(MRef<LdapEntryBinaryValue*>(new LdapEntryBinaryValue(binaries[i]->bv_val, binaries[i]->bv_len)));
+ }
+ ldap_value_free_len(binaries);
+ }
+ } else {
+ // Process string attributes
+ if ((strings = ldap_get_values(ld, entry, attr)) != NULL) {
+ for (i = 0; strings[i] != NULL; i++) {
+ valuesStrings[attrName].push_back(std::string(strings[i]));
+ }
+ ldap_value_free(strings);
+ }
+ }
+ ldap_memfree(attr);
+ }
+ if (ber != NULL) {
+ ber_free(ber,0);
+ }
+}
+
+bool LdapEntry::hasAttribute(std::string attr) {
+ std::map<std::string, std::vector<MRef<LdapEntryBinaryValue*> > >::iterator binaryIter = valuesBinary.find(attr);
+ std::map<std::string, std::vector<std::string> >::iterator stringIter = valuesStrings.find(attr);
+
+ if( binaryIter != valuesBinary.end() || stringIter != valuesStrings.end() ) {
+ return true;
+ }
+
+ return false;
+}
+
+std::string LdapEntry::getAttrValueString(std::string attr) throw (LdapAttributeNotFoundException) {
+ std::map<std::string, std::vector<std::string> >::iterator stringIter = valuesStrings.find(attr);
+
+ if (stringIter != valuesStrings.end()) {
+ return valuesStrings[attr].at(0);
+ }
+
+ throw LdapAttributeNotFoundException(attr);
+}
+std::vector<std::string> LdapEntry::getAttrValuesStrings(std::string attr) throw (LdapAttributeNotFoundException) {
+ std::map<std::string, std::vector<std::string> >::iterator i = valuesStrings.find(attr);
+
+ if (i != valuesStrings.end()) {
+ return valuesStrings[attr];
+ }
+
+ throw LdapAttributeNotFoundException(attr);
+}
+std::vector< MRef<LdapEntryBinaryValue*> > LdapEntry::getAttrValuesBinary(std::string attr) throw (LdapAttributeNotFoundException) {
+ std::map<std::string, std::vector<MRef<LdapEntryBinaryValue*> > >::iterator i = valuesBinary.find(attr);
+
+ if (i != valuesBinary.end()) {
+ return valuesBinary[attr];
+ }
+
+ throw LdapAttributeNotFoundException(attr);
+
+}
+std::vector<std::string> LdapEntry::getAttrNames() {
+ std::vector<std::string> res;
+ std::map<std::string, std::vector<std::string> >::iterator i;
+ std::map<std::string, std::vector<MRef<LdapEntryBinaryValue*> > >::iterator j;
+
+ for (i = valuesStrings.begin(); i != valuesStrings.end(); i++)
+ res.push_back(i->first);
+
+ for (j = valuesBinary.begin(); j != valuesBinary.end(); j++)
+ res.push_back(j->first);
+
+ return res;
+}
Added: trunk/libmnetutil/source/LdapException.cxx
===================================================================
--- trunk/libmnetutil/source/LdapException.cxx (rev 0)
+++ trunk/libmnetutil/source/LdapException.cxx 2007-06-12 08:48:39 UTC (rev 3303)
@@ -0,0 +1,29 @@
+#include <libmnetutil/LdapException.h>
+
+/**
+ * @author Mikael Svensson
+ * @author Erik Eliasson <eliasson at it.kth.se>
+ * @author Johan Bilien <jobi at via.ecp.fr>
+ */
+
+LdapException::LdapException() {
+ msg = "LdapException";
+};
+
+LdapException::LdapException(std::string msg) {
+ this->msg = "LdapException: " + msg;
+};
+
+const char* LdapException::what()const throw(){
+ return msg.c_str();
+}
+
+LdapAttributeNotFoundException::LdapAttributeNotFoundException(std::string message) {
+ msg = "LdapAttributeNotFoundException: Could not find attribute " + message;
+}
+LdapNotConnectedException::LdapNotConnectedException() {
+ msg = "LdapNotConnectedException: Not connected to server";
+}
+LdapUnsupportedException::LdapUnsupportedException(std::string feature) {
+ msg = "LdapUnsupportedException: Feature " + feature + " not supported";
+}
More information about the Minisip-devel
mailing list