1// OpenLDAP: pkg/ldap/contrib/ldapc++/src/TlsOptions.cpp,v 1.5.2.2 2010/04/14 23:50:44 quanah Exp
2/*
3 * Copyright 2010, OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5 */
6
7#include "TlsOptions.h"
8#include "LDAPException.h"
9
10enum opttype {
11    INT=0,
12    STRING,
13    OTHER
14};
15
16typedef struct tls_optmap {
17    int optval;
18    opttype type;
19} tls_optmap_t;
20
21static tls_optmap_t optmap[] = {
22    { LDAP_OPT_X_TLS_CACERTFILE, STRING },
23    { LDAP_OPT_X_TLS_CACERTDIR, STRING },
24    { LDAP_OPT_X_TLS_CERTFILE, STRING },
25    { LDAP_OPT_X_TLS_KEYFILE, STRING },
26    { LDAP_OPT_X_TLS_REQUIRE_CERT, INT },
27    { LDAP_OPT_X_TLS_PROTOCOL_MIN, INT },
28    { LDAP_OPT_X_TLS_CIPHER_SUITE, STRING },
29    { LDAP_OPT_X_TLS_RANDOM_FILE, STRING },
30    { LDAP_OPT_X_TLS_CRLCHECK, INT },
31    { LDAP_OPT_X_TLS_DHFILE, STRING },
32    { LDAP_OPT_X_TLS_NEWCTX, INT }
33};
34#if 0 /* not implemented currently */
35        static const int TLS_CRLFILE /* GNUtls only */
36        static const int TLS_SSL_CTX  /* OpenSSL SSL* */
37        static const int TLS_CONNECT_CB
38        static const int TLS_CONNECT_ARG
39#endif
40
41static void checkOpt( TlsOptions::tls_option opt, opttype type ) {
42    if ( opt < TlsOptions::CACERTFILE || opt >= TlsOptions::LASTOPT ){
43        throw( LDAPException( LDAP_PARAM_ERROR, "unknown Option" ) );
44    }
45
46    if ( optmap[opt].type != type ){
47        throw( LDAPException( LDAP_PARAM_ERROR, "not a string option" ) );
48    }
49}
50
51TlsOptions::TlsOptions() : m_ld(NULL) {}
52
53TlsOptions::TlsOptions( LDAP* ld ): m_ld(ld) { }
54
55void TlsOptions::setOption( tls_option opt, const std::string& value ) const {
56    checkOpt(opt, STRING);
57    this->setOption( opt, value.empty() ? NULL : (void*) value.c_str() );
58}
59
60void TlsOptions::setOption( tls_option opt, int value ) const {
61    checkOpt(opt, INT);
62    this->setOption( opt, (void*) &value);
63}
64
65void TlsOptions::setOption( tls_option opt, void *value ) const {
66    int ret = ldap_set_option( m_ld, optmap[opt].optval, value);
67    if ( ret != LDAP_OPT_SUCCESS )
68    {
69        if ( ret != LDAP_OPT_ERROR ){
70            throw( LDAPException( ret ));
71        } else {
72            throw( LDAPException( LDAP_PARAM_ERROR, "error while setting TLS option" ) );
73        }
74    }
75    if ( m_ld ){
76        this->newCtx();
77    }
78}
79
80void TlsOptions::getOption( tls_option opt, void* value ) const {
81    int ret = ldap_get_option( m_ld, optmap[opt].optval, value);
82    if ( ret != LDAP_OPT_SUCCESS )
83    {
84        if ( ret != LDAP_OPT_ERROR ){
85            throw( LDAPException( ret ));
86        } else {
87            throw( LDAPException( LDAP_PARAM_ERROR, "error while reading TLS option" ) );
88        }
89    }
90}
91
92int TlsOptions::getIntOption( tls_option opt ) const {
93    int value;
94    checkOpt(opt, INT);
95    ldap_get_option( m_ld, optmap[opt].optval, (void*) &value);
96    return value;
97}
98
99std::string TlsOptions::getStringOption( tls_option opt ) const {
100    char *value;
101    checkOpt(opt, STRING);
102    ldap_get_option( m_ld, optmap[opt].optval, (void*) &value);
103    std::string strval;
104    if (value)
105    {
106        strval=std::string(value);
107        ldap_memfree(value);
108    }
109    return strval;
110}
111
112void TlsOptions::newCtx() const {
113    int ret = ldap_set_option( m_ld, LDAP_OPT_X_TLS_NEWCTX, LDAP_OPT_ON);
114    if ( ret != LDAP_OPT_SUCCESS )
115    {
116        if ( ret != LDAP_OPT_ERROR ){
117            throw( LDAPException( ret ));
118        } else {
119            throw( LDAPException( LDAP_LOCAL_ERROR, "error while renewing TLS context" ) );
120        }
121    }
122}
123