fixed memleak in SQL config lookup
[strongswan.git] / src / charon / plugins / sql / sql_config.c
index eaa9da5..e7dfe57 100644 (file)
@@ -11,8 +11,6 @@
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  * for more details.
- *
- * $Id$
  */
 
 #include <string.h>
  */
 
 #include <string.h>
@@ -52,7 +50,7 @@ static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
                                                                                                  enumerator_t *e, bool *local)
 {
        int type, protocol, start_port, end_port;
                                                                                                  enumerator_t *e, bool *local)
 {
        int type, protocol, start_port, end_port;
-       char *start_addr, *end_addr;
+       chunk_t start_addr, end_addr;
        traffic_selector_t *ts;
        enum {
                TS_LOCAL = 0,
        traffic_selector_t *ts;
        enum {
                TS_LOCAL = 0,
@@ -71,14 +69,14 @@ static traffic_selector_t *build_traffic_selector(private_sql_config_t *this,
                                *local = TRUE;
                                /* FALL */
                        case TS_REMOTE:
                                *local = TRUE;
                                /* FALL */
                        case TS_REMOTE:
-                               ts = traffic_selector_create_from_string(protocol, type, 
-                                                               start_addr, start_port, end_addr, end_port);
+                               ts = traffic_selector_create_from_bytes(protocol, type,
+                                                               start_addr, start_port, end_addr, end_port);
                                break;
                        case TS_LOCAL_DYNAMIC:
                                *local = TRUE;
                                /* FALL */
                        case TS_REMOTE_DYNAMIC:
                                break;
                        case TS_LOCAL_DYNAMIC:
                                *local = TRUE;
                                /* FALL */
                        case TS_REMOTE_DYNAMIC:
-                               ts = traffic_selector_create_dynamic(protocol, type,
+                               ts = traffic_selector_create_dynamic(protocol,
                                                                start_port, end_port);
                                break;
                        default:
                                                                start_port, end_port);
                                break;
                        default:
@@ -109,7 +107,7 @@ static void add_traffic_selectors(private_sql_config_t *this,
                        "ON id = traffic_selector WHERE child_cfg = ?",
                        DB_INT, id,
                        DB_INT, DB_INT, DB_INT,
                        "ON id = traffic_selector WHERE child_cfg = ?",
                        DB_INT, id,
                        DB_INT, DB_INT, DB_INT,
-                       DB_TEXT, DB_TEXT, DB_INT, DB_INT);
+                       DB_BLOB, DB_BLOB, DB_INT, DB_INT);
        if (e)
        {
                while ((ts = build_traffic_selector(this, e, &local)))
        if (e)
        {
                while ((ts = build_traffic_selector(this, e, &local)))
@@ -125,15 +123,15 @@ static void add_traffic_selectors(private_sql_config_t *this,
  */
 static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
 {
  */
 static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
 {
-       int id, lifetime, rekeytime, jitter, hostaccess, mode;
+       int id, lifetime, rekeytime, jitter, hostaccess, mode, dpd, close, ipcomp;
        char *name, *updown;
        child_cfg_t *child_cfg;
        
        if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter, 
        char *name, *updown;
        child_cfg_t *child_cfg;
        
        if (e->enumerate(e, &id, &name, &lifetime, &rekeytime, &jitter, 
-                                               &updown, &hostaccess, &mode))
+                                               &updown, &hostaccess, &mode, &dpd, &close, &ipcomp))
        {
                child_cfg = child_cfg_create(name, lifetime, rekeytime, jitter,
        {
                child_cfg = child_cfg_create(name, lifetime, rekeytime, jitter,
-                                                                        updown, hostaccess, mode);
+                                                                        updown, hostaccess, mode, dpd, close, ipcomp);
                /* TODO: read proposal from db */
                child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
                add_traffic_selectors(this, child_cfg, id);
                /* TODO: read proposal from db */
                child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
                add_traffic_selectors(this, child_cfg, id);
@@ -152,12 +150,12 @@ static void add_child_cfgs(private_sql_config_t *this, peer_cfg_t *peer, int id)
        
        e = this->db->query(this->db,
                        "SELECT id, name, lifetime, rekeytime, jitter, "
        
        e = this->db->query(this->db,
                        "SELECT id, name, lifetime, rekeytime, jitter, "
-                       "updown, hostaccess, mode "
+                       "updown, hostaccess, mode, dpd_action, close_action, ipcomp "
                        "FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
                        "WHERE peer_cfg = ?",
                        DB_INT, id,
                        DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT,
                        "FROM child_configs JOIN peer_config_child_config ON id = child_cfg "
                        "WHERE peer_cfg = ?",
                        DB_INT, id,
                        DB_INT, DB_TEXT, DB_INT, DB_INT, DB_INT,
-                       DB_TEXT, DB_INT, DB_INT);
+                       DB_TEXT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
        if (e)
        {
                while ((child_cfg = build_child_cfg(this, e)))
        if (e)
        {
                while ((child_cfg = build_child_cfg(this, e)))
@@ -179,34 +177,9 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
        
        while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
        {
        
        while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
        {
-               host_t *me, *other;
                ike_cfg_t *ike_cfg;
                
                ike_cfg_t *ike_cfg;
                
-               me = host_create_from_string(local, 500);
-               if (!me)
-               {
-                       continue;
-               }
-               if (my_host && !me->is_anyaddr(me) &&
-                       !me->ip_equals(me, my_host))
-               {
-                       me->destroy(me);
-                       continue;
-               }
-               other = host_create_from_string(remote, 500);
-               if (!other)
-               {
-                       me->destroy(me);
-                       continue;
-               }
-               if (other_host && !other->is_anyaddr(other) &&
-                       !other->ip_equals(other, other_host))
-               {
-                       me->destroy(me);
-                       other->destroy(other);
-                       continue;
-               }
-               ike_cfg = ike_cfg_create(certreq, force_encap, me, other);
+               ike_cfg = ike_cfg_create(certreq, force_encap, local, remote);
                /* TODO: read proposal from db */
                ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
                return ike_cfg;
                /* TODO: read proposal from db */
                ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
                return ike_cfg;
@@ -244,18 +217,22 @@ static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
        peer_cfg_t *peer_cfg = NULL;
        
        e = this->db->query(this->db,
        peer_cfg_t *peer_cfg = NULL;
        
        e = this->db->query(this->db,
-                       "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
-                       "auth_method, eap_type, eap_vendor, keyingtries, "
-                       "rekeytime, reauthtime, jitter, overtime, mobike, "
-                       "dpd_delay, dpd_action, local_vip, remote_vip, "
-                       "mediation, mediated_by, peer_id "
-                       "FROM peer_configs WHERE id = ?",
+                       "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
+                       "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
+                       "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
+                       "dpd_delay, virtual, pool, "
+                       "mediation, mediated_by, COALESCE(p.type, 0), p.data "
+                       "FROM peer_configs AS c "
+                       "JOIN identities AS l ON local_id = l.id "
+                       "JOIN identities AS r ON remote_id = r.id "
+                       "LEFT JOIN identities AS p ON peer_id = p.id "
+                       "WHERE id = ?",
                        DB_INT, id,
                        DB_INT, id,
-                       DB_INT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
-                       DB_INT, DB_INT, DB_INT, DB_INT,
-                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
-                       DB_INT, DB_INT, DB_TEXT, DB_TEXT,
-                       DB_INT, DB_INT, DB_TEXT);
+                       DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
+                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, 
+                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, 
+                       DB_INT, DB_TEXT, DB_TEXT,
+                       DB_INT, DB_INT, DB_INT, DB_BLOB);
        if (e)
        {
                peer_cfg = build_peer_cfg(this, e, NULL, NULL);
        if (e)
        {
                peer_cfg = build_peer_cfg(this, e, NULL, NULL);
@@ -270,68 +247,76 @@ static peer_cfg_t *get_peer_cfg_by_id(private_sql_config_t *this, int id)
 static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
                                                                  identification_t *me, identification_t *other)
 {
 static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
                                                                  identification_t *me, identification_t *other)
 {
-       int id, ike_cfg, cert_policy, auth_method, eap_type, eap_vendor,
-               keyingtries, rekeytime, reauthtime, jitter, overtime, mobike,
-               dpd_delay, dpd_action, mediation, mediated_by;
-       char *local_id, *remote_id, *local_vip, *remote_vip, *peer_id, *name;
+       int id, ike_cfg, l_type, r_type,
+               cert_policy, uniqueid, auth_method, eap_type, eap_vendor, keyingtries,
+               rekeytime, reauthtime, jitter, overtime, mobike, dpd_delay,
+               mediation, mediated_by, p_type;
+       chunk_t l_data, r_data, p_data;
+       char *name, *virtual, *pool;
        
        
-       while (e->enumerate(e, &id, &name, &ike_cfg, &local_id, &remote_id, &cert_policy, 
-                                               &auth_method, &eap_type, &eap_vendor, &keyingtries, 
-                                               &rekeytime, &reauthtime, &jitter, &overtime, &mobike, 
-                                               &dpd_delay, &dpd_action, &local_vip, &remote_vip, 
-                                               &mediation, &mediated_by, &peer_id))
+       while (e->enumerate(e,
+                       &id, &name, &ike_cfg, &l_type, &l_data, &r_type, &r_data,
+                       &cert_policy, &uniqueid, &auth_method, &eap_type, &eap_vendor,
+                       &keyingtries, &rekeytime, &reauthtime, &jitter, &overtime, &mobike, 
+                       &dpd_delay,     &virtual, &pool,
+                       &mediation, &mediated_by, &p_type, &p_data))
        {
        {
-               ike_cfg_t *ike;
+               identification_t *local_id, *remote_id, *peer_id = NULL;
                peer_cfg_t *peer_cfg, *mediated_cfg;
                peer_cfg_t *peer_cfg, *mediated_cfg;
-               identification_t *my_id, *other_id, *peer;
-               host_t *my_vip, *other_vip;
+               ike_cfg_t *ike;
+               host_t *vip = NULL;
+               auth_cfg_t *auth;
                
                
-               my_id = identification_create_from_string(local_id);
-               if (!my_id)
+               local_id = identification_create_from_encoding(l_type, l_data);
+               remote_id = identification_create_from_encoding(r_type, r_data);
+               if ((me && !me->matches(me, local_id)) ||
+                       (other && !other->matches(other, remote_id)))
                {
                {
+                       local_id->destroy(local_id);
+                       remote_id->destroy(remote_id);
                        continue;
                }
                        continue;
                }
-               if (me && !me->matches(me, my_id))
-               {
-                       my_id->destroy(my_id);
-                       continue;
-               }
-               other_id = identification_create_from_string(remote_id);
-               if (!other_id)
+               ike = get_ike_cfg_by_id(this, ike_cfg);
+               mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by) : NULL;
+               if (p_type)
                {
                {
-                       my_id->destroy(my_id);
-                       continue;
+                       peer_id = identification_create_from_encoding(p_type, p_data);
                }
                }
-               if (other && !other->matches(other, other_id))
+               if (virtual)
                {
                {
-                       other_id->destroy(other_id);
-                       my_id->destroy(my_id);
-                       continue;
+                       vip = host_create_from_string(virtual, 0);
                }
                }
-               ike = get_ike_cfg_by_id(this, ike_cfg);
-               mediated_cfg = mediated_by ? get_peer_cfg_by_id(this, mediated_by) : NULL;
-               peer = peer_id ? identification_create_from_string(peer_id) : NULL;
-               my_vip = local_vip ? host_create_from_string(local_vip, 0) : NULL;
-               other_vip = remote_vip ? host_create_from_string(remote_vip, 0) : NULL;
-               
                if (ike)
                {
                        peer_cfg = peer_cfg_create(
                if (ike)
                {
                        peer_cfg = peer_cfg_create(
-                                                               name, 2, ike, my_id, other_id, cert_policy,
-                                                               auth_method, eap_type, eap_vendor, keyingtries, 
-                                                               rekeytime, reauthtime, jitter, overtime, mobike,
-                                                               dpd_delay, dpd_action, my_vip, other_vip,
-                                                               mediation, mediated_cfg, peer);
+                                       name, 2, ike, cert_policy, uniqueid,
+                                       keyingtries, rekeytime, reauthtime, jitter, overtime,
+                                       mobike, dpd_delay, vip, pool,
+                                       mediation, mediated_cfg, peer_id);
+                       auth = auth_cfg_create();
+                       auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method);
+                       auth->add(auth, AUTH_RULE_IDENTITY, local_id);
+                       peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+                       auth = auth_cfg_create();
+                       auth->add(auth, AUTH_RULE_IDENTITY, remote_id);
+                       if (eap_type)
+                       {
+                               auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+                               auth->add(auth, AUTH_RULE_EAP_TYPE, eap_type);
+                               if (eap_vendor)
+                               {
+                                       auth->add(auth, AUTH_RULE_EAP_VENDOR, eap_vendor);
+                               }
+                       }
+                       peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
                        add_child_cfgs(this, peer_cfg, id);
                        return peer_cfg;
                }
                DESTROY_IF(ike);
                DESTROY_IF(mediated_cfg);
                        add_child_cfgs(this, peer_cfg, id);
                        return peer_cfg;
                }
                DESTROY_IF(ike);
                DESTROY_IF(mediated_cfg);
-               DESTROY_IF(peer);
-               DESTROY_IF(my_vip);
-               DESTROY_IF(other_vip);
-               DESTROY_IF(my_id);
-               DESTROY_IF(other_id);
+               DESTROY_IF(peer_id);
+               DESTROY_IF(local_id);
+               DESTROY_IF(remote_id);
        }
        return NULL;
 }
        }
        return NULL;
 }
@@ -345,18 +330,22 @@ static peer_cfg_t *get_peer_cfg_by_name(private_sql_config_t *this, char *name)
        peer_cfg_t *peer_cfg = NULL;
        
        e = this->db->query(this->db,
        peer_cfg_t *peer_cfg = NULL;
        
        e = this->db->query(this->db,
-                       "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
-                       "auth_method, eap_type, eap_vendor, keyingtries, "
-                       "rekeytime, reauthtime, jitter, overtime, mobike, "
-                       "dpd_delay, dpd_action, local_vip, remote_vip, "
-                       "mediation, mediated_by, peer_id "
-                       "FROM peer_configs WHERE ike_version = ? AND name = ?",
+                       "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
+                       "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
+                       "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
+                       "dpd_delay, virtual, pool, "
+                       "mediation, mediated_by, COALESCE(p.type, 0), p.data "
+                       "FROM peer_configs AS c "
+                       "JOIN identities AS l ON local_id = l.id "
+                       "JOIN identities AS r ON remote_id = r.id "
+                       "LEFT JOIN identities AS p ON peer_id = p.id "
+                       "WHERE ike_version = ? AND name = ?",
                        DB_INT, 2, DB_TEXT, name,
                        DB_INT, 2, DB_TEXT, name,
-                       DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
-                       DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
-                       DB_INT, DB_INT, DB_TEXT, DB_TEXT,
-                       DB_INT, DB_INT, DB_TEXT);
+                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_TEXT, DB_TEXT,
+                       DB_INT, DB_INT, DB_INT, DB_BLOB);
        if (e)
        {
                peer_cfg = build_peer_cfg(this, e, NULL, NULL);
        if (e)
        {
                peer_cfg = build_peer_cfg(this, e, NULL, NULL);
@@ -491,18 +480,22 @@ static enumerator_t* create_peer_cfg_enumerator(private_sql_config_t *this,
 
        /* TODO: only get configs whose IDs match exactly or contain wildcards */
        e->inner = this->db->query(this->db,
 
        /* TODO: only get configs whose IDs match exactly or contain wildcards */
        e->inner = this->db->query(this->db,
-                       "SELECT id, name, ike_cfg, local_id, remote_id, cert_policy, "
-                       "auth_method, eap_type, eap_vendor, keyingtries, "
-                       "rekeytime, reauthtime, jitter, overtime, mobike, "
-                       "dpd_delay, dpd_action, local_vip, remote_vip, "
-                       "mediation, mediated_by, peer_id "
-                       "FROM peer_configs WHERE ike_version = ? ",
+                       "SELECT c.id, name, ike_cfg, l.type, l.data, r.type, r.data, "
+                       "cert_policy, uniqueid, auth_method, eap_type, eap_vendor, "
+                       "keyingtries, rekeytime, reauthtime, jitter, overtime, mobike, "
+                       "dpd_delay, virtual, pool, "
+                       "mediation, mediated_by, COALESCE(p.type, 0), p.data "
+                       "FROM peer_configs AS c "
+                       "JOIN identities AS l ON local_id = l.id "
+                       "JOIN identities AS r ON remote_id = r.id "
+                       "LEFT JOIN identities AS p ON peer_id = p.id "
+                       "WHERE ike_version = ?",
                        DB_INT, 2,
                        DB_INT, 2,
-                       DB_INT, DB_TEXT, DB_INT, DB_TEXT, DB_TEXT, DB_INT,
-                       DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_TEXT, DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB,
                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
                        DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
-                       DB_INT, DB_INT, DB_TEXT, DB_TEXT,
-                       DB_INT, DB_INT, DB_TEXT);
+                       DB_INT, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT,
+                       DB_INT, DB_TEXT, DB_TEXT,
+                       DB_INT, DB_INT, DB_INT, DB_BLOB);
        if (!e->inner)
        {
                free(e);
        if (!e->inner)
        {
                free(e);