gloox  1.0.1
prep.cpp
1 /*
2  Copyright (c) 2004-2012 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 #include "prep.h"
14 
15 #include "config.h"
16 
17 #ifdef HAVE_LIBIDN
18 # include <stringprep.h>
19 # include <idna.h>
20 #endif
21 
22 #include <cstdlib>
23 #include <string>
24 
25 #include <string.h>
26 
27 #define JID_PORTION_SIZE 1023
28 
29 namespace gloox
30 {
31 
32  namespace prep
33  {
34 
35 #ifdef HAVE_LIBIDN
36 
44  static bool prepare( const std::string& s, std::string& out, const Stringprep_profile* profile )
45  {
46  if( s.empty() || s.length() > JID_PORTION_SIZE )
47  return false;
48 
49  char* p = static_cast<char*>( calloc( JID_PORTION_SIZE, sizeof( char ) ) );
50  strncpy( p, s.c_str(), s.length() );
51  int rc = stringprep( p, JID_PORTION_SIZE, (Stringprep_profile_flags)0, profile );
52  if( rc == STRINGPREP_OK )
53  out = p;
54  free( p );
55  return rc == STRINGPREP_OK;
56  }
57 #endif
58 
59  bool nodeprep( const std::string& node, std::string& out )
60  {
61 #ifdef HAVE_LIBIDN
62  return prepare( node, out, stringprep_xmpp_nodeprep );
63 #else
64  if( node.length() > JID_PORTION_SIZE )
65  return false;
66  out = node;
67  return true;
68 #endif
69  }
70 
71  bool nameprep( const std::string& domain, std::string& out )
72  {
73 #ifdef HAVE_LIBIDN
74  return prepare( domain, out, stringprep_nameprep );
75 #else
76  if( domain.length() > JID_PORTION_SIZE )
77  return false;
78  out = domain;
79  return true;
80 #endif
81  }
82 
83  bool resourceprep( const std::string& resource, std::string& out )
84  {
85 #ifdef HAVE_LIBIDN
86  return prepare( resource, out, stringprep_xmpp_resourceprep );
87 #else
88  if( resource.length() > JID_PORTION_SIZE )
89  return false;
90  out = resource;
91  return true;
92 #endif
93  }
94 
95  bool idna( const std::string& domain, std::string& out )
96  {
97 #ifdef HAVE_LIBIDN
98  if( domain.empty() || domain.length() > JID_PORTION_SIZE )
99  return false;
100 
101  char* prepped;
102  int rc = idna_to_ascii_8z( domain.c_str(), &prepped, (Idna_flags)IDNA_USE_STD3_ASCII_RULES );
103  if( rc == IDNA_SUCCESS )
104  {
105  out = prepped;
106  return true;
107  }
108  if( rc != IDNA_MALLOC_ERROR )
109  free( prepped );
110  return false;
111 #else
112  if( domain.length() > JID_PORTION_SIZE )
113  return false;
114  out = domain;
115  return true;
116 #endif
117  }
118 
119  }
120 
121 }