示例#1
0
void pni_sasl_set_user_password(pn_transport_t *transport, const char *user, const char *password)
{
  pni_sasl_t *sasl = transport->sasl;
  sasl->username = user;
  free(sasl->password);
  sasl->password = password ? pn_strdup(password) : NULL;
}
示例#2
0
pn_sasl_t *pn_sasl(pn_transport_t *transport)
{
  if (!transport->sasl) {
    pni_sasl_t *sasl = (pni_sasl_t *) malloc(sizeof(pni_sasl_t));

    const char *sasl_config_path = getenv("PN_SASL_CONFIG_PATH");

    sasl->impl_context = NULL;
    sasl->client = !transport->server;
    sasl->selected_mechanism = NULL;
    sasl->included_mechanisms = NULL;
    sasl->username = NULL;
    sasl->password = NULL;
    sasl->config_name = NULL;
    sasl->config_dir =  sasl_config_path ? pn_strdup(sasl_config_path) : NULL;
    sasl->remote_fqdn = NULL;
    sasl->external_auth = NULL;
    sasl->external_ssf = 0;
    sasl->outcome = PN_SASL_NONE;
    sasl->impl_context = NULL;
    sasl->decoded_buffer = pn_buffer(0);
    sasl->encoded_buffer = pn_buffer(0);
    sasl->bytes_out.size = 0;
    sasl->bytes_out.start = NULL;
    sasl->desired_state = SASL_NONE;
    sasl->last_state = SASL_NONE;
    sasl->allow_insecure_mechs = false;

    transport->sasl = sasl;
  }

  // The actual external pn_sasl_t pointer is a pointer to its enclosing pn_transport_t
  return (pn_sasl_t *)transport;
}
示例#3
0
void pni_sasl_set_external_security(pn_transport_t *transport, int ssf, const char *authid)
{
  pni_sasl_t *sasl = transport->sasl;
  sasl->external_ssf = ssf;
  free(sasl->external_auth);
  sasl->external_auth = authid ? pn_strdup(authid) : NULL;
}
示例#4
0
int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
                                          const pn_ssl_verify_mode_t mode,
                                          const char *trusted_CAs)
{
  if (!domain) return -1;

  switch (mode) {
  case PN_SSL_VERIFY_PEER:
  case PN_SSL_VERIFY_PEER_NAME:

    if (!domain->has_ca_db) {
      pn_transport_logf(NULL, "Error: cannot verify peer without a trusted CA configured.\n"
                 "       Use pn_ssl_domain_set_trusted_ca_db()");
      return -1;
    }

    if (domain->mode == PN_SSL_MODE_SERVER) {
      // openssl requires that server connections supply a list of trusted CAs which is
      // sent to the client
      if (!trusted_CAs) {
        pn_transport_logf(NULL, "Error: a list of trusted CAs must be provided.");
        return -1;
      }
      if (!domain->has_certificate) {
        pn_transport_logf(NULL, "Error: Server cannot verify peer without configuring a certificate.\n"
                   "       Use pn_ssl_domain_set_credentials()");
      }

      if (domain->trusted_CAs) free(domain->trusted_CAs);
      domain->trusted_CAs = pn_strdup( trusted_CAs );
      STACK_OF(X509_NAME) *cert_names;
      cert_names = SSL_load_client_CA_file( domain->trusted_CAs );
      if (cert_names != NULL)
        SSL_CTX_set_client_CA_list(domain->ctx, cert_names);
      else {
        pn_transport_logf(NULL, "Error: Unable to process file of trusted CAs: %s", trusted_CAs);
        return -1;
      }
    }

    SSL_CTX_set_verify( domain->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                        verify_callback);
#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
    SSL_CTX_set_verify_depth(domain->ctx, 1);
#endif
    break;

  case PN_SSL_ANONYMOUS_PEER:   // hippie free love mode... :)
    SSL_CTX_set_verify( domain->ctx, SSL_VERIFY_NONE, NULL );
    break;

  default:
    pn_transport_logf(NULL, "Invalid peer authentication mode given." );
    return -1;
  }

  domain->verify_mode = mode;
  return 0;
}
示例#5
0
char* pn_i_genuuid(void) {
    unsigned char *generated;
    UUID uuid;
    UuidCreate(&uuid);
    UuidToString(&uuid, &generated);
    char* r = pn_strdup((const char*)generated);
    RpcStringFree(&generated);
    return r;
}
示例#6
0
int pn_error_set(pn_error_t *error, int code, const char *text)
{
  pn_error_clear(error);
  if (code) {
    error->code = code;
    error->text = pn_strdup(text);
  }
  return code;
}
示例#7
0
void pn_sasl_allowed_mechs(pn_sasl_t *sasl0, const char *mechs)
{
    pni_sasl_t *sasl = get_sasl_internal(sasl0);
    free(sasl->included_mechanisms);
    sasl->included_mechanisms = mechs ? pn_strdup(mechs) : NULL;
    if (strcmp(mechs, "ANONYMOUS")==0 ) {
      pn_transport_t *transport = get_transport_internal(sasl0);
      pni_sasl_force_anonymous(transport);
    }
}
示例#8
0
char *build_name(const char *name)
{
  if (name) {
    return pn_strdup(name);
  } else {
    char *generated = malloc(37*sizeof(char));
    uuid_t uuid;
    uuid_generate(uuid);
    uuid_unparse_lower(uuid, generated);
    return generated;
  }
}
示例#9
0
int pni_sasl_impl_list_mechs(pn_transport_t *transport, char **mechlist)
{
  pni_sasl_t *sasl = transport->sasl;
  sasl_conn_t *cyrus_conn = (sasl_conn_t*)sasl->impl_context;
  int count = 0;
  if (cyrus_conn) {
    const char *result = NULL;

    int r = sasl_listmech(cyrus_conn, NULL, "", " ", "", &result, NULL, &count);
    if (pni_check_sasl_result(cyrus_conn, r, transport)) {
      if (result && *result) {
        *mechlist = pn_strdup(result);
      }
    }
  }
  return count;
}
示例#10
0
bool pni_process_mechanisms(pn_transport_t *transport, const char *mechs)
{
    pni_sasl_t *sasl = transport->sasl;
    sasl_conn_t *cyrus_conn = (sasl_conn_t*)sasl->impl_context;
    const char *mech_selected;
    int result = pni_wrap_client_start(sasl, mechs, &mech_selected);
    switch (result) {
        case SASL_OK:
        case SASL_CONTINUE:
          sasl->selected_mechanism = pn_strdup(mech_selected);
          return true;
        case SASL_NOMECH:
        default:
          pni_check_sasl_result(cyrus_conn, result, transport);
          return false;
    }
}
示例#11
0
int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id)
{
  pn_transport_t *transport = get_transport_internal(ssl0);
  pni_ssl_t *ssl = transport->ssl;
  if (!ssl || !domain || ssl->domain) return -1;

  ssl->domain = domain;
  domain->ref_count++;
  if (session_id && domain->mode == PN_SSL_MODE_CLIENT)
    ssl->session_id = pn_strdup(session_id);

  // If SSL doesn't specifically allow skipping encryption, require SSL
  // TODO: This is a probably a stop-gap until allow_unsecured is removed
  if (!domain->allow_unsecured) transport->encryption_required = true;

  return init_ssl_socket(transport, ssl);
}
示例#12
0
int pn_ssl_set_peer_hostname( pn_ssl_t *ssl, const char *hostname )
{
  if (!ssl) return -1;

  if (ssl->peer_hostname) free((void *)ssl->peer_hostname);
  ssl->peer_hostname = NULL;
  if (hostname) {
    ssl->peer_hostname = pn_strdup(hostname);
    if (!ssl->peer_hostname) return -2;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
    if (ssl->ssl && ssl->domain && ssl->domain->mode == PN_SSL_MODE_CLIENT) {
      SSL_set_tlsext_host_name(ssl->ssl, ssl->peer_hostname);
    }
#endif
  }
  return 0;
}
示例#13
0
int pn_ssl_init( pn_ssl_t *ssl, pn_ssl_domain_t *domain, const char *session_id)
{
  if (!ssl || !domain || ssl->domain) return -1;

  ssl->domain = domain;
  domain->ref_count++;
  if (domain->allow_unsecured) {
    ssl->io_layer->process_input = process_input_unknown;
    ssl->io_layer->process_output = process_output_unknown;
  } else {
    ssl->io_layer->process_input = process_input_ssl;
    ssl->io_layer->process_output = process_output_ssl;
  }

  if (session_id && domain->mode == PN_SSL_MODE_CLIENT)
    ssl->session_id = pn_strdup(session_id);

  return init_ssl_socket(ssl);
}
示例#14
0
int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
                               const char *certificate_file,
                               const char *private_key_file,
                               const char *password)
{
  if (!domain || !domain->ctx) return -1;

  if (SSL_CTX_use_certificate_chain_file(domain->ctx, certificate_file) != 1) {
    ssl_log_error("SSL_CTX_use_certificate_chain_file( %s ) failed", certificate_file);
    return -3;
  }

  if (password) {
    domain->keyfile_pw = pn_strdup(password);  // @todo: obfuscate me!!!
    SSL_CTX_set_default_passwd_cb(domain->ctx, keyfile_pw_cb);
    SSL_CTX_set_default_passwd_cb_userdata(domain->ctx, domain->keyfile_pw);
  }

  if (SSL_CTX_use_PrivateKey_file(domain->ctx, private_key_file, SSL_FILETYPE_PEM) != 1) {
    ssl_log_error("SSL_CTX_use_PrivateKey_file( %s ) failed", private_key_file);
    return -4;
  }

  if (SSL_CTX_check_private_key(domain->ctx) != 1) {
    ssl_log_error("The key file %s is not consistent with the certificate %s",
                   private_key_file, certificate_file);
    return -5;
  }

  domain->has_certificate = true;

  // bug in older versions of OpenSSL: servers may request client cert even if anonymous
  // cipher was negotiated.  TLSv1 will reject such a request.  Hack: once a cert is
  // configured, allow only authenticated ciphers.
  if (!SSL_CTX_set_cipher_list( domain->ctx, CIPHERS_AUTHENTICATE )) {
      ssl_log_error("Failed to set cipher list to %s", CIPHERS_AUTHENTICATE);
      return -6;
  }

  return 0;
}
示例#15
0
static int start_ssl_shutdown( pn_ssl_t *ssl )
{
  if (!ssl->ssl_shutdown) {
    _log(ssl, "Shutting down SSL connection...\n");
    if (ssl->session_id) {
      // save the negotiated credentials before we close the connection
      pn_ssl_session_t *ssn = (pn_ssl_session_t *)calloc( 1, sizeof(pn_ssl_session_t));
      if (ssn) {
        ssn->id = pn_strdup( ssl->session_id );
        ssn->session = SSL_get1_session( ssl->ssl );
        if (ssn->session) {
          _log( ssl, "Saving SSL session as %s\n", ssl->session_id );
          LL_ADD( ssl->domain, ssn_cache, ssn );
        } else {
          ssl_session_free( ssn );
        }
      }
    }
    ssl->ssl_shutdown = true;
    BIO_ssl_shutdown( ssl->bio_ssl );
  }
  return 0;
}
示例#16
0
void pn_sasl_config_path(pn_sasl_t *sasl0, const char *dir)
{
    pni_sasl_t *sasl = get_sasl_internal(sasl0);
    free(sasl->config_dir);
    sasl->config_dir = pn_strdup(dir);
}
示例#17
0
void pn_sasl_config_name(pn_sasl_t *sasl0, const char *name)
{
    pni_sasl_t *sasl = get_sasl_internal(sasl0);
    free(sasl->config_name);
    sasl->config_name = pn_strdup(name);
}
示例#18
0
void pn_sasl_mechanisms(pn_sasl_t *sasl, const char *mechanisms)
{
  if (!sasl) return;
  sasl->mechanisms = pn_strdup(mechanisms);
}