prep.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "prep.h"
00014
00015 #include "config.h"
00016
00017 #ifdef HAVE_LIBIDN
00018 # include <stringprep.h>
00019 # include <idna.h>
00020 #endif
00021
00022 #include <cstdlib>
00023 #include <string>
00024
00025 #include <string.h>
00026
00027 #define JID_PORTION_SIZE 1023
00028
00029 namespace gloox
00030 {
00031
00032 namespace prep
00033 {
00034
00035 #ifdef HAVE_LIBIDN
00036
00044 static bool prepare( const std::string& s, std::string& out, const Stringprep_profile* profile )
00045 {
00046 if( s.empty() || s.length() > JID_PORTION_SIZE )
00047 return false;
00048
00049 char* p = static_cast<char*>( calloc( JID_PORTION_SIZE, sizeof( char ) ) );
00050 strncpy( p, s.c_str(), s.length() );
00051 int rc = stringprep( p, JID_PORTION_SIZE, (Stringprep_profile_flags)0, profile );
00052 if( rc == STRINGPREP_OK )
00053 out = p;
00054 free( p );
00055 return rc == STRINGPREP_OK;
00056 }
00057 #endif
00058
00059 bool nodeprep( const std::string& node, std::string& out )
00060 {
00061 #ifdef HAVE_LIBIDN
00062 return prepare( node, out, stringprep_xmpp_nodeprep );
00063 #else
00064 if( node.length() > JID_PORTION_SIZE )
00065 return false;
00066 out = node;
00067 return true;
00068 #endif
00069 }
00070
00071 bool nameprep( const std::string& domain, std::string& out )
00072 {
00073 #ifdef HAVE_LIBIDN
00074 return prepare( domain, out, stringprep_nameprep );
00075 #else
00076 if( domain.length() > JID_PORTION_SIZE )
00077 return false;
00078 out = domain;
00079 return true;
00080 #endif
00081 }
00082
00083 bool resourceprep( const std::string& resource, std::string& out )
00084 {
00085 #ifdef HAVE_LIBIDN
00086 return prepare( resource, out, stringprep_xmpp_resourceprep );
00087 #else
00088 if( resource.length() > JID_PORTION_SIZE )
00089 return false;
00090 out = resource;
00091 return true;
00092 #endif
00093 }
00094
00095 bool idna( const std::string& domain, std::string& out )
00096 {
00097 #ifdef HAVE_LIBIDN
00098 if( domain.empty() || domain.length() > JID_PORTION_SIZE )
00099 return false;
00100
00101 char* prepped;
00102 int rc = idna_to_ascii_8z( domain.c_str(), &prepped, (Idna_flags)IDNA_USE_STD3_ASCII_RULES );
00103 if( rc == IDNA_SUCCESS )
00104 {
00105 out = prepped;
00106 return true;
00107 }
00108 if( rc != IDNA_MALLOC_ERROR )
00109 free( prepped );
00110 return false;
00111 #else
00112 if( domain.length() > JID_PORTION_SIZE )
00113 return false;
00114 out = domain;
00115 return true;
00116 #endif
00117 }
00118
00119 }
00120
00121 }