Example #1
0
void init_rfs_instance(struct rfs_instance *instance)
{
	init_client(instance);
	init_attr_cache(&instance->attr_cache);
	init_id_lookup(&instance->id_lookup);
	init_resume(instance);
	init_write_cache(instance);
	init_sendrecv(&instance->sendrecv);
	init_nss(instance);

	init_rfs_config(instance);
}
Example #2
0
File: nss.c Project: zcopley/curl
CURLcode Curl_nss_force_init(struct SessionHandle *data)
{
  CURLcode rv;
  if(!nss_initlock) {
    failf(data, "unable to initialize NSS, curl_global_init() should have been "
                "called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
    return CURLE_OUT_OF_MEMORY;
  }

  PR_Lock(nss_initlock);
  rv = init_nss(data);
  PR_Unlock(nss_initlock);
  return rv;
}
/** Entry point of application.
  @param argc Number of arguments on command line
  @param argv Array of strings with arguments from command line
  @return 0 on success, otherwise >0.
*/
int main(int argc,char *argv[]) {
  int mode,operation;
  char *hostname, *port;
  char *pname;
  int port_n;
  PRFileDesc *fd_socket;
  int res;

  pname=basename(argv[0]);

  atexit(atexit_handler);

  if (!parse_cli(argc,argv,&operation,&mode,&hostname,&port) || operation==OPERATION_HELP) {
    show_usage(pname);

    if (operation!=OPERATION_HELP) return 1;

    return 0;
  }

  if ((port_n=return_port(port))==-1) {
    fprintf(stderr,"Error. Unknown port number/name %s!\n",port);

    return 1;
  }

  if (!(mode&MODE_NO_SSL)) {
    if (!init_nss()) return 1;
  }

  if (!(fd_socket=create_connected_socket(hostname,port_n,mode)))
    return 1;

  res=poll_cycle(fd_socket,mode);

  if (PR_Close(fd_socket)!=PR_SUCCESS) {
    print_nspr_error();

    return 1;
  }

  return (res?0:1);
}
Example #4
0
File: nss.c Project: zcopley/curl
CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
{
  PRInt32 err;
  PRFileDesc *model = NULL;
  PRBool ssl2 = PR_FALSE;
  PRBool ssl3 = PR_FALSE;
  PRBool tlsv1 = PR_FALSE;
  struct SessionHandle *data = conn->data;
  curl_socket_t sockfd = conn->sock[sockindex];
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
  int curlerr;
  const int *cipher_to_enable;
  PRSocketOptionData sock_opt;
  long time_left;
  PRUint32 timeout;

  if (connssl->state == ssl_connection_complete)
    return CURLE_OK;

  connssl->data = data;

#ifdef HAVE_PK11_CREATEGENERICOBJECT
  /* list of all NSS objects we need to destroy in Curl_nss_close() */
  connssl->obj_list = Curl_llist_alloc(nss_destroy_object);
  if(!connssl->obj_list)
    return CURLE_OUT_OF_MEMORY;
#endif

  /* FIXME. NSS doesn't support multiple databases open at the same time. */
  PR_Lock(nss_initlock);
  curlerr = init_nss(conn->data);
  if(CURLE_OK != curlerr) {
    PR_Unlock(nss_initlock);
    goto error;
  }

  curlerr = CURLE_SSL_CONNECT_ERROR;

#ifdef HAVE_PK11_CREATEGENERICOBJECT
  if(!mod) {
    char *configstring = aprintf("library=%s name=PEM", pem_library);
    if(!configstring) {
      PR_Unlock(nss_initlock);
      goto error;
    }
    mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
    free(configstring);

    if(!mod || !mod->loaded) {
      if(mod) {
        SECMOD_DestroyModule(mod);
        mod = NULL;
      }
      infof(data, "WARNING: failed to load NSS PEM library %s. Using "
            "OpenSSL PEM certificates will not work.\n", pem_library);
    }
  }
#endif

  PK11_SetPasswordFunc(nss_get_password);
  PR_Unlock(nss_initlock);

  model = PR_NewTCPSocket();
  if(!model)
    goto error;
  model = SSL_ImportFD(NULL, model);

  /* make the socket nonblocking */
  sock_opt.option = PR_SockOpt_Nonblocking;
  sock_opt.value.non_blocking = PR_TRUE;
  if(PR_SetSocketOption(model, &sock_opt) != SECSuccess)
    goto error;

  if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
    goto error;

  switch (data->set.ssl.version) {
  default:
  case CURL_SSLVERSION_DEFAULT:
    ssl3 = PR_TRUE;
    if (data->state.ssl_connect_retry)
      infof(data, "TLS disabled due to previous handshake failure\n");
    else
      tlsv1 = PR_TRUE;
    break;
  case CURL_SSLVERSION_TLSv1:
    tlsv1 = PR_TRUE;
    break;
  case CURL_SSLVERSION_SSLv2:
    ssl2 = PR_TRUE;
    break;
  case CURL_SSLVERSION_SSLv3:
    ssl3 = PR_TRUE;
    break;
  }

  if(SSL_OptionSet(model, SSL_ENABLE_SSL2, ssl2) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_ENABLE_SSL3, ssl3) != SECSuccess)
    goto error;
  if(SSL_OptionSet(model, SSL_ENABLE_TLS, tlsv1) != SECSuccess)
    goto error;

  if(SSL_OptionSet(model, SSL_V2_COMPATIBLE_HELLO, ssl2) != SECSuccess)
    goto error;

  /* reset the flag to avoid an infinite loop */
  data->state.ssl_connect_retry = FALSE;

  /* enable all ciphers from enable_ciphers_by_default */
  cipher_to_enable = enable_ciphers_by_default;
  while (SSL_NULL_WITH_NULL_NULL != *cipher_to_enable) {
    if (SSL_CipherPrefSet(model, *cipher_to_enable, PR_TRUE) != SECSuccess) {
      curlerr = CURLE_SSL_CIPHER;
      goto error;
    }
    cipher_to_enable++;
  }

  if(data->set.ssl.cipher_list) {
    if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) {
      curlerr = CURLE_SSL_CIPHER;
      goto error;
    }
  }

  if(data->set.ssl.verifyhost == 1)
    infof(data, "warning: ignoring unsupported value (1) of ssl.verifyhost\n");

  data->set.ssl.certverifyresult=0; /* not checked yet */
  if(SSL_BadCertHook(model, (SSLBadCertHandler) BadCertHandler, conn)
     != SECSuccess) {
    goto error;
  }
  if(SSL_HandshakeCallback(model, (SSLHandshakeCallback) HandshakeCallback,
                           NULL) != SECSuccess)
    goto error;

  if(data->set.ssl.verifypeer && (CURLE_OK !=
        (curlerr = nss_load_ca_certificates(conn, sockindex))))
    goto error;

  if (data->set.ssl.CRLfile) {
    if(SECSuccess != nss_load_crl(data->set.ssl.CRLfile)) {
      curlerr = CURLE_SSL_CRL_BADFILE;
      goto error;
    }
    infof(data,
          "  CRLfile: %s\n",
          data->set.ssl.CRLfile ? data->set.ssl.CRLfile : "none");
  }

  if(data->set.str[STRING_CERT]) {
    bool is_nickname;
    char *nickname = fmt_nickname(data, STRING_CERT, &is_nickname);
    if(!nickname)
      return CURLE_OUT_OF_MEMORY;

    if(!is_nickname && !cert_stuff(conn, sockindex, data->set.str[STRING_CERT],
                                   data->set.str[STRING_KEY])) {
      /* failf() is already done in cert_stuff() */
      free(nickname);
      return CURLE_SSL_CERTPROBLEM;
    }

    /* store the nickname for SelectClientCert() called during handshake */
    connssl->client_nickname = nickname;
  }
  else
    connssl->client_nickname = NULL;

  if(SSL_GetClientAuthDataHook(model, SelectClientCert,
                               (void *)connssl) != SECSuccess) {
    curlerr = CURLE_SSL_CERTPROBLEM;
    goto error;
  }

  /* Import our model socket  onto the existing file descriptor */
  connssl->handle = PR_ImportTCPSocket(sockfd);
  connssl->handle = SSL_ImportFD(model, connssl->handle);
  if(!connssl->handle)
    goto error;

  PR_Close(model); /* We don't need this any more */
  model = NULL;

  /* This is the password associated with the cert that we're using */
  if (data->set.str[STRING_KEY_PASSWD]) {
    SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]);
  }

  /* Force handshake on next I/O */
  SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE);

  SSL_SetURL(connssl->handle, conn->host.name);

  /* check timeout situation */
  time_left = Curl_timeleft(data, NULL, TRUE);
  if(time_left < 0L) {
    failf(data, "timed out before SSL handshake");
    goto error;
  }
  timeout = PR_MillisecondsToInterval((PRUint32) time_left);

  /* Force the handshake now */
  if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) {
    if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
      curlerr = CURLE_PEER_FAILED_VERIFICATION;
    else if(conn->data->set.ssl.certverifyresult!=0)
      curlerr = CURLE_SSL_CACERT;
    goto error;
  }

  connssl->state = ssl_connection_complete;
  conn->recv[sockindex] = nss_recv;
  conn->send[sockindex] = nss_send;

  display_conn_info(conn, connssl->handle);

  if (data->set.str[STRING_SSL_ISSUERCERT]) {
    SECStatus ret = SECFailure;
    bool is_nickname;
    char *nickname = fmt_nickname(data, STRING_SSL_ISSUERCERT, &is_nickname);
    if(!nickname)
      return CURLE_OUT_OF_MEMORY;

    if(is_nickname)
      /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */
      ret = check_issuer_cert(connssl->handle, nickname);

    free(nickname);

    if(SECFailure == ret) {
      infof(data,"SSL certificate issuer check failed\n");
      curlerr = CURLE_SSL_ISSUER_ERROR;
      goto error;
    }
    else {
      infof(data, "SSL certificate issuer check ok\n");
    }
  }

  return CURLE_OK;

  error:
  /* reset the flag to avoid an infinite loop */
  data->state.ssl_connect_retry = FALSE;

  err = PR_GetError();
  if(handle_cc_error(err, data))
    curlerr = CURLE_SSL_CERTPROBLEM;
  else
    infof(data, "NSS error %d\n", err);

  if(model)
    PR_Close(model);

  if (ssl3 && tlsv1 && isTLSIntoleranceError(err)) {
    /* schedule reconnect through Curl_retry_request() */
    data->state.ssl_connect_retry = TRUE;
    infof(data, "Error in TLS handshake, trying SSLv3...\n");
    return CURLE_OK;
  }

  return curlerr;
}
Example #5
0
int nsscrypto_init(
	knet_handle_t knet_h,
	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
{
	struct nsscrypto_instance *nsscrypto_instance = NULL;

	log_debug(knet_h, KNET_SUB_NSSCRYPTO,
		  "Initizializing nss crypto module [%s/%s]",
		  knet_handle_crypto_cfg->crypto_cipher_type,
		  knet_handle_crypto_cfg->crypto_hash_type);

	knet_h->crypto_instance->model_instance = malloc(sizeof(struct nsscrypto_instance));
	if (!knet_h->crypto_instance->model_instance) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to allocate memory for nss model instance");
		return -1;
	}

	nsscrypto_instance = knet_h->crypto_instance->model_instance;

	memset(nsscrypto_instance, 0, sizeof(struct nsscrypto_instance));

	nsscrypto_instance->crypto_cipher_type = string_to_crypto_cipher_type(knet_handle_crypto_cfg->crypto_cipher_type);
	if (nsscrypto_instance->crypto_cipher_type < 0) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "unknown crypto cipher type requested");
		goto out_err;
	}

	nsscrypto_instance->crypto_hash_type = string_to_crypto_hash_type(knet_handle_crypto_cfg->crypto_hash_type);
	if (nsscrypto_instance->crypto_hash_type < 0) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "unknown crypto hash type requested");
		goto out_err;
	}

	if ((nsscrypto_instance->crypto_cipher_type > 0) &&
	    (nsscrypto_instance->crypto_hash_type == 0)) {
		log_err(knet_h, KNET_SUB_NSSCRYPTO, "crypto communication requires hash specified");
		goto out_err;
	}

	nsscrypto_instance->private_key = knet_handle_crypto_cfg->private_key;
	nsscrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len;

	if (init_nss(knet_h) < 0) {
		goto out_err;
	}

	knet_h->sec_header_size = 0;

	if (nsscrypto_instance->crypto_hash_type > 0) {
		knet_h->sec_header_size += hash_len[nsscrypto_instance->crypto_hash_type];
		knet_h->sec_hash_size = hash_len[nsscrypto_instance->crypto_hash_type];
	}

	if (nsscrypto_instance->crypto_cipher_type > 0) {
		int block_size;

		if (cypher_block_len[nsscrypto_instance->crypto_cipher_type]) {
			block_size = cypher_block_len[nsscrypto_instance->crypto_cipher_type];
		} else {
			block_size = PK11_GetBlockSize(nsscrypto_instance->crypto_cipher_type, NULL);
			if (block_size < 0) {
				goto out_err;
			}
		}

		knet_h->sec_header_size += (block_size * 2);
		knet_h->sec_header_size += SALT_SIZE;
		knet_h->sec_salt_size = SALT_SIZE;
		knet_h->sec_block_size = block_size;
	}

	return 0;

out_err:
	nsscrypto_fini(knet_h);
	return -1;
}