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