diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/conf.c | 255 | ||||
| -rw-r--r-- | lib/confutil.c | 146 | ||||
| -rw-r--r-- | lib/event.c | 3 | ||||
| -rw-r--r-- | lib/include/radsec/radsec-impl.h | 17 | ||||
| -rw-r--r-- | lib/include/radsec/radsec.h | 3 | ||||
| -rw-r--r-- | lib/radsec.c | 2 | ||||
| -rw-r--r-- | lib/radsec.sym | 1 | ||||
| -rw-r--r-- | lib/tls.c | 23 | 
8 files changed, 341 insertions, 109 deletions
| @@ -1,4 +1,4 @@ -/* Copyright 2010, 2011 NORDUnet A/S. All rights reserved. +/* Copyright 2010, 2011, 2013 NORDUnet A/S. All rights reserved.     See LICENSE for licensing information.  */  #if defined HAVE_CONFIG_H @@ -15,49 +15,190 @@  #include "util.h"  #include "debug.h" -#if 0 -  # common config options - -  # common realm config options +#if 0 /* Configuration file syntax. */ +  # realm specific configuration    realm STRING {        type = "UDP"|"TCP"|"TLS"|"DTLS"        timeout = INT        retries = INT +  } + +  # realm configuration inherited by clients and servers +  realm STRING {        cacertfile = STRING        #cacertpath = STRING        certfile = STRING        certkeyfile = STRING -      pskstr = STRING	# Transport pre-shared key, UTF-8 form. +      pskstr = STRING	 # Transport pre-shared key, UTF-8 form.        pskhexstr = STRING # Transport pre-shared key, ASCII hex form.        pskid = STRING        pskex = "PSK"|"DHE_PSK"|"RSA_PSK"    } -  # client specific realm config options +  # client configuration    realm STRING {        server {            hostname = STRING -	  service = STRING +	  service = STRING      # name or port number +          secret = STRING       # RADIUS secret +      } +  } + +  # server configuration +  realm STRING { +      client { +          hostname = STRING +	  service = STRING      # name or port number            secret = STRING       # RADIUS secret        }    }  #endif +struct confcommon { +  struct rs_credentials *transport_cred; +  char *cacertfile; +  char *cacertpath; +  char *certfile; +  char *certkeyfile; +  char *pskstr; +  char *pskhexstr; +}; + +#define CONFGET_STR(dst,cfg,key,def) do {  \ +        (dst) = cfg_getstr ((cfg), (key)); \ +        if ((dst) == NULL) (dst) = (def);  \ +      } while (0) +#define CONFGET_INT(dst,cfg,key,def) do {  \ +        (dst) = cfg_getint ((cfg), (key)); \ +        if ((dst) == -1) (dst) = (def);    \ +      } while (0) + +static int +confload_peers (struct rs_context *ctx, +                /*const*/ cfg_t *cfg_realm, +                enum rs_peer_type type, +                struct rs_realm *r) +{ +  const char *peer_type_str[] = {"<no type>", "client", "server"}; +  cfg_t *cfg_peer = NULL; +  int j; +  char *def_cacertfile = cfg_getstr (cfg_realm, "cacertfile"); +  /*char *def_cacertpath = cfg_getstr (cfg_realm, "cacertpath");*/ +  char *def_certfile = cfg_getstr (cfg_realm, "certfile"); +  char *def_certkeyfile = cfg_getstr (cfg_realm, "certkeyfile"); +  char *def_pskstr = cfg_getstr (cfg_realm, "pskstr"); +  char *def_pskhexstr = cfg_getstr (cfg_realm, "pskhexstr"); + +  for (j = 0; j < cfg_size (cfg_realm, peer_type_str[type]); j++) +    { +      char *pskstr = NULL; +      char *pskhexstr = NULL; +      struct rs_peer *p = peer_create (ctx, &r->peers); +      if (p == NULL) +        return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, +                                   NULL); +      p->type = type; +      p->realm = r; + +      cfg_peer = cfg_getnsec (cfg_realm, peer_type_str[type], j); +      p->hostname = cfg_getstr (cfg_peer, "hostname"); +      p->service = cfg_getstr (cfg_peer, "service"); +      p->secret = cfg_getstr (cfg_peer, "secret"); + +      CONFGET_STR (p->cacertfile, cfg_peer, "cacertfile", def_cacertfile); +      CONFGET_STR (p->certfile, cfg_peer, "certfile", def_certfile); +      CONFGET_STR (p->certkeyfile, cfg_peer, "certkeyfile", def_certkeyfile); +      CONFGET_STR (pskstr, cfg_peer, "pskstr", def_pskstr); +      CONFGET_STR (pskhexstr, cfg_peer, "pskhexstr", def_pskhexstr); + +      if (pskstr || pskhexstr) +        { +#if defined RS_ENABLE_TLS_PSK +          char *def_pskex = cfg_getstr (cfg_realm, "pskex"); +          char *tmp_pskex = NULL; +          rs_cred_type_t type = RS_CRED_NONE; +          struct rs_credentials *cred = NULL; + +          CONFGET_STR (tmp_pskex, cfg_peer, "pskex", def_pskex); +          if (!strcmp (tmp_pskex, "PSK")) +            type = RS_CRED_TLS_PSK; +          else +            { +              /* TODO: push a warning on the error stack:*/ +              /*rs_err_ctx_push (ctx, RSE_WARN, "%s: unsupported PSK key exchange" +                               " algorithm -- PSK not used", kex);*/ +            } + +          if (type != RS_CRED_NONE) +            { +              char *def_pskid = cfg_getstr (cfg_realm, "pskid"); +              cred = rs_calloc (ctx, 1, sizeof (*cred)); +              if (cred == NULL) +                return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, +                                           NULL); +              cred->type = type; +              CONFGET_STR (cred->identity, cfg_peer, "pskid", def_pskid); +              if (pskhexstr) +                { +                  cred->secret_encoding = RS_KEY_ENCODING_ASCII_HEX; +                  cred->secret = pskhexstr; +                  if (pskstr) +                    ;      /* TODO: warn that we're ignoring pskstr */ +                } +              else +                { +                  cred->secret_encoding = RS_KEY_ENCODING_UTF8; +                  cred->secret = pskstr; +                } + +              p->transport_cred = cred; +            } +#else  /* !RS_ENABLE_TLS_PSK */ +          /* TODO: push a warning on the error stack: */ +          /* rs_err_ctx_push (ctx, RSE_WARN, "libradsec wasn't configured with " +             "support for TLS preshared keys, ignoring pskstr " +             "and pskhexstr");*/ +#endif  /* RS_ENABLE_TLS_PSK */ +        } + + +      /* For a TLS or DTLS client or server, validate that we have either of CA +         cert file/path or PSK.  */ +      if ((r->type == RS_CONN_TYPE_TLS || r->type == RS_CONN_TYPE_DTLS) +          && (p->cacertfile == NULL && p->cacertpath == NULL) +          && p->transport_cred == NULL) +        return rs_err_ctx_push (ctx, RSE_CONFIG, +                                "%s: missing both CA file/path and PSK", +                                r->name); +    } + +  return RSE_OK; +} +  /* FIXME: Leaking memory in error cases.  */  int  rs_context_read_config(struct rs_context *ctx, const char *config_file)  { -  cfg_t *cfg, *cfg_realm, *cfg_server; +  cfg_t *cfg, *cfg_realm;    int err = 0; -  int i, j; +  int i;    const char *s;    struct rs_config *config = NULL; -  cfg_opt_t server_opts[] = +  cfg_opt_t peer_opts[] =      {        CFG_STR ("hostname", NULL, CFGF_NONE),        CFG_STR ("service", "2083", CFGF_NONE),        CFG_STR ("secret", "radsec", CFGF_NONE), +      CFG_STR ("cacertfile", NULL, CFGF_NONE), +      /*CFG_STR ("cacertpath", NULL, CFGF_NONE),*/ +      CFG_STR ("certfile", NULL, CFGF_NONE), +      CFG_STR ("certkeyfile", NULL, CFGF_NONE), +      CFG_STR ("pskstr", NULL, CFGF_NONE), +      CFG_STR ("pskhexstr", NULL, CFGF_NONE), +      CFG_STR ("pskid", NULL, CFGF_NONE), +      CFG_STR ("pskex", "PSK", CFGF_NONE), +        CFG_END ()      };    cfg_opt_t realm_opts[] = @@ -73,7 +214,8 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)        CFG_STR ("pskhexstr", NULL, CFGF_NONE),        CFG_STR ("pskid", NULL, CFGF_NONE),        CFG_STR ("pskex", "PSK", CFGF_NONE), -      CFG_SEC ("server", server_opts, CFGF_MULTI), +      CFG_SEC ("server", peer_opts, CFGF_MULTI), +      CFG_SEC ("client", peer_opts, CFGF_MULTI),        CFG_END ()      };    cfg_opt_t opts[] = @@ -111,8 +253,9 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)      {        struct rs_realm *r = NULL;        const char *typestr; -      char *pskstr = NULL, *pskhexstr = NULL; +      struct confcommon cc; +      memset (&cc, 0, sizeof(cc));        r = rs_calloc (ctx, 1, sizeof(*r));        if (r == NULL)  	return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, NULL); @@ -148,87 +291,17 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)  	return rs_err_ctx_push (ctx, RSE_CONFIG,                                  "%s: invalid connection type: %s",                                  r->name, typestr); +        r->timeout = cfg_getint (cfg_realm, "timeout");        r->retries = cfg_getint (cfg_realm, "retries"); -      r->cacertfile = cfg_getstr (cfg_realm, "cacertfile"); -      /*r->cacertpath = cfg_getstr (cfg_realm, "cacertpath");*/ -      r->certfile = cfg_getstr (cfg_realm, "certfile"); -      r->certkeyfile = cfg_getstr (cfg_realm, "certkeyfile"); - -      pskstr = cfg_getstr (cfg_realm, "pskstr"); -      pskhexstr = cfg_getstr (cfg_realm, "pskhexstr"); -      if (pskstr || pskhexstr) -        { -#if defined RS_ENABLE_TLS_PSK -          char *kex = cfg_getstr (cfg_realm, "pskex"); -          rs_cred_type_t type = RS_CRED_NONE; -          struct rs_credentials *cred = NULL; -          assert (kex != NULL); - -          if (!strcmp (kex, "PSK")) -            type = RS_CRED_TLS_PSK; -          else -            { -              /* TODO: push a warning on the error stack:*/ -              /*rs_err_ctx_push (ctx, RSE_WARN, "%s: unsupported PSK key exchange" -                               " algorithm -- PSK not used", kex);*/ -            } - -          if (type != RS_CRED_NONE) -            { -              cred = rs_calloc (ctx, 1, sizeof (*cred)); -              if (cred == NULL) -                return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, -                                           NULL); -              cred->type = type; -              cred->identity = cfg_getstr (cfg_realm, "pskid"); -              if (pskhexstr) -                { -                  cred->secret_encoding = RS_KEY_ENCODING_ASCII_HEX; -                  cred->secret = pskhexstr; -                  if (pskstr) -                    ;      /* TODO: warn that we're ignoring pskstr */ -                } -              else -                { -                  cred->secret_encoding = RS_KEY_ENCODING_UTF8; -                  cred->secret = pskstr; -                } - -              r->transport_cred = cred; -            } -#else  /* !RS_ENABLE_TLS_PSK */ -          /* TODO: push a warning on the error stack: */ -          /* rs_err_ctx_push (ctx, RSE_WARN, "libradsec wasn't configured with " -                           "support for TLS preshared keys, ignoring pskstr " -                           "and pskhexstr");*/ -#endif  /* RS_ENABLE_TLS_PSK */ -        } - -      /* For TLS and DTLS realms, validate that we either have (i) CA -         cert file or path or (ii) PSK.  */ -      if ((r->type == RS_CONN_TYPE_TLS || r->type == RS_CONN_TYPE_DTLS) -          && (r->cacertfile == NULL && r->cacertpath == NULL) -          && r->transport_cred == NULL) -        return rs_err_ctx_push (ctx, RSE_CONFIG, -                                "%s: missing both CA file/path and PSK", -                                r->name); - -      /* Add peers, one per server stanza.  */ -      for (j = 0; j < cfg_size (cfg_realm, "server"); j++) -	{ -	  struct rs_peer *p = peer_create (ctx, &r->peers); -	  if (p == NULL) -	    return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__, -				       NULL); -	  p->realm = r; - -	  cfg_server = cfg_getnsec (cfg_realm, "server", j); -	  p->hostname = cfg_getstr (cfg_server, "hostname"); -          p->service = cfg_getstr (cfg_server, "service"); -	  p->secret = cfg_getstr (cfg_server, "secret"); -	} +      /* Add client and server peers. */ +      err = confload_peers (ctx, cfg_realm, RS_PEER_TYPE_CLIENT, r); +      if (err) +        return err; +      err = confload_peers (ctx, cfg_realm, RS_PEER_TYPE_SERVER, r); +      if (err) +        return err;      }    /* Save config object in context, for freeing in rs_context_destroy().  */ diff --git a/lib/confutil.c b/lib/confutil.c new file mode 100644 index 0000000..3a1d639 --- /dev/null +++ b/lib/confutil.c @@ -0,0 +1,146 @@ +/* Copyright 2013 NORDUnet A/S. All rights reserved. +   See LICENSE for licensing information.  */ + +#if defined HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +#include <radsec/radsec.h> +#include <radsec/radsec-impl.h> + +#if 0 +/* This code triggers the memory-stomping-detector of electric fence */ + +#define MEMCHUNK 30 + +static int +print_to_buf (const struct rs_context *ctx, +              char **buf_ptr, ssize_t *i_ptr, ssize_t *len_ptr, +              const char *fmt, ...) +{ +  char *buf = *buf_ptr; +  ssize_t i = *i_ptr; +  ssize_t len = *len_ptr; + +  va_list args; +  for (;;) +    { +      int n; +      va_start (args, fmt); +      fprintf (stdout, "sprintf (%p + %ld, %ld, \"%s\") -->", +               buf, i, len, buf); +      fflush (stdout); +      n = vsnprintf (buf + i, len - i, fmt, args); +      fprintf (stdout, "%d\n", n); +      va_end (args); +      if (n < 0) +        return -RSE_INTERNAL; +      if (n >= len - i) +        { +          int newlen = len + MEMCHUNK; +          buf = rs_realloc (ctx, buf, newlen); +          if (buf == NULL) +            return -RSE_NOMEM; +          len = newlen; +          continue; +        } +      len -= n; +      i += n; + +      *buf_ptr = buf; +      *i_ptr = i; +      *len_ptr = len; +      return RSE_OK; +    } +} +#endif  /* 0 */ + +static int +pp (char **out, size_t *len, const char *fmt, ...) +{ +  int n; +  va_list args; +  va_start (args, fmt); +  n = vsnprintf (*out, *len, fmt, args); +  va_end (args); +  if (n == -1 || n >= *len) +    return -RSE_INTERNAL; +  *out += n; +  *len -= n; +  return RSE_OK; +} + +int +rs_context_print_config (struct rs_context *ctx, char **buf_out) +{ +  char *buf = rs_malloc (ctx, 8192); +  char *out = NULL; +  size_t len = 8192; +  struct rs_config *cfg = ctx->config; +  struct rs_realm *r = NULL; +  struct rs_peer *p = NULL; +  char *peer_type[] = {"<no type>", "client", "server"}; +  char *realm_type[] = {"<no type>", "UDP", "TCP", "TLS", "DTLS"}; +  char *cred_type[] = {"<no type>", "PSK", "DHE_PSK", "RSA_PSK"}; + +  out = buf; +  assert (out); +  assert (cfg); + +  for (r = cfg->realms; r != NULL; r = r->next) +    { +      if (pp (&out, &len, "realm %s {\n", r->name) +          || pp (&out, &len, "\ttype = \"%s\"\n\ttimeout = %d\n\tretries = %d\n", +                 realm_type[r->type], +                 r->timeout, +                 r->retries)) +        return -RSE_INTERNAL; +      for (p = r->peers; p != NULL; p = p->next) +        { +          if (pp (&out, &len, +                  "\t%s {\n" +                  "\t\thostname = \"%s\"\n" +                  "\t\tservice = \"%s\"\n" +                  "\t\tsecret = \"%s\"\n", +                  peer_type[p->type], +                  p->hostname, +                  p->service, +                  p->secret)) +            return -RSE_INTERNAL; +          if (p->cacertfile) +            if (pp (&out, &len, "\t\tcacertfile = \"%s\"\n", p->cacertfile)) +              return -RSE_INTERNAL; +          if (p->certfile) +            if (pp (&out, &len, "\t\tcertfile = \"%s\"\n", p->certfile)) +              return -RSE_INTERNAL; +          if (p->certkeyfile) +            if (pp (&out, &len, "\t\tcertkeyfile = \"%s\"\n", p->certkeyfile)) +              return -RSE_INTERNAL; +          if (p->transport_cred) +            { +              if (pp (&out, &len, "\t\tpskex = \"%s\"\n", +                      cred_type[p->transport_cred->type]) +                  || pp (&out, &len, "\t\tpskid = \"%s\"\n", +                         p->transport_cred->identity) +                  || pp (&out, &len, +                         "\t\t%s = \"%s\"\n", (p->transport_cred->secret_encoding +                                               == RS_KEY_ENCODING_ASCII_HEX +                                               ? "pskhexstr" : "pskstr"), +                         p->transport_cred->secret)) +                return -RSE_INTERNAL; +            } +          if (pp (&out, &len, "\t}\n")) +            return -RSE_INTERNAL; +        } +      if (pp (&out, &len, "}\n")) +        return -RSE_INTERNAL; +    } + +  if (buf_out) +    *buf_out = buf; +  return RSE_OK; +} diff --git a/lib/event.c b/lib/event.c index 138fa72..6b7ba48 100644 --- a/lib/event.c +++ b/lib/event.c @@ -244,11 +244,12 @@ int  event_on_connect (struct rs_connection *conn, struct rs_message *msg)  {    assert (!conn->is_connecting); +  assert (conn->active_peer);  #if defined (RS_ENABLE_TLS)    if ((conn->realm->type == RS_CONN_TYPE_TLS         || conn->realm->type == RS_CONN_TYPE_DTLS) -      && conn->realm->transport_cred->type != RS_CRED_TLS_PSK) +      && conn->active_peer->transport_cred->type != RS_CRED_TLS_PSK)      if (tls_verify_cert (conn) != RSE_OK)        {          rs_debug (("%s: server cert verification failed\n", __func__)); diff --git a/lib/include/radsec/radsec-impl.h b/lib/include/radsec/radsec-impl.h index 9f8ebbb..ef01d70 100644 --- a/lib/include/radsec/radsec-impl.h +++ b/lib/include/radsec/radsec-impl.h @@ -40,7 +40,6 @@ struct rs_credentials {      char *identity;      char *secret;      enum rs_key_encoding secret_encoding; -    unsigned int secret_len;  };  struct rs_error { @@ -48,14 +47,25 @@ struct rs_error {      char buf[1024];  }; +enum rs_peer_type { +    RS_PEER_TYPE_CLIENT = 1, +    RS_PEER_TYPE_SERVER = 2 +}; +  /** Configuration object for a connection.  */  struct rs_peer { +    enum rs_peer_type type;      struct rs_connection *conn;      struct rs_realm *realm;      char *hostname;      char *service;      char *secret;               /* RADIUS secret.  */      struct evutil_addrinfo *addr_cache; +    char *cacertfile; +    char *cacertpath; +    char *certfile; +    char *certkeyfile; +    struct rs_credentials *transport_cred;      struct rs_peer *next;  }; @@ -65,11 +75,6 @@ struct rs_realm {      enum rs_conn_type type;      int timeout;      int retries; -    char *cacertfile; -    char *cacertpath; -    char *certfile; -    char *certkeyfile; -    struct rs_credentials *transport_cred;      struct rs_peer *peers;      struct rs_realm *next;  }; diff --git a/lib/include/radsec/radsec.h b/lib/include/radsec/radsec.h index ee8c6a8..0a43f6f 100644 --- a/lib/include/radsec/radsec.h +++ b/lib/include/radsec/radsec.h @@ -208,6 +208,9 @@ int rs_context_set_alloc_scheme(struct rs_context *ctx,      accessed using \a rs_err_ctx_pop.  */  int rs_context_read_config(struct rs_context *ctx, const char *config_file); +int rs_context_print_config (struct rs_context *ctx, char **buf_out); + +  /****************/  /* Connection.  */  /****************/ diff --git a/lib/radsec.c b/lib/radsec.c index db406ae..e6b79cf 100644 --- a/lib/radsec.c +++ b/lib/radsec.c @@ -107,11 +107,11 @@ rs_context_destroy (struct rs_context *ctx)                    evutil_freeaddrinfo (p->addr_cache);                    p->addr_cache = NULL;                  } +              rs_free (ctx, p->transport_cred);  	      p = p->next;  	      rs_free (ctx, tmp);  	    }  	  free (r->name); -          rs_free (ctx, r->transport_cred);  	  r = r->next;  	  rs_free (ctx, tmp);  	} diff --git a/lib/radsec.sym b/lib/radsec.sym index 11f2468..6378cfd 100644 --- a/lib/radsec.sym +++ b/lib/radsec.sym @@ -53,6 +53,7 @@ rs_conn_set_timeout  rs_conn_set_type  rs_context_create  rs_context_destroy +rs_context_print_config  rs_context_read_config  rs_context_set_alloc_scheme  rs_dump_message @@ -25,13 +25,15 @@ _get_tlsconf (struct rs_connection *conn, const struct rs_realm *realm)    if (c)      {        memset (c, 0, sizeof (struct tls)); +      /* _conn_open() should've picked a peer by now. */ +      assert (conn->active_peer);        /* TODO: Make sure old radsecproxy code doesn't free these all  	 of a sudden, or strdup them.  */        c->name = realm->name; -      c->cacertfile = realm->cacertfile; +      c->cacertfile = conn->active_peer->cacertfile;        c->cacertpath = NULL;	/* NYI */ -      c->certfile = realm->certfile; -      c->certkeyfile = realm->certkeyfile; +      c->certfile = conn->active_peer->certfile; +      c->certkeyfile = conn->active_peer->certkeyfile;        c->certkeypwd = NULL;	/* NYI */        c->cacheexpiry = 0;	/* NYI */        c->crlcheck = 0;		/* NYI */ @@ -54,10 +56,11 @@ psk_client_cb (SSL *ssl,  {    struct rs_connection *conn = NULL;    struct rs_credentials *cred = NULL; +  unsigned int secret_len;    conn = SSL_get_ex_data (ssl, 0);    assert (conn != NULL); -  cred = conn->active_peer->realm->transport_cred; +  cred = conn->active_peer->transport_cred;    assert (cred != NULL);    /* NOTE: Ignoring identity hint from server.  */ @@ -72,14 +75,14 @@ psk_client_cb (SSL *ssl,    switch (cred->secret_encoding)      {      case RS_KEY_ENCODING_UTF8: -      cred->secret_len = strlen (cred->secret); -      if (cred->secret_len > max_psk_len) +      secret_len = strlen (cred->secret); +      if (secret_len > max_psk_len)          {            rs_err_conn_push (conn, RSE_CRED, "PSK secret longer than max %d",                              max_psk_len);            return 0;          } -      memcpy (psk, cred->secret, cred->secret_len); +      memcpy (psk, cred->secret, secret_len);        break;      case RS_KEY_ENCODING_ASCII_HEX:        { @@ -99,7 +102,7 @@ psk_client_cb (SSL *ssl,              BN_clear_free (bn);              return 0;            } -        cred->secret_len = BN_bn2bin (bn, psk); +        secret_len = BN_bn2bin (bn, psk);          BN_clear_free (bn);        }        break; @@ -107,7 +110,7 @@ psk_client_cb (SSL *ssl,        assert (!"unknown psk encoding");      } -  return cred->secret_len; +  return secret_len;  }  #endif  /* RS_ENABLE_TLS_PSK */ @@ -144,7 +147,7 @@ rs_tls_init (struct rs_connection *conn)      }  #if defined RS_ENABLE_TLS_PSK -  if (conn->active_peer->realm->transport_cred != NULL) +  if (conn->active_peer->transport_cred != NULL)      {        SSL_set_psk_client_callback (ssl, psk_client_cb);        SSL_set_ex_data (ssl, 0, conn); | 
