Exemple #1
0
int main(int argc, char *argv[], char *envp[])
{
	register int		i=0; // for counter
	int		rc = 0;
	char 	*logtitle;	// for syslog title
	pid_t	pid;

	// Initialization area
	config.loglevel = 0;
	config.daemon = 1;
	config.cmdl = 1;
	config.index = 0;

	strcpy(config.pidfilename, DEFAULT_PID_FILE);
	strcpy(config.imagefile, argv[0]);

	// Initialize buffers for errors
	*errbuf.common = '\0';
	*errbuf.libnet = '\0';
	capindex = 0;

	if ((rc = optparse(&config, argc, argv, envp)) != 0)
	switch (rc)
	{
		case -1:
			exit(EXIT_FAILURE);
		case 1:
			exit(EXIT_SUCCESS);
		default:
			exit(rc);
	}
	
	if (config.index == 0)
	{
		fprintf(stderr,"You must define all obligatory parameters in running arguments or in configuration file.\n");
		usage();
		exit(EXIT_FAILURE);
	}
	
	if (check_config(&config))
		exit (EXIT_FAILURE);
		
	if (config.loglevel > 0)
		print_config(&config);
		
	if (getuid() != 0)
	{
		fprintf(stderr, "%s, you must be root to run this program.\n", getlogin());
		exit (EXIT_FAILURE);
	}

	config.pidfile = fopen (config.pidfilename, "w");
	if (config.pidfile == NULL)
	{
		fprintf (stderr, "Error to create pid-file \"%s\".\n", config.pidfilename);
		fprintf (stderr, "Try %s -f <path>", config.imagefile);
		exit (EXIT_FAILURE);
	}

	if (config.daemon)
	{
		if (daemon(1,1) != 0)
		{
			fprintf(stderr,"Daemonize error, running in interactive mode.\n");
			config.daemon = 0;
		}
	}
	
	// Write PID to PID-file
	fprintf(config.pidfile, "%d\n", getpid());
	fclose(config.pidfile);

	atexit(before_exit);

	if (config.index > 1)
	{
		struct	sigaction sact;
		
		sact.sa_sigaction = SIGCHLD_act;
		sact.sa_flags = SA_RESTART | SA_NOMASK | SA_SIGINFO;
		sigaction(SIGCHLD, &sact, NULL);
	
		childs.index = 0;
		parent = 1;
		for (i=0; i<config.index; i++)
		{
			pid = fork();
			switch(pid)
			{
				case -1: // fork() error
					errorlog("ERROR: Can't exec fork().");
					break;

				case 0:	// in child
					logtitle = malloc((strlen(config.cap[i]->title)+24) * sizeof(char));
					parent = 0;
					capindex = i;
				
					sprintf(logtitle, "viewssl daemon child [%s]", config.cap[capindex]->title);

					openlog(logtitle, LOG_PID, LOG_DAEMON);
					syslog(LOG_NOTICE,"started at %s",gettime());
					break;

				default: // in parent
					childs.pid[childs.index] = pid;
					childs.title[childs.index] = malloc((strlen(config.cap[childs.index]->title)+1)*sizeof(char));
					strcpy(childs.title[childs.index],config.cap[childs.index]->title);
					childs.index++;
					break;
			} // switch(pid)

			if (!parent)
				break;
		} // for (i=0;i<config.index;i++)

		signal(SIGTERM, fsignal);
		signal(SIGINT, fsignal);
		signal(SIGQUIT, fsignal);


		if (parent)
		{ // in parent
			struct	sockaddr_un uds_addr;
			struct  sockaddr_un cl_addr;

			int		ss=0, r=0;	// master services socket

			// Master
			openlog("viewssl daemon master", LOG_PID, LOG_DAEMON);
			syslog(LOG_NOTICE, "started at %s", gettime());
			
			ss = socket(PF_UNIX, SOCK_STREAM, 0);
			if (ss < 0)
				errorlog("socket() error.");

			
			memset(&uds_addr, 0, sizeof(uds_addr));
			uds_addr.sun_family = AF_UNIX;
			strcpy(uds_addr.sun_path,SOCKPATH);
			
			unlink (SOCKPATH);
			
			r = bind(ss, (struct sockaddr *)&uds_addr, sizeof(uds_addr));
			if (r < 0)
				errorlog("bind() error.");
			
			r = listen(ss, 10);
			if (r < 0)
				errorlog("listen() error.");
			
			while(1)
			{
				int	cons=0;
				socklen_t cl_addr_len=0;

				memset (&cl_addr, 0, sizeof(cl_addr));
				cons = accept(ss, (struct sockaddr*) &cl_addr, &cl_addr_len);
				close(cons);
			}

			close(ss);
			unlink (SOCKPATH);
			exit(EXIT_SUCCESS);	// end master

		} else // child
		{
			signal(SIGCHLD, fsignal);
		}
		
	} // if (config.index > 1)
	else
	{ // one thread
		openlog("viewssl daemon", LOG_PID, LOG_DAEMON);
	}
	
	SSL_library_init();
	OpenSSL_add_all_ciphers();
	OpenSSL_add_all_digests();

	rc = proceed();

	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();

	if (rc != 0)
		exit(EXIT_FAILURE);
	else
		exit(EXIT_SUCCESS);	// end childs
}
unsigned char * AesFileEnc::key ( )
{
	FILE* keystore;
	keystore = fopen(this->keystore_path, "r");
	unsigned char *iv = this->iv(32);
	unsigned char* key = new unsigned char[32];
	const char *prompt;
	prompt = getpass("Your password to keystore: " );
	unsigned char* sha;
   sha = SHA256(reinterpret_cast<const unsigned char*>(prompt), 32, NULL); //uwaga
   //printf("SHA %s aaa",(char *)sha);
	delete prompt;
	

  ERR_load_crypto_strings();
  OpenSSL_add_all_algorithms();
  OPENSSL_config(NULL);
  
	if(keystore == NULL)
	{
		keystore = fopen(this->keystore_path, "w+");
		std::cout<<this->keystore_path;
		srand(time(0));
		int j;
		char *buffer;
		buffer = new char;
		for(int i = 0 ; i<32; i++)
		{
			j = (int)(rand() / (RAND_MAX + 1.0) * 16);		
			sprintf(buffer,"%x",j);
			key[i] = *buffer;
		}
		 delete(buffer);

  unsigned char ciphertext[512];

  int ciphertext_len;

  ciphertext_len = this->encrypt (key, 32, sha, iv,
                            ciphertext);
	fprintf(keystore, "%s" ,(const char *)ciphertext);	
	//printf("KLUCZ zapisywany:%s KKK   %i" ,(const char *)ciphertext, ciphertext_len);	
}
else{

  unsigned char * decryptedtext = new unsigned char[512];
  unsigned char* keycipher = new unsigned char[512];
  int ciphertext_len = 0;
  int buff;
  while((buff = getc(keystore))!= EOF)
	{
		keycipher[ciphertext_len] = (unsigned char)buff;
		ciphertext_len++;
	}
	ciphertext_len--;
  //fscanf(keystore, "%512c", keycipher);
  int decryptedtext_len;
	//printf("KLUCZ wczytany:%s KKK   %i" ,(const char *)keycipher, ciphertext_len);	


  decryptedtext_len = decrypt(keycipher, ciphertext_len, sha, iv,
    decryptedtext);
  key = ( unsigned char *)decryptedtext;
}

  unsigned char* KEY;
  KEY = new unsigned char[this->keyLength];
  KEY[this->keyLength] = '\0';
  printf("%s        PIES \n",KEY);
  for(int i =0; i<this->keyLength; i++)
	{KEY[i] = key[i];}

  //delete(key);
  //delete(sha);
    	//std::cout << "tutajkhjghjfghyt" <<std::endl;
  fclose(keystore);
  //std::cout<<this->keyLength <<std::endl;
   //printf("KLUCZ %s",KEY);
  std::cout << (const char *)KEY<<"PIES"<<std::endl;
    std::cout <<key<<"PIES"<<std::endl;
   EVP_cleanup();
  ERR_free_strings();
  return KEY;
	}
Exemple #3
0
//--------------------------------------------------
// cleanup of DigiDoc library
//--------------------------------------------------
EXP_OPTION void finalizeDigiDocLib()
{
    ERR_free_strings();
    EVP_cleanup();
}
Exemple #4
0
int main(int argc, char *argv[]) {

  unsigned int bundleLength=0, urlLength=0;

  if (argc == 3) {
    printf("UNSUPPORTED\n");  //for now at least
    return EXIT_SUCCESS;
  } else if (argc != 4) {
    printf("usage: %s <host> <port> <ca-bundle>\n", argv[0]);
    return EXIT_FAILURE;
  } else if ((urlLength = strlen(argv[1]) + strlen(argv[2]) + 2) > MAX_LENGTH) {
    printf("Too long URL: %d characters, max: %d\n", urlLength, MAX_LENGTH);
    return EXIT_FAILURE;
  } else if ((bundleLength = strlen(argv[3]) + 1) > MAX_LENGTH) {
    printf("Too long ca-bundle filepath: %d characters, max: %d\n", bundleLength, MAX_LENGTH);
    return EXIT_FAILURE;
  }

  char url[1024];       snprintf(url, sizeof(url), "%s:%s", argv[1], argv[2]);
  char ca_bundle[1024]; memcpy(ca_bundle, argv[3], bundleLength);
  int exitvalue = 0;

  BIO *sbio;
  SSL_CTX *ssl_ctx;
  SSL *ssl;
  X509 *cert;

  const char *servername = NULL;
  X509_VERIFY_PARAM *param = NULL;

  SSL_load_error_strings();
  SSL_library_init();

  ssl_ctx = SSL_CTX_new(TLS_method());  //if you are using an older version of openssl, you may need to change this into for example: TLSv1_2_client_method
  param = SSL_CTX_get0_param(ssl_ctx);

  //set certificate verify
  //https://wiki.openssl.org/index.php/Hostname_validation
  X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
  X509_VERIFY_PARAM_set1_host(param, argv[1], 0);
  SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
  if (SSL_CTX_load_verify_locations(ssl_ctx, ca_bundle, NULL) != 1) {
    printf("Couldn't load certificate trust store\n");
    printf("%s\n", ERR_reason_error_string(ERR_get_error()));
    exitvalue=EXIT_FAILURE;
    goto end;
  }

  sbio = BIO_new_ssl_connect(ssl_ctx);
  BIO_get_ssl(sbio, &ssl);
  if (!ssl) {
    printf("Connection failed\n");
    printf("%s\n", ERR_reason_error_string(ERR_get_error()));
    exitvalue=EXIT_FAILURE;
    goto connect_end;
  }

  //handshake
  SSL_set_tlsext_host_name(ssl, url);
  BIO_set_conn_hostname(sbio, url);
  if(SSL_do_handshake(ssl) <= 0) {
    unsigned long int error = ERR_get_error();
    printf("%s\n", ERR_reason_error_string(error));
    printf("REJECT\n");
  } else {
    printf ("ACCEPT\n");
  }

connect_end:

  BIO_free_all(sbio);

end:

  SSL_CTX_free(ssl_ctx);
  EVP_cleanup();
  ERR_free_strings();

  return exitvalue;
}
Exemple #5
0
/**
 * libwebsocket_context_destroy() - Destroy the websocket context
 * @context:	Websocket context
 *
 *	This function closes any active connections and then frees the
 *	context.  After calling this, any further use of the context is
 *	undefined.
 */
LWS_VISIBLE void
libwebsocket_context_destroy(struct libwebsocket_context *context)
{
	int n;
	struct libwebsocket_protocols *protocol = context->protocols;

#ifdef LWS_LATENCY
	if (context->worst_latency_info[0])
		lwsl_notice("Worst latency: %s\n", context->worst_latency_info);
#endif

	for (n = 0; n < context->fds_count; n++) {
		struct libwebsocket *wsi =
					context->lws_lookup[context->fds[n].fd];
		if (!wsi)
			continue;
		libwebsocket_close_and_free_session(context,
			wsi, LWS_CLOSE_STATUS_NOSTATUS /* no protocol close */);
		n--;
	}

	/*
	 * give all extensions a chance to clean up any per-context
	 * allocations they might have made
	 */
	if (context->listen_port) {
		if (lws_ext_callback_for_each_extension_type(context, NULL,
			 LWS_EXT_CALLBACK_SERVER_CONTEXT_DESTRUCT, NULL, 0) < 0)
			return;
	} else
		if (lws_ext_callback_for_each_extension_type(context, NULL,
			 LWS_EXT_CALLBACK_CLIENT_CONTEXT_DESTRUCT, NULL, 0) < 0)
			return;

	/*
	 * inform all the protocols that they are done and will have no more
	 * callbacks
	 */

	while (protocol->callback) {
		protocol->callback(context, NULL, LWS_CALLBACK_PROTOCOL_DESTROY,
				NULL, NULL, 0);
		protocol++;
	}

	lws_plat_context_early_destroy(context);

#ifdef LWS_OPENSSL_SUPPORT
	if (context->ssl_ctx)
		SSL_CTX_free(context->ssl_ctx);
	if (context->ssl_client_ctx)
		SSL_CTX_free(context->ssl_client_ctx);

	ERR_remove_state(0);
	ERR_free_strings();
	EVP_cleanup();
	CRYPTO_cleanup_all_ex_data();
#endif

	if (context->fds)
		free(context->fds);
	if (context->lws_lookup)
		free(context->lws_lookup);

	free(context);

	lws_plat_context_late_destroy(context);
}
Exemple #6
0
/*
 * OpenSSL provides SSL, TLS and general purpose cryptography.  It wraps the
 * OpenSSL[http://www.openssl.org/] library.
 *
 * = Install
 *
 * OpenSSL comes bundled with the Standard Library of Ruby.
 *
 * This means the OpenSSL extension is compiled with Ruby and packaged on
 * build. During compile time, Ruby will need to link against the OpenSSL
 * library on your system. However, you cannot use openssl provided by Apple to
 * build standard library openssl.
 *
 * If you use OSX, you should install another openssl and run ```./configure
 * --with-openssl-dir=/path/to/another-openssl```. For Homebrew user, run `brew
 * install openssl` and then ```./configure --with-openssl-dir=`brew --prefix
 * openssl` ```.
 *
 * = Examples
 *
 * All examples assume you have loaded OpenSSL with:
 *
 *   require 'openssl'
 *
 * These examples build atop each other.  For example the key created in the
 * next is used in throughout these examples.
 *
 * == Keys
 *
 * === Creating a Key
 *
 * This example creates a 2048 bit RSA keypair and writes it to the current
 * directory.
 *
 *   key = OpenSSL::PKey::RSA.new 2048
 *
 *   open 'private_key.pem', 'w' do |io| io.write key.to_pem end
 *   open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
 *
 * === Exporting a Key
 *
 * Keys saved to disk without encryption are not secure as anyone who gets
 * ahold of the key may use it unless it is encrypted.  In order to securely
 * export a key you may export it with a pass phrase.
 *
 *   cipher = OpenSSL::Cipher.new 'AES-128-CBC'
 *   pass_phrase = 'my secure pass phrase goes here'
 *
 *   key_secure = key.export cipher, pass_phrase
 *
 *   open 'private.secure.pem', 'w' do |io|
 *     io.write key_secure
 *   end
 *
 * OpenSSL::Cipher.ciphers returns a list of available ciphers.
 *
 * === Loading a Key
 *
 * A key can also be loaded from a file.
 *
 *   key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
 *   key2.public? # => true
 *
 * or
 *
 *   key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
 *   key3.private? # => false
 *
 * === Loading an Encrypted Key
 *
 * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
 * If you will not be able to type in the pass phrase you may provide it when
 * loading the key:
 *
 *   key4_pem = File.read 'private.secure.pem'
 *   key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
 *
 * == RSA Encryption
 *
 * RSA provides encryption and decryption using the public and private keys.
 * You can use a variety of padding methods depending upon the intended use of
 * encrypted data.
 *
 * === Encryption & Decryption
 *
 * Asymmetric public/private key encryption is slow and victim to attack in
 * cases where it is used without padding or directly to encrypt larger chunks
 * of data. Typical use cases for RSA encryption involve "wrapping" a symmetric
 * key with the public key of the recipient who would "unwrap" that symmetric
 * key again using their private key.
 * The following illustrates a simplified example of such a key transport
 * scheme. It shouldn't be used in practice, though, standardized protocols
 * should always be preferred.
 *
 *   wrapped_key = key.public_encrypt key
 *
 * A symmetric key encrypted with the public key can only be decrypted with
 * the corresponding private key of the recipient.
 *
 *   original_key = key.private_decrypt wrapped_key
 *
 * By default PKCS#1 padding will be used, but it is also possible to use
 * other forms of padding, see PKey::RSA for further details.
 *
 * === Signatures
 *
 * Using "private_encrypt" to encrypt some data with the private key is
 * equivalent to applying a digital signature to the data. A verifying
 * party may validate the signature by comparing the result of decrypting
 * the signature with "public_decrypt" to the original data. However,
 * OpenSSL::PKey already has methods "sign" and "verify" that handle
 * digital signatures in a standardized way - "private_encrypt" and
 * "public_decrypt" shouldn't be used in practice.
 *
 * To sign a document, a cryptographically secure hash of the document is
 * computed first, which is then signed using the private key.
 *
 *   digest = OpenSSL::Digest::SHA256.new
 *   signature = key.sign digest, document
 *
 * To validate the signature, again a hash of the document is computed and
 * the signature is decrypted using the public key. The result is then
 * compared to the hash just computed, if they are equal the signature was
 * valid.
 *
 *   digest = OpenSSL::Digest::SHA256.new
 *   if key.verify digest, signature, document
 *     puts 'Valid'
 *   else
 *     puts 'Invalid'
 *   end
 *
 * == PBKDF2 Password-based Encryption
 *
 * If supported by the underlying OpenSSL version used, Password-based
 * Encryption should use the features of PKCS5. If not supported or if
 * required by legacy applications, the older, less secure methods specified
 * in RFC 2898 are also supported (see below).
 *
 * PKCS5 supports PBKDF2 as it was specified in PKCS#5
 * v2.0[http://www.rsa.com/rsalabs/node.asp?id=2127]. It still uses a
 * password, a salt, and additionally a number of iterations that will
 * slow the key derivation process down. The slower this is, the more work
 * it requires being able to brute-force the resulting key.
 *
 * === Encryption
 *
 * The strategy is to first instantiate a Cipher for encryption, and
 * then to generate a random IV plus a key derived from the password
 * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
 * the number of iterations largely depends on the hardware being used.
 *
 *   cipher = OpenSSL::Cipher.new 'AES-128-CBC'
 *   cipher.encrypt
 *   iv = cipher.random_iv
 *
 *   pwd = 'some hopefully not to easily guessable password'
 *   salt = OpenSSL::Random.random_bytes 16
 *   iter = 20000
 *   key_len = cipher.key_len
 *   digest = OpenSSL::Digest::SHA256.new
 *
 *   key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
 *   cipher.key = key
 *
 *   Now encrypt the data:
 *
 *   encrypted = cipher.update document
 *   encrypted << cipher.final
 *
 * === Decryption
 *
 * Use the same steps as before to derive the symmetric AES key, this time
 * setting the Cipher up for decryption.
 *
 *   cipher = OpenSSL::Cipher.new 'AES-128-CBC'
 *   cipher.decrypt
 *   cipher.iv = iv # the one generated with #random_iv
 *
 *   pwd = 'some hopefully not to easily guessable password'
 *   salt = ... # the one generated above
 *   iter = 20000
 *   key_len = cipher.key_len
 *   digest = OpenSSL::Digest::SHA256.new
 *
 *   key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
 *   cipher.key = key
 *
 *   Now decrypt the data:
 *
 *   decrypted = cipher.update encrypted
 *   decrypted << cipher.final
 *
 * == PKCS #5 Password-based Encryption
 *
 * PKCS #5 is a password-based encryption standard documented at
 * RFC2898[http://www.ietf.org/rfc/rfc2898.txt].  It allows a short password or
 * passphrase to be used to create a secure encryption key. If possible, PBKDF2
 * as described above should be used if the circumstances allow it.
 *
 * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
 * key.
 *
 *   pass_phrase = 'my secure pass phrase goes here'
 *   salt = '8 octets'
 *
 * === Encryption
 *
 * First set up the cipher for encryption
 *
 *   encryptor = OpenSSL::Cipher.new 'AES-128-CBC'
 *   encryptor.encrypt
 *   encryptor.pkcs5_keyivgen pass_phrase, salt
 *
 * Then pass the data you want to encrypt through
 *
 *   encrypted = encryptor.update 'top secret document'
 *   encrypted << encryptor.final
 *
 * === Decryption
 *
 * Use a new Cipher instance set up for decryption
 *
 *   decryptor = OpenSSL::Cipher.new 'AES-128-CBC'
 *   decryptor.decrypt
 *   decryptor.pkcs5_keyivgen pass_phrase, salt
 *
 * Then pass the data you want to decrypt through
 *
 *   plain = decryptor.update encrypted
 *   plain << decryptor.final
 *
 * == X509 Certificates
 *
 * === Creating a Certificate
 *
 * This example creates a self-signed certificate using an RSA key and a SHA1
 * signature.
 *
 *   name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
 *
 *   cert = OpenSSL::X509::Certificate.new
 *   cert.version = 2
 *   cert.serial = 0
 *   cert.not_before = Time.now
 *   cert.not_after = Time.now + 3600
 *
 *   cert.public_key = key.public_key
 *   cert.subject = name
 *
 * === Certificate Extensions
 *
 * You can add extensions to the certificate with
 * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
 *
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
 *
 *   cert.add_extension \
 *     extension_factory.create_extension('basicConstraints', 'CA:FALSE', true)
 *
 *   cert.add_extension \
 *     extension_factory.create_extension(
 *       'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
 *
 *   cert.add_extension \
 *     extension_factory.create_extension('subjectKeyIdentifier', 'hash')
 *
 * The list of supported extensions (and in some cases their possible values)
 * can be derived from the "objects.h" file in the OpenSSL source code.
 *
 * === Signing a Certificate
 *
 * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
 * with a digest algorithm.  This creates a self-signed cert because we're using
 * the same name and key to sign the certificate as was used to create the
 * certificate.
 *
 *   cert.issuer = name
 *   cert.sign key, OpenSSL::Digest::SHA1.new
 *
 *   open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
 *
 * === Loading a Certificate
 *
 * Like a key, a cert can also be loaded from a file.
 *
 *   cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
 *
 * === Verifying a Certificate
 *
 * Certificate#verify will return true when a certificate was signed with the
 * given public key.
 *
 *   raise 'certificate can not be verified' unless cert2.verify key
 *
 * == Certificate Authority
 *
 * A certificate authority (CA) is a trusted third party that allows you to
 * verify the ownership of unknown certificates.  The CA issues key signatures
 * that indicate it trusts the user of that key.  A user encountering the key
 * can verify the signature by using the CA's public key.
 *
 * === CA Key
 *
 * CA keys are valuable, so we encrypt and save it to disk and make sure it is
 * not readable by other users.
 *
 *   ca_key = OpenSSL::PKey::RSA.new 2048
 *
 *   cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
 *
 *   open 'ca_key.pem', 'w', 0400 do |io|
 *     io.write ca_key.export(cipher, pass_phrase)
 *   end
 *
 * === CA Certificate
 *
 * A CA certificate is created the same way we created a certificate above, but
 * with different extensions.
 *
 *   ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
 *
 *   ca_cert = OpenSSL::X509::Certificate.new
 *   ca_cert.serial = 0
 *   ca_cert.version = 2
 *   ca_cert.not_before = Time.now
 *   ca_cert.not_after = Time.now + 86400
 *
 *   ca_cert.public_key = ca_key.public_key
 *   ca_cert.subject = ca_name
 *   ca_cert.issuer = ca_name
 *
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new
 *   extension_factory.subject_certificate = ca_cert
 *   extension_factory.issuer_certificate = ca_cert
 *
 *   ca_cert.add_extension \
 *     extension_factory.create_extension('subjectKeyIdentifier', 'hash')
 *
 * This extension indicates the CA's key may be used as a CA.
 *
 *   ca_cert.add_extension \
 *     extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
 *
 * This extension indicates the CA's key may be used to verify signatures on
 * both certificates and certificate revocations.
 *
 *   ca_cert.add_extension \
 *     extension_factory.create_extension(
 *       'keyUsage', 'cRLSign,keyCertSign', true)
 *
 * Root CA certificates are self-signed.
 *
 *   ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
 *
 * The CA certificate is saved to disk so it may be distributed to all the
 * users of the keys this CA will sign.
 *
 *   open 'ca_cert.pem', 'w' do |io|
 *     io.write ca_cert.to_pem
 *   end
 *
 * === Certificate Signing Request
 *
 * The CA signs keys through a Certificate Signing Request (CSR).  The CSR
 * contains the information necessary to identify the key.
 *
 *   csr = OpenSSL::X509::Request.new
 *   csr.version = 0
 *   csr.subject = name
 *   csr.public_key = key.public_key
 *   csr.sign key, OpenSSL::Digest::SHA1.new
 *
 * A CSR is saved to disk and sent to the CA for signing.
 *
 *   open 'csr.pem', 'w' do |io|
 *     io.write csr.to_pem
 *   end
 *
 * === Creating a Certificate from a CSR
 *
 * Upon receiving a CSR the CA will verify it before signing it.  A minimal
 * verification would be to check the CSR's signature.
 *
 *   csr = OpenSSL::X509::Request.new File.read 'csr.pem'
 *
 *   raise 'CSR can not be verified' unless csr.verify csr.public_key
 *
 * After verification a certificate is created, marked for various usages,
 * signed with the CA key and returned to the requester.
 *
 *   csr_cert = OpenSSL::X509::Certificate.new
 *   csr_cert.serial = 0
 *   csr_cert.version = 2
 *   csr_cert.not_before = Time.now
 *   csr_cert.not_after = Time.now + 600
 *
 *   csr_cert.subject = csr.subject
 *   csr_cert.public_key = csr.public_key
 *   csr_cert.issuer = ca_cert.subject
 *
 *   extension_factory = OpenSSL::X509::ExtensionFactory.new
 *   extension_factory.subject_certificate = csr_cert
 *   extension_factory.issuer_certificate = ca_cert
 *
 *   csr_cert.add_extension \
 *     extension_factory.create_extension('basicConstraints', 'CA:FALSE')
 *
 *   csr_cert.add_extension \
 *     extension_factory.create_extension(
 *       'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature')
 *
 *   csr_cert.add_extension \
 *     extension_factory.create_extension('subjectKeyIdentifier', 'hash')
 *
 *   csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
 *
 *   open 'csr_cert.pem', 'w' do |io|
 *     io.write csr_cert.to_pem
 *   end
 *
 * == SSL and TLS Connections
 *
 * Using our created key and certificate we can create an SSL or TLS connection.
 * An SSLContext is used to set up an SSL session.
 *
 *   context = OpenSSL::SSL::SSLContext.new
 *
 * === SSL Server
 *
 * An SSL server requires the certificate and private key to communicate
 * securely with its clients:
 *
 *   context.cert = cert
 *   context.key = key
 *
 * Then create an SSLServer with a TCP server socket and the context.  Use the
 * SSLServer like an ordinary TCP server.
 *
 *   require 'socket'
 *
 *   tcp_server = TCPServer.new 5000
 *   ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
 *
 *   loop do
 *     ssl_connection = ssl_server.accept
 *
 *     data = connection.gets
 *
 *     response = "I got #{data.dump}"
 *     puts response
 *
 *     connection.puts "I got #{data.dump}"
 *     connection.close
 *   end
 *
 * === SSL client
 *
 * An SSL client is created with a TCP socket and the context.
 * SSLSocket#connect must be called to initiate the SSL handshake and start
 * encryption.  A key and certificate are not required for the client socket.
 *
 *   require 'socket'
 *
 *   tcp_client = TCPSocket.new 'localhost', 5000
 *   ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
 *   ssl_client.connect
 *
 *   ssl_client.puts "hello server!"
 *   puts ssl_client.gets
 *
 * === Peer Verification
 *
 * An unverified SSL connection does not provide much security.  For enhanced
 * security the client or server can verify the certificate of its peer.
 *
 * The client can be modified to verify the server's certificate against the
 * certificate authority's certificate:
 *
 *   context.ca_file = 'ca_cert.pem'
 *   context.verify_mode = OpenSSL::SSL::VERIFY_PEER
 *
 *   require 'socket'
 *
 *   tcp_client = TCPSocket.new 'localhost', 5000
 *   ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
 *   ssl_client.connect
 *
 *   ssl_client.puts "hello server!"
 *   puts ssl_client.gets
 *
 * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
 * when verifying peers an OpenSSL::SSL::SSLError will be raised.
 *
 */
void
Init_openssl(void)
{
    /*
     * Init timezone info
     */
#if 0
    tzset();
#endif

    /*
     * Init all digests, ciphers
     */
    /* CRYPTO_malloc_init(); */
    /* ENGINE_load_builtin_engines(); */
    OpenSSL_add_ssl_algorithms();
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    SSL_load_error_strings();

    /*
     * FIXME:
     * On unload do:
     */
#if 0
    CONF_modules_unload(1);
    destroy_ui_method();
    EVP_cleanup();
    ENGINE_cleanup();
    CRYPTO_cleanup_all_ex_data();
    ERR_remove_state(0);
    ERR_free_strings();
#endif

    /*
     * Init main module
     */
    mOSSL = rb_define_module("OpenSSL");
    rb_global_variable(&mOSSL);

    /*
     * OpenSSL ruby extension version
     */
    rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));

    /*
     * Version of OpenSSL the ruby OpenSSL extension was built with
     */
    rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));

    /*
     * Version of OpenSSL the ruby OpenSSL extension is running with
     */
    rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION)));

    /*
     * Version number of OpenSSL the ruby OpenSSL extension was built with
     * (base 16)
     */
    rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));

    /*
     * Boolean indicating whether OpenSSL is FIPS-enabled or not
     */
#ifdef HAVE_OPENSSL_FIPS
    rb_define_const(mOSSL, "OPENSSL_FIPS", Qtrue);
#else
    rb_define_const(mOSSL, "OPENSSL_FIPS", Qfalse);
#endif
    rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1);

    /*
     * Generic error,
     * common for all classes under OpenSSL module
     */
    eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
    rb_global_variable(&eOSSLError);

    /*
     * Verify callback Proc index for ext-data
     */
    if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
        ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");

    /*
     * Init debug core
     */
    dOSSL = Qfalse;
    rb_global_variable(&dOSSL);

    rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
    rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
    rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);

    /*
     * Get ID of to_der
     */
    ossl_s_to_der = rb_intern("to_der");

    Init_ossl_locks();

    /*
     * Init components
     */
    Init_ossl_bn();
    Init_ossl_cipher();
    Init_ossl_config();
    Init_ossl_digest();
    Init_ossl_hmac();
    Init_ossl_ns_spki();
    Init_ossl_pkcs12();
    Init_ossl_pkcs7();
    Init_ossl_pkcs5();
    Init_ossl_pkey();
    Init_ossl_rand();
    Init_ossl_ssl();
    Init_ossl_x509();
    Init_ossl_ocsp();
    Init_ossl_engine();
    Init_ossl_asn1();
}
Exemple #7
0
void hcrypt_library_exit(void)
{
	ERR_free_strings();
	EVP_cleanup();
}
Exemple #8
0
int main(int argc, char** argv) {
  s32 opt;
  u32 loop_cnt = 0, purge_age = 0, seed;
  u8 show_once = 0, no_statistics = 0, display_mode = 0, has_fake = 0;
  s32 oindex = 0;
  u8 *wordlist = NULL, *output_dir = NULL;
  u8* gtimeout_str = NULL;
  u32 gtimeout = 0;

  struct termios term;
  struct timeval tv;
  u64 st_time, en_time;

  signal(SIGINT, ctrlc_handler);
  signal(SIGWINCH, resize_handler);
  signal(SIGPIPE, SIG_IGN);
  SSL_library_init();

/* Options, options, and options */

  static struct option long_options[] = {
    {"auth", required_argument, 0, 'A' },
    {"host", required_argument, 0, 'F' },
    {"cookie", required_argument, 0, 'C' },
    {"reject-cookies", required_argument, 0, 'N' },
    {"header", required_argument, 0, 'H' },
    {"user-agent", required_argument, 0, 'b' },
#ifdef PROXY_SUPPORT
    {"proxy", required_argument, 0, 'J' },
#endif /* PROXY_SUPPORT */
    {"max-depth", required_argument, 0, 'd' },
    {"max-child", required_argument, 0, 'c' },
    {"max-descendants", required_argument, 0, 'x' },
    {"max-requests", required_argument, 0, 'r' },
    {"max-rate", required_argument, 0, 'l'},
    {"probability", required_argument, 0, 'p' },
    {"seed", required_argument, 0, 'q' },
    {"include", required_argument, 0, 'I' },
    {"exclude", required_argument, 0, 'X' },
    {"skip-param", required_argument, 0, 'K' },
    {"skip-forms", no_argument, 0, 'O' },
    {"include-domain", required_argument, 0, 'D' },
    {"ignore-links", no_argument, 0, 'P' },
    {"no-ext-fuzzing", no_argument, 0, 'Y' },
    {"log-mixed-content", no_argument, 0, 'M' },
    {"skip-error-pages", no_argument, 0, 'Z' },
    {"log-external-urls", no_argument, 0, 'U' },
    {"log-cache-mismatches", no_argument, 0, 'E' },
    {"form-value", no_argument, 0, 'T' },
    {"rw-wordlist", required_argument, 0, 'W' },
    {"no-keyword-learning", no_argument, 0, 'L' },
    {"mode", required_argument, 0, 'J' },
    {"wordlist", required_argument, 0, 'S'},
    {"trust-domain", required_argument, 0, 'B' },
    {"max-connections", required_argument, 0, 'g' },
    {"max-host-connections", required_argument, 0, 'm' },
    {"max-fail", required_argument, 0, 'f' },
    {"request-timeout", required_argument, 0, 't' },
    {"network-timeout", required_argument, 0, 'w' },
    {"idle-timeout", required_argument, 0, 'i' },
    {"response-size", required_argument, 0, 's' },
    {"discard-binary", required_argument, 0, 'e' },
    {"output", required_argument, 0, 'o' },
    {"help", no_argument, 0, 'h' },
    {"quiet", no_argument, 0, 'u' },
    {"verbose", no_argument, 0, 'v' },
    {"scan-timeout", required_argument, 0, 'k'},
    {"checks", no_argument, 0, 0},
    {"checks-toggle", required_argument, 0, 0},
    {"no-checks", no_argument, 0, 0},
    {0, 0, 0, 0 }

  };
  /* Come up with a quasi-decent random seed. */

  gettimeofday(&tv, NULL);
  seed = tv.tv_usec ^ (tv.tv_sec << 16) ^ getpid();

  SAY("skipfish version " VERSION " by <[email protected]>\n");

  while ((opt = getopt_long(argc, argv,
          "+A:B:C:D:EF:G:H:I:J:K:LMNOPQR:S:T:UW:X:YZ"
	  "b:c:d:ef:g:hi:k:l:m:o:p:q:r:s:t:uvw:x:",
          long_options, &oindex)) >= 0)

    switch (opt) {

      case 'A': {
          u8* x = (u8*)strchr(optarg, ':');
          if (!x) FATAL("Credentials must be in 'user:pass' form.");
          *(x++) = 0;
          auth_user = (u8*)optarg;
          auth_pass = x;
          auth_type = AUTH_BASIC;
          break;
        }

#ifdef PROXY_SUPPORT
      case 'J':  {
          u8* x = (u8*)strchr(optarg, ':');
          if (!x) FATAL("Proxy data must be in 'host:port' form.");
          *(x++) = 0;
          use_proxy = (u8*)optarg;
          use_proxy_port = atoi((char*)x);
          if (!use_proxy_port) FATAL("Incorrect proxy port number.");
          break;
        }
#endif /* PROXY_SUPPORT */

      case 'F': {
          u8* x = (u8*)strchr(optarg, '=');
          u32 fake_addr;
          if (!x) FATAL("Fake mappings must be in 'host=IP' form.");
          *x = 0;
          fake_addr = inet_addr((char*)x + 1);
          if (fake_addr == (u32)-1)
            FATAL("Could not parse IP address '%s'.", x + 1);
          fake_host((u8*)optarg, fake_addr);
          has_fake = 1;
          break;
        }

      case 'H': {
          u8* x = (u8*)strchr(optarg, '=');
          if (!x) FATAL("Extra headers must be in 'name=value' form.");
          *x = 0;
          if (!strcasecmp(optarg, "Cookie"))
            FATAL("Do not use -H to set cookies (try -C instead).");
          SET_HDR((u8*)optarg, x + 1, &global_http_par);
          break;
        }

      case 'C': {
          u8* x = (u8*)strchr(optarg, '=');
          if (!x) FATAL("Cookies must be in 'name=value' form.");
          if (strchr(optarg, ';'))
            FATAL("Split multiple cookies into separate -C options.");
          *x = 0;
          SET_CK((u8*)optarg, x + 1, &global_http_par);
          break;
        }

      case 'D':
        if (*optarg == '*') optarg++;
        APPEND_FILTER(allow_domains, num_allow_domains, optarg);
        break;

      case 'K':
        APPEND_FILTER(skip_params, num_skip_params, optarg);
        break;

      case 'B':
        if (*optarg == '*') optarg++;
        APPEND_FILTER(trust_domains, num_trust_domains, optarg);
        break;

      case 'I':
        if (*optarg == '*') optarg++;
        APPEND_FILTER(allow_urls, num_allow_urls, optarg);
        break;

      case 'X':
        if (*optarg == '*') optarg++;
        APPEND_FILTER(deny_urls, num_deny_urls, optarg);
        break;

      case 'T': {
          u8* x = (u8*)strchr(optarg, '=');
          if (!x) FATAL("Rules must be in 'name=value' form.");
          *x = 0;
          add_form_hint((u8*)optarg, x + 1);
          break;
        }

      case 'N':
        ignore_cookies = 1;
        break;

      case 'Y':
        no_fuzz_ext = 1;
        break;

      case 'q':
        if (sscanf(optarg, "0x%08x", &seed) != 1)
          FATAL("Invalid seed format.");
        srandom(seed);
        break;

      case 'Q':
        suppress_dupes = 1;
        break;

      case 'P':
        no_parse = 1;
        break;

      case 'M':
        warn_mixed = 1;
        break;

      case 'U':
        log_ext_urls = 1;
        break;

      case 'L':
        dont_add_words = 1;
        break;

      case 'E':
        pedantic_cache = 1;
        break;

      case 'O':
        no_forms = 1;
        break;

      case 'R':
        purge_age = atoi(optarg);
        if (purge_age < 3) FATAL("Purge age invalid or too low (min 3).");
        break;

      case 'd':
        max_depth = atoi(optarg);
        if (max_depth < 2) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'c':
        max_children = atoi(optarg);
        if (!max_children) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'x':
        max_descendants = atoi(optarg);
        if (!max_descendants) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'p':
        crawl_prob = atoi(optarg);
        if (!crawl_prob) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'W':
        if (wordlist)
          FATAL("Only one -W parameter permitted (use -S to load supplemental dictionaries).");

        if (!strcmp(optarg, "-")) wordlist = (u8*)"/dev/null";
        else wordlist = (u8*)optarg;

        break;

      case 'S':
        load_keywords((u8*)optarg, 1, 0);
        break;

      case 'b':
        if (optarg[0] == 'i') browser_type = BROWSER_MSIE; else
        if (optarg[0] == 'f') browser_type = BROWSER_FFOX; else
        if (optarg[0] == 'p') browser_type = BROWSER_PHONE; else
          usage(argv[0]);
        break;

      case 'g':
        max_connections = atoi(optarg);
        if (!max_connections) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'm':
        max_conn_host = atoi(optarg);
        if (!max_conn_host) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'G':
        max_guesses = atoi(optarg);
        if (!max_guesses) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'r':
        max_requests = atoi(optarg);
        if (!max_requests) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'l':
        max_requests_sec = atof(optarg);
        if (!max_requests_sec) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'f':
        max_fail = atoi(optarg);
        if (!max_fail) FATAL("Invalid value '%s'.", optarg);
        break;

      case 't':
        resp_tmout = atoi(optarg);
        if (!resp_tmout) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'w':
        rw_tmout = atoi(optarg);
        if (!rw_tmout) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'i':
        idle_tmout = atoi(optarg);
        if (!idle_tmout) FATAL("Invalid value '%s'.", optarg);
        break;

      case 's':
        size_limit = atoi(optarg);
        if (!size_limit) FATAL("Invalid value '%s'.", optarg);
        break;

      case 'o':
        if (output_dir) FATAL("Multiple -o options not allowed.");
        output_dir = (u8*)optarg;

        rmdir(optarg);

        if (mkdir(optarg, 0755))
          PFATAL("Unable to create '%s'.", output_dir);

        break;

      case 'u':
        no_statistics = 1;
        break;

      case 'v':
        verbosity++;
        break;


      case 'e':
        delete_bin = 1;
        break;

      case 'k':
        if (gtimeout_str) FATAL("Multiple -k options not allowed.");
        gtimeout_str = (u8*)optarg;
        break;

      case 'Z':
        no_500_dir = 1;
        break;

      case '?':
        PFATAL("Unrecognized option.");
	break;

      case 0:
        if(!strcmp( "checks", long_options[oindex].name ))
          display_injection_checks();
        if(!strcmp( "checks-toggle", long_options[oindex].name ))
          toggle_injection_checks((u8*)optarg, 1);
        if(!strcmp( "no-checks", long_options[oindex].name ))
          no_checks = 1;

        break;

      default:
        usage(argv[0]);

  }

#ifdef PROXY_SUPPORT
  if (has_fake && use_proxy)
    FATAL("-F and -J should not be used together.");
#endif /* PROXY_SUPPORT */

  if (access(ASSETS_DIR "/index.html", R_OK))
    PFATAL("Unable to access '%s/index.html' - wrong directory?", ASSETS_DIR);

  srandom(seed);

  if (optind == argc)
    FATAL("Scan target not specified (try -h for help).");

  if (!output_dir)
    FATAL("Output directory not specified (try -h for help).");

  if(verbosity && !no_statistics && isatty(2))
    FATAL("Please use -v in combination with the -u flag or, "
          "run skipfish while redirecting stderr to a file. ");


  if (resp_tmout < rw_tmout) 
    resp_tmout = rw_tmout;

  if (max_connections < max_conn_host)
    max_connections = max_conn_host;

  /* Parse the timeout string - format h:m:s */
  if (gtimeout_str) {
    int i = 0;
    int m[3] = { 1, 60, 3600 };

    u8* tok = (u8*)strtok((char*)gtimeout_str, ":");

    while(tok && i <= 2) {
      gtimeout += atoi((char*)tok) * m[i];
      tok = (u8*)strtok(NULL, ":");
      i++;
    }

    if(!gtimeout)
      FATAL("Wrong timeout format, please use h:m:s (hours, minutes, seconds)");
    DEBUG("* Scan timeout is set to %d seconds\n", gtimeout);
  }


  if (!wordlist) {
    wordlist = (u8*)"/dev/null";
    DEBUG("* No wordlist specified with -W defaulting to /dev/null..\n");
  }

  load_keywords(wordlist, 0, purge_age);

  /* Schedule all URLs in the command line for scanning. */

  while (optind < argc) {

    struct http_request *req;

    /* Support @ notation for reading URL lists from files. */

    if (argv[optind][0] == '@') {
      read_urls((u8*)argv[optind++] + 1);
      continue;
    }

    req = ck_alloc(sizeof(struct http_request));

    if (parse_url((u8*)argv[optind], req, NULL))
      FATAL("Scan target '%s' is not a valid absolute URL.", argv[optind]);

    if (!url_allowed_host(req))
      APPEND_FILTER(allow_domains, num_allow_domains,
                    __DFL_ck_strdup(req->host));

    if (!url_allowed(req))
      FATAL("URL '%s' explicitly excluded by -I / -X rules.", argv[optind]);

    maybe_add_pivot(req, NULL, 2);
    destroy_request(req);

    optind++;
  }

  /* Char-by char stdin. */

  tcgetattr(0, &term);
  term.c_lflag &= ~ICANON;
  tcsetattr(0, TCSANOW, &term);
  fcntl(0, F_SETFL, O_NONBLOCK);

  gettimeofday(&tv, NULL);
  st_time = tv.tv_sec * 1000LL + tv.tv_usec / 1000;

#ifdef SHOW_SPLASH
  if (!no_statistics) splash_screen();
#endif /* SHOW_SPLASH */

  if (!no_statistics) SAY("\x1b[H\x1b[J");
  else SAY(cLGN "[*] " cBRI "Scan in progress, please stay tuned...\n");

  /* Enter the crawler loop */
  while ((next_from_queue() && !stop_soon) || (!show_once++)) {

    u8 keybuf[8];

    u64 end_time;
    u64 run_time;
    struct timeval tv_tmp;

    gettimeofday(&tv_tmp, NULL);
    end_time = tv_tmp.tv_sec * 1000LL + tv_tmp.tv_usec / 1000;

    run_time = end_time - st_time;
    if (gtimeout > 0 && run_time && run_time/1000 > gtimeout) {
      DEBUG("* Stopping scan due to timeout\n");
      stop_soon = 1;
    }

    req_sec = (req_count - queue_cur / 1.15) * 1000 / (run_time + 1);

    if (no_statistics || ((loop_cnt++ % 100) && !show_once && idle == 0))
      continue;

    if (clear_screen) {
      SAY("\x1b[H\x1b[2J");
      clear_screen = 0;
    }

    SAY(cYEL "\x1b[H"
           "skipfish version " VERSION " by <[email protected]>\n\n"
           cBRI "  -" cPIN " %s " cBRI "-\n\n" cNOR, 
           allow_domains[0]);


    if (!display_mode) {
      http_stats(st_time);
      SAY("\n");
      database_stats();
    } else {
      http_req_list();
    }

    SAY("        \r");

    if (fread(keybuf, 1, sizeof(keybuf), stdin) > 0) {
      display_mode ^= 1;
      clear_screen = 1;
    }

  }

  gettimeofday(&tv, NULL);
  en_time = tv.tv_sec * 1000LL + tv.tv_usec / 1000;

  SAY("\n");

  if (stop_soon)
    SAY(cYEL "[!] " cBRI "Scan aborted by user, bailing out!" cNOR "\n");

  term.c_lflag |= ICANON;
  tcsetattr(0, TCSANOW, &term);
  fcntl(0, F_SETFL, O_SYNC);

  save_keywords((u8*)wordlist);

  write_report(output_dir, en_time - st_time, seed);

#ifdef LOG_STDERR
  SAY("\n== PIVOT DEBUG ==\n");
  dump_pivots(0, 0);
  SAY("\n== END OF DUMP ==\n\n");
#endif /* LOG_STDERR */

  SAY(cLGN "[+] " cBRI "This was a great day for science!" cRST "\n\n");

#ifdef DEBUG_ALLOCATOR
  if (!stop_soon) {
    destroy_database();
    destroy_http();
    destroy_signatures();
    __TRK_report();
  }
#endif /* DEBUG_ALLOCATOR */

  fflush(0);

  EVP_cleanup();
  CRYPTO_cleanup_all_ex_data();

  return 0;

}
Exemple #9
0
int main(int argc, char *argv[])
{
    /* Set up the key and iv. Do I need to say to not hard code these in a
     * real application? :-)
     */

    /* A 256 bit key */
    unsigned char key[AES_KEY_LENGTH] = { '\0' };

    /* A 128 bit IV */
    unsigned char iv[AES_IV_LENGTH] = { '\0' };


    /* Message to be encrypted */
    unsigned char *plaintext = NULL;

    /* Buffer for ciphertext. Ensure the buffer is long enough for the
     * ciphertext which may be longer than the plaintext, dependant on the
     * algorithm and mode
     */
    unsigned char *ciphertext = NULL;

    int plaintext_len = 0;
    int ciphertext_len = 0;

    int i = 0, rem = 0, num_of_blocks = 0;

    printf("AES file encryption tool.  Written by Kevin Neale 2015\n\n");

    if (argc < 5 || !argv[1] || !argv[2] || !argv[3] || !argv[4]) {
    printf("Usage: ./encrypt <in> <out> <key> <iv>\n\n");
    printf ("    <in>         - Filepath to the file to be encrypted\n");
    printf("    <out>        - Filepath to the file which will contain the encrypted data\n\n");
    printf ("    <key>        - 256 bit key to be used for the encryption represented as a 64 character hex string\n");
    printf("                   e.g. 471C6ABB3CAD5CD41509F961EDD3A2E08E76F61FF6D63412B79E9D500257A06A\n\n");
    printf("    <iv>         - 128 bit initialisation vector to be used for the encryption represented as a 32 character hex string\n");
    printf("                   e.g. 743D32B3BEDEEAF5\n\n");
    exit(EXIT_FAILURE);
    }

    //Open the input file
    FILE *in = fopen(argv[1], "r");

    if (!in) {
        printf("Error! Could not open input file\n");
        exit(EXIT_FAILURE);
    }
    //Open the output file
    FILE *out = fopen(argv[2], "w");


    if (!out) {
        printf("Error! Could not open output file\n");
        exit(EXIT_FAILURE);
    }
    //Get key and iv
    if (get_key(argv[3], key) != 0 || get_iv(argv[4], iv) != 0) {
        printf("Error! Bad parameters\n");
        exit(EXIT_FAILURE);
    }
    //Prepare input buffer

    //Determine lenght of the input and allocate a buffer to store it.
    fseek(in, 0L, SEEK_END);
    plaintext_len = ftell(in);

    printf("length of plaintext: %d\n", plaintext_len);
    fseek(in, 0L, SEEK_SET);

    if (plaintext_len <= 0) {
        printf("Error! Input file is empty\n");
        exit(EXIT_FAILURE);
    }

    plaintext = malloc(sizeof(char) * plaintext_len);

    if (!plaintext) {
        printf("Error! Could not allocate memory for input buffer\n");
        exit(EXIT_FAILURE);
    }

    memset(plaintext, '\0', sizeof(char) * plaintext_len);

    //Read the file data into the input buffer
    fread(plaintext, 1, plaintext_len, in);


    //Prepare the output buffer 
    //Calculate the length of the input data in blocks (128 bit (32 bytes) for AES).
    rem = plaintext_len % AES_BLOCK_SIZE;
    num_of_blocks = (plaintext_len - rem) / AES_BLOCK_SIZE;

    if (rem != 0) {
        num_of_blocks++;    //Add an extra block as the the input data is not an exact multiple of blocks.
    }

    ciphertext_len = num_of_blocks * AES_BLOCK_SIZE;    //Total memory to allocate is num of blocks times block size

    printf("number of blocks: %d\ntotal buffer to allocate: %d\n",num_of_blocks, ciphertext_len);

    ciphertext = malloc(sizeof(char) * ciphertext_len);

    if (!ciphertext) {
        printf("Error! Could not allocate memory for output buffer\n");
        exit(EXIT_FAILURE);
    }

    memset(ciphertext, '\0', sizeof(char) * ciphertext_len);


    /* Encrypt the plaintext */
    ciphertext_len =
    encrypt(plaintext, plaintext_len, key, iv, ciphertext);

    printf("length of ciphertext: %d\n", ciphertext_len);

    for (i = 0; i < ciphertext_len; i++) {
        fwrite(&ciphertext[i], sizeof(unsigned char), 1, out);
    }

    sync();         //Force output flush

    free(plaintext);
    free(ciphertext);

    fclose(in);
    fclose(out);

    /* Clean up */
    EVP_cleanup();
    ERR_free_strings();

    return 0;
}
Exemple #10
0
int
main(int argc, char **argv)
{
  int i;
  sigset_t set;
#if ENABLE_MPEGTS
  uint32_t adapter_mask = 0;
#endif
  int  log_level   = LOG_INFO;
  int  log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG;
  const char *log_debug = NULL, *log_trace = NULL;
  gid_t gid = -1;
  uid_t uid = -1;
  char buf[512];
  FILE *pidfile = NULL;
  static struct {
    void *thread_id;
    struct timeval tv;
    uint8_t ru[32];
  } randseed;
  extern int dvb_bouquets_parse;

  main_tid = pthread_self();

  /* Setup global mutexes */
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);
  pthread_mutex_init(&tasklet_lock, NULL);
  pthread_mutex_init(&atomic_lock, NULL);
  pthread_cond_init(&gtimer_cond, NULL);
  pthread_cond_init(&tasklet_cond, NULL);
  TAILQ_INIT(&tasklets);

  /* Defaults */
  tvheadend_webui_port      = 9981;
  tvheadend_webroot         = NULL;
  tvheadend_htsp_port       = 9982;
  tvheadend_htsp_port_extra = 0;
  time(&dispatch_clock);

  /* Command line options */
  int         opt_help         = 0,
              opt_version      = 0,
              opt_fork         = 0,
              opt_firstrun     = 0,
              opt_stderr       = 0,
              opt_syslog       = 0,
              opt_nosyslog     = 0,
              opt_uidebug      = 0,
              opt_abort        = 0,
              opt_noacl        = 0,
              opt_fileline     = 0,
              opt_threadid     = 0,
              opt_libav        = 0,
              opt_ipv6         = 0,
              opt_nosatip      = 0,
              opt_satip_rtsp   = 0,
#if ENABLE_TSFILE
              opt_tsfile_tuner = 0,
#endif
              opt_dump         = 0,
              opt_xspf         = 0,
              opt_dbus         = 0,
              opt_dbus_session = 0,
              opt_nobackup     = 0,
              opt_nobat        = 0;
  const char *opt_config       = NULL,
             *opt_user         = NULL,
             *opt_group        = NULL,
             *opt_logpath      = NULL,
             *opt_log_debug    = NULL,
             *opt_log_trace    = NULL,
             *opt_pidpath      = "/var/run/tvheadend.pid",
#if ENABLE_LINUXDVB
             *opt_dvb_adapters = NULL,
#endif
             *opt_bindaddr     = NULL,
             *opt_subscribe    = NULL,
             *opt_user_agent   = NULL;
  str_list_t  opt_satip_xml    = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  str_list_t  opt_tsfile       = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  cmdline_opt_t cmdline_opts[] = {
    {   0, NULL,        N_("Generic options"),         OPT_BOOL, NULL         },
    { 'h', "help",      N_("Show this page"),          OPT_BOOL, &opt_help    },
    { 'v', "version",   N_("Show version information"),OPT_BOOL, &opt_version },

    {   0, NULL,        N_("Service configuration"),   OPT_BOOL, NULL         },
    { 'c', "config",    N_("Alternate configuration path"), OPT_STR,  &opt_config  },
    { 'B', "nobackup",  N_("Don't backup configuration tree at upgrade"), OPT_BOOL, &opt_nobackup },
    { 'f', "fork",      N_("Fork and run as daemon"),  OPT_BOOL, &opt_fork    },
    { 'u', "user",      N_("Run as user"),             OPT_STR,  &opt_user    },
    { 'g', "group",     N_("Run as group"),            OPT_STR,  &opt_group   },
    { 'p', "pid",       N_("Alternate PID path"),      OPT_STR,  &opt_pidpath },
    { 'C', "firstrun",  N_("If no user account exists then create one with\n"
	                   "no username and no password. Use with care as\n"
	                   "it will allow world-wide administrative access\n"
	                   "to your Tvheadend installation until you create or edit\n"
	                   "the access control from within the Tvheadend web interface."),
      OPT_BOOL, &opt_firstrun },
#if ENABLE_DBUS_1
    { 'U', "dbus",      N_("Enable DBus"),
      OPT_BOOL, &opt_dbus },
    { 'e', "dbus_session", N_("DBus - use the session message bus instead of the system one"),
      OPT_BOOL, &opt_dbus_session },
#endif
#if ENABLE_LINUXDVB
    { 'a', "adapters",  N_("Only use specified DVB adapters (comma separated, -1 = none)"),
      OPT_STR, &opt_dvb_adapters },
#endif
#if ENABLE_SATIP_SERVER
    {   0, "satip_rtsp", N_("SAT>IP RTSP port number for server\n"
                            "(default: -1 = disable, 0 = webconfig, standard port is 554)"),
      OPT_INT, &opt_satip_rtsp },
#endif
#if ENABLE_SATIP_CLIENT
    {   0, "nosatip",    N_("Disable SAT>IP client"),
      OPT_BOOL, &opt_nosatip },
    {   0, "satip_xml",  N_("URL with the SAT>IP server XML location"),
      OPT_STR_LIST, &opt_satip_xml },
#endif
    {   0, NULL,         N_("Server connectivity"),    OPT_BOOL, NULL         },
    { '6', "ipv6",       N_("Listen on IPv6"),         OPT_BOOL, &opt_ipv6    },
    { 'b', "bindaddr",   N_("Specify bind address"),   OPT_STR,  &opt_bindaddr},
    {   0, "http_port",  N_("Specify alternative http port"),
      OPT_INT, &tvheadend_webui_port },
    {   0, "http_root",  N_("Specify alternative http webroot"),
      OPT_STR, &tvheadend_webroot },
    {   0, "htsp_port",  N_("Specify alternative htsp port"),
      OPT_INT, &tvheadend_htsp_port },
    {   0, "htsp_port2", N_("Specify extra htsp port"),
      OPT_INT, &tvheadend_htsp_port_extra },
    {   0, "useragent",  N_("Specify User-Agent header for the http client"),
      OPT_STR, &opt_user_agent },
    {   0, "xspf",       N_("Use XSPF playlist instead of M3U"),
      OPT_BOOL, &opt_xspf },

    {   0, NULL,        N_("Debug options"),           OPT_BOOL, NULL         },
    { 'd', "stderr",    N_("Enable debug on stderr"),  OPT_BOOL, &opt_stderr  },
    { 's', "syslog",    N_("Enable debug to syslog"),  OPT_BOOL, &opt_syslog  },
    { 'S', "nosyslog",  N_("Disable syslog (all messages)"), OPT_BOOL, &opt_nosyslog },
    { 'l', "logfile",   N_("Enable debug to file"),    OPT_STR,  &opt_logpath },
    {   0, "debug",     N_("Enable debug subsystems"),  OPT_STR,  &opt_log_debug },
#if ENABLE_TRACE
    {   0, "trace",     N_("Enable trace subsystems"), OPT_STR,  &opt_log_trace },
#endif
    {   0, "fileline",  N_("Add file and line numbers to debug"), OPT_BOOL, &opt_fileline },
    {   0, "threadid",  N_("Add the thread ID to debug"), OPT_BOOL, &opt_threadid },
#if ENABLE_LIBAV
    {   0, "libav",     N_("More verbose libav log"),  OPT_BOOL, &opt_libav },
#endif
    {   0, "uidebug",   N_("Enable web UI debug (non-minified JS)"), OPT_BOOL, &opt_uidebug },
    { 'A', "abort",     N_("Immediately abort"),       OPT_BOOL, &opt_abort   },
    { 'D', "dump",      N_("Enable coredumps for daemon"), OPT_BOOL, &opt_dump },
    {   0, "noacl",     N_("Disable all access control checks"),
      OPT_BOOL, &opt_noacl },
    {   0, "nobat",     N_("Disable DVB bouquets"),
      OPT_BOOL, &opt_nobat },
    { 'j', "join",      N_("Subscribe to a service permanently"),
      OPT_STR, &opt_subscribe },


#if ENABLE_TSFILE || ENABLE_TSDEBUG
    { 0, NULL, N_("Testing options"), OPT_BOOL, NULL },
    { 0, "tsfile_tuners", N_("Number of tsfile tuners"), OPT_INT, &opt_tsfile_tuner },
    { 0, "tsfile", N_("tsfile input (mux file)"), OPT_STR_LIST, &opt_tsfile },
#endif
#if ENABLE_TSDEBUG
    { 0, "tsdebug", N_("Output directory for tsdebug"), OPT_STR, &tvheadend_tsdebug },
#endif

  };

  /* Get current directory */
  tvheadend_cwd0 = dirname(tvh_strdupa(argv[0]));
  tvheadend_cwd = dirname(tvh_strdupa(tvheadend_cwd0));

  /* Set locale */
  setlocale(LC_ALL, "");
  setlocale(LC_NUMERIC, "C");
  tvh_gettext_init();

  /* make sure the timezone is set */
  tzset();

  /* Process command line */
  for (i = 1; i < argc; i++) {

    /* Find option */
    cmdline_opt_t *opt
      = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]);
    if (!opt) {
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 _("invalid option specified [%s]"), argv[i]);
      continue;
    }

    /* Process */
    if (opt->type == OPT_BOOL)
      *((int*)opt->param) = 1;
    else if (++i == argc)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 _("option %s requires a value"), opt->lopt);
    else if (opt->type == OPT_INT)
      *((int*)opt->param) = atoi(argv[i]);
    else if (opt->type == OPT_STR_LIST) {
      str_list_t *strl = opt->param;
      if (strl->num < strl->max)
        strl->str[strl->num++] = argv[i];
    }
    else
      *((char**)opt->param) = argv[i];

    /* Stop processing */
    if (opt_help)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL);
    if (opt_version)
      show_version(argv[0]);
  }

  /* Additional cmdline processing */
  if (opt_nobat)
    dvb_bouquets_parse = 0;
#if ENABLE_LINUXDVB
  if (!opt_dvb_adapters) {
    adapter_mask = ~0;
  } else {
    char *p, *e;
    char *r = NULL;
    char *dvb_adapters = strdup(opt_dvb_adapters);
    adapter_mask = 0x0;
    i = 0;
    p = strtok_r(dvb_adapters, ",", &r);
    while (p) {
      int a = strtol(p, &e, 10);
      if (*e != 0 || a > 31) {
        fprintf(stderr, _("Invalid adapter number '%s'\n"), p);
        free(dvb_adapters);
        return 1;
      }
      i = 1;
      if (a < 0)
        adapter_mask = 0;
      else
        adapter_mask |= (1 << a);
      p = strtok_r(NULL, ",", &r);
    }
    free(dvb_adapters);
    if (!i) {
      fprintf(stderr, "%s", _("No adapters specified!\n"));
      return 1;
    }
  }
#endif
  if (tvheadend_webroot) {
    char *tmp;
    if (*tvheadend_webroot == '/')
      tmp = strdup(tvheadend_webroot);
    else {
      tmp = malloc(strlen(tvheadend_webroot)+2);
      *tmp = '/';
      strcpy(tmp+1, tvheadend_webroot);
    }
    if (tmp[strlen(tmp)-1] == '/')
      tmp[strlen(tmp)-1] = '\0';
    tvheadend_webroot = tmp;
  }
  tvheadend_webui_debug = opt_uidebug;

  /* Setup logging */
  if (isatty(2))
    log_options |= TVHLOG_OPT_DECORATE;
  if (opt_stderr || opt_syslog || opt_logpath) {
    if (!opt_log_trace && !opt_log_debug)
      log_debug      = "all";
    log_level      = LOG_DEBUG;
    if (opt_stderr)
      log_options   |= TVHLOG_OPT_DBG_STDERR;
    if (opt_syslog)
      log_options   |= TVHLOG_OPT_DBG_SYSLOG;
    if (opt_logpath)
      log_options   |= TVHLOG_OPT_DBG_FILE;
  }
  if (opt_nosyslog)
    log_options &= ~(TVHLOG_OPT_SYSLOG|TVHLOG_OPT_DBG_SYSLOG);
  if (opt_fileline)
    log_options |= TVHLOG_OPT_FILELINE;
  if (opt_threadid)
    log_options |= TVHLOG_OPT_THREAD;
  if (opt_libav)
    log_options |= TVHLOG_OPT_LIBAV;
  if (opt_log_trace) {
    log_level  = LOG_TRACE;
    log_trace  = opt_log_trace;
  }
  if (opt_log_debug)
    log_debug  = opt_log_debug;
    
  tvhlog_init(log_level, log_options, opt_logpath);
  tvhlog_set_debug(log_debug);
  tvhlog_set_trace(log_trace);
  tvhinfo("main", "Log started");
 
  signal(SIGPIPE, handle_sigpipe); // will be redundant later
  signal(SIGILL, handle_sigill);   // see handler..

  /* Set priviledges */
  if(opt_fork || opt_group || opt_user) {
    const char *homedir;
    struct group  *grp = getgrnam(opt_group ?: "video");
    struct passwd *pw  = opt_user ? getpwnam(opt_user) : NULL;

    if(grp != NULL) {
      gid = grp->gr_gid;
    } else {
      gid = 1;
    }

    if (pw != NULL) {
      if (getuid() != pw->pw_uid) {
        gid_t glist[16];
        int gnum;
        gnum = get_user_groups(pw, glist, ARRAY_SIZE(glist));
        if (gnum > 0 && setgroups(gnum, glist)) {
          char buf[256] = "";
          int i;
          for (i = 0; i < gnum; i++)
            snprintf(buf + strlen(buf), sizeof(buf) - 1 - strlen(buf),
                     ",%d", glist[i]);
          tvhlog(LOG_ALERT, "START",
                 "setgroups(%s) failed, do you have permission?", buf+1);
          return 1;
        }
      }
      uid     = pw->pw_uid;
      homedir = pw->pw_dir;
      setenv("HOME", homedir, 1);
    } else {
      uid = 1;
    }
  }

  uuid_init();
  config_boot(opt_config, gid, uid);
  tcp_server_preinit(opt_ipv6);
  http_server_init(opt_bindaddr);    // bind to ports only
  htsp_init(opt_bindaddr);	     // bind to ports only
  satip_server_init(opt_satip_rtsp); // bind to ports only

  if (opt_fork)
    pidfile = tvh_fopen(opt_pidpath, "w+");

  if (gid != -1 && (getgid() != gid) && setgid(gid)) {
    tvhlog(LOG_ALERT, "START",
           "setgid(%d) failed, do you have permission?", gid);
    return 1;
  }
  if (uid != -1 && (getuid() != uid) && setuid(uid)) {
    tvhlog(LOG_ALERT, "START",
           "setuid(%d) failed, do you have permission?", uid);
    return 1;
  }

  /* Daemonise */
  if(opt_fork) {
    if(daemon(0, 0)) {
      exit(2);
    }
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

    /* Make dumpable */
    if (opt_dump) {
#ifdef PLATFORM_LINUX
      if (chdir("/tmp"))
        tvhwarn("START", "failed to change cwd to /tmp");
      prctl(PR_SET_DUMPABLE, 1);
#else
      tvhwarn("START", "Coredumps not implemented on your platform");
#endif
    }

    umask(0);
  }

  tvheadend_running = 1;

  /* Start log thread (must be done post fork) */
  tvhlog_start();

  /* Alter logging */
  if (opt_fork)
    tvhlog_options &= ~TVHLOG_OPT_STDERR;
  if (!isatty(2))
    tvhlog_options &= ~TVHLOG_OPT_DECORATE;
  
  /* Initialise clock */
  pthread_mutex_lock(&global_lock);
  time(&dispatch_clock);

  /* Signal handling */
  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);
  trap_init(argv[0]);

  /* SSL library init */
  OPENSSL_config(NULL);
  SSL_load_error_strings();
  SSL_library_init();
  /* Rand seed */
  randseed.thread_id = (void *)main_tid;
  gettimeofday(&randseed.tv, NULL);
  uuid_random(randseed.ru, sizeof(randseed.ru));
  RAND_seed(&randseed, sizeof(randseed));

  /* Initialise configuration */
  notify_init();
  idnode_init();
  spawn_init();
  config_init(opt_nobackup == 0);

  /**
   * Initialize subsystems
   */

  epg_in_load = 1;

  tvhthread_create(&tasklet_tid, NULL, tasklet_thread, NULL, "tasklet");

  dbus_server_init(opt_dbus, opt_dbus_session);

  intlconv_init();
  
  api_init();

  fsmonitor_init();

  libav_init();

  tvhtime_init();

  profile_init();

  imagecache_init();

  http_client_init(opt_user_agent);
  esfilter_init();

  bouquet_init();

  service_init();

  dvb_init();

#if ENABLE_MPEGTS
  mpegts_init(adapter_mask, opt_nosatip, &opt_satip_xml,
              &opt_tsfile, opt_tsfile_tuner);
#endif

  channel_init();

  bouquet_service_resolve();

  subscription_init();

  dvr_config_init();

  access_init(opt_firstrun, opt_noacl);

#if ENABLE_TIMESHIFT
  timeshift_init();
#endif

  tcp_server_init();
  webui_init(opt_xspf);
#if ENABLE_UPNP
  upnp_server_init(opt_bindaddr);
#endif

  service_mapper_init();

  descrambler_init();

  epggrab_init();
  epg_init();

  dvr_init();

  dbus_server_start();

  http_server_register();
  satip_server_register();
  htsp_register();

  if(opt_subscribe != NULL)
    subscription_dummy_join(opt_subscribe, 1);

  avahi_init();
  bonjour_init();

  epg_updated(); // cleanup now all prev ref's should have been created
  epg_in_load = 0;

  pthread_mutex_unlock(&global_lock);

  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
         "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s",
         tvheadend_version,
         getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)),
         hts_settings_get_root());

  if(opt_abort)
    abort();

  mainloop();

#if ENABLE_DBUS_1
  tvhftrace("main", dbus_server_done);
#endif
#if ENABLE_UPNP
  tvhftrace("main", upnp_server_done);
#endif
  tvhftrace("main", satip_server_done);
  tvhftrace("main", htsp_done);
  tvhftrace("main", http_server_done);
  tvhftrace("main", webui_done);
  tvhftrace("main", fsmonitor_done);
  tvhftrace("main", http_client_done);
  tvhftrace("main", tcp_server_done);

  // Note: the locking is obviously a bit redundant, but without
  //       we need to disable the gtimer_arm call in epg_save()
  pthread_mutex_lock(&global_lock);
  tvhftrace("main", epg_save);

#if ENABLE_TIMESHIFT
  tvhftrace("main", timeshift_term);
#endif
  pthread_mutex_unlock(&global_lock);

  tvhftrace("main", epggrab_done);
#if ENABLE_MPEGTS
  tvhftrace("main", mpegts_done);
#endif
  tvhftrace("main", descrambler_done);
  tvhftrace("main", service_mapper_done);
  tvhftrace("main", service_done);
  tvhftrace("main", channel_done);
  tvhftrace("main", bouquet_done);
  tvhftrace("main", dvr_done);
  tvhftrace("main", subscription_done);
  tvhftrace("main", access_done);
  tvhftrace("main", epg_done);
  tvhftrace("main", avahi_done);
  tvhftrace("main", bonjour_done);
  tvhftrace("main", imagecache_done);
  tvhftrace("main", lang_code_done);
  tvhftrace("main", api_done);

  tvhtrace("main", "tasklet enter");
  pthread_cond_signal(&tasklet_cond);
  pthread_join(tasklet_tid, NULL);
  tvhtrace("main", "tasklet thread end");
  tasklet_flush();
  tvhtrace("main", "tasklet leave");

  tvhftrace("main", hts_settings_done);
  tvhftrace("main", dvb_done);
  tvhftrace("main", lang_str_done);
  tvhftrace("main", esfilter_done);
  tvhftrace("main", profile_done);
  tvhftrace("main", intlconv_done);
  tvhftrace("main", urlparse_done);
  tvhftrace("main", idnode_done);
  tvhftrace("main", notify_done);
  tvhftrace("main", spawn_done);

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");
  tvhlog_end();

  tvhftrace("main", config_done);

  if(opt_fork)
    unlink(opt_pidpath);
    
#if ENABLE_TSFILE
  free(opt_tsfile.str);
#endif
  free(opt_satip_xml.str);

  /* OpenSSL - welcome to the "cleanup" hell */
  ENGINE_cleanup();
  RAND_cleanup();
  CRYPTO_cleanup_all_ex_data();
  EVP_cleanup();
  CONF_modules_free();
#ifndef OPENSSL_NO_COMP
  COMP_zlib_cleanup();
#endif
  ERR_remove_state(0);
  ERR_free_strings();
#ifndef OPENSSL_NO_COMP
  sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
#endif
  /* end of OpenSSL cleanup code */

#if ENABLE_DBUS_1
  extern void dbus_shutdown(void);
  if (opt_dbus) dbus_shutdown();
#endif
  tvh_gettext_done();
  return 0;
}

/**
 *
 */
void
tvh_str_set(char **strp, const char *src)
{
  free(*strp);
  *strp = src ? strdup(src) : NULL;
}


/**
 *
 */
int
tvh_str_update(char **strp, const char *src)
{
  if(src == NULL)
    return 0;
  free(*strp);
  *strp = strdup(src);
  return 1;
}


/**
 *
 */
void
scopedunlock(pthread_mutex_t **mtxp)
{
  pthread_mutex_unlock(*mtxp);
}
Exemple #11
0
static void server_free(server *srv) {
	size_t i;

	for (i = 0; i < FILE_CACHE_MAX; i++) {
		buffer_free(srv->mtime_cache[i].str);
	}

#define CLEAN(x) \
	buffer_free(srv->x);

	CLEAN(response_header);
	CLEAN(parse_full_path);
	CLEAN(ts_debug_str);
	CLEAN(ts_date_str);
	CLEAN(errorlog_buf);
	CLEAN(response_range);
	CLEAN(tmp_buf);
	CLEAN(empty_string);
	CLEAN(cond_check_buf);

	CLEAN(srvconf.errorlog_file);
	CLEAN(srvconf.breakagelog_file);
	CLEAN(srvconf.groupname);
	CLEAN(srvconf.username);
	CLEAN(srvconf.changeroot);
	CLEAN(srvconf.bindhost);
	CLEAN(srvconf.event_handler);
	CLEAN(srvconf.pid_file);
	CLEAN(srvconf.modules_dir);
	CLEAN(srvconf.network_backend);

	//- Sungmin add 20111018
	CLEAN(srvconf.arpping_interface);
	CLEAN(srvconf.syslog_file);
	CLEAN(srvconf.product_image);
	CLEAN(srvconf.aicloud_version);
	CLEAN(srvconf.app_installation_url);
	CLEAN(syslog_buf);
	CLEAN(cur_login_info);
	CLEAN(last_login_info);
	
	CLEAN(tmp_chunk_len);
#undef CLEAN

#if 0
	fdevent_unregister(srv->ev, srv->fd);
#endif
	fdevent_free(srv->ev);

	free(srv->conns);

	if (srv->config_storage) {
		for (i = 0; i < srv->config_context->used; i++) {
			specific_config *s = srv->config_storage[i];

			if (!s) continue;

			buffer_free(s->document_root);
			buffer_free(s->server_name);
			buffer_free(s->server_tag);
			buffer_free(s->ssl_pemfile);
			buffer_free(s->ssl_ca_file);
			buffer_free(s->ssl_cipher_list);
			buffer_free(s->ssl_dh_file);
			buffer_free(s->ssl_ec_curve);
			buffer_free(s->error_handler);
			buffer_free(s->errorfile_prefix);
			array_free(s->mimetypes);
			buffer_free(s->ssl_verifyclient_username);
#ifdef USE_OPENSSL
			SSL_CTX_free(s->ssl_ctx);
			EVP_PKEY_free(s->ssl_pemfile_pkey);
			X509_free(s->ssl_pemfile_x509);
			if (NULL != s->ssl_ca_file_cert_names) sk_X509_NAME_pop_free(s->ssl_ca_file_cert_names, X509_NAME_free);
#endif
			free(s);
		}
		free(srv->config_storage);
		srv->config_storage = NULL;
	}

#define CLEAN(x) \
	array_free(srv->x);

	CLEAN(config_context);
	CLEAN(config_touched);
	CLEAN(status);
	CLEAN(srvconf.upload_tempdirs);
#undef CLEAN

	joblist_free(srv, srv->joblist);
	fdwaitqueue_free(srv, srv->fdwaitqueue);

	if (srv->stat_cache) {
		stat_cache_free(srv->stat_cache);
	}

	array_free(srv->srvconf.modules);
	array_free(srv->split_vals);

#ifdef USE_OPENSSL
	if (srv->ssl_is_init) {
		CRYPTO_cleanup_all_ex_data();
		ERR_free_strings();
		ERR_remove_state(0);
		EVP_cleanup();
	}
#endif

	free(srv);
}
main(int argc, char *argv[])
{
    EVP_MD_CTX *mdctx;
    EVP_MD_CTX *mdctxdup;
    const EVP_MD *md;
    const EVP_MD *mddup;
    char mess1[] = "Hello World";
    unsigned char md_value[EVP_MAX_MD_SIZE];
    unsigned char md_valuedup[EVP_MAX_MD_SIZE];
    int md_len,md_lendup, i;
    char originalBinary[24];
    char randomBinary[24];
    OpenSSL_add_all_digests();
    
    if(!argv[1]) {
        printf("Usage: mdtest digestname\n");
        exit(1);
    }
    
    md = EVP_get_digestbyname(argv[1]) ;
    
    if(!md) {
        printf("Unknown message digest %s\n", argv[1]);
        exit(1);
    }
   
    mdctx = EVP_MD_CTX_create();
    EVP_DigestInit_ex(mdctx, md, NULL);
    EVP_DigestUpdate(mdctx, mess1, strlen(mess1));
    EVP_DigestFinal_ex(mdctx, md_value, &md_len);
    EVP_MD_CTX_destroy(mdctx);
    
    printf("Input Original: %s\n",mess1);
    printf("Digest Original: ");
    for(i = 0; i < md_len; i++)
    printf("%02x", md_value[i]);
    printf("\n");
    
int dontExit =1;
char *str ;
    
  while(dontExit)
   {
    str = (char*)malloc(10);
    str = rand_string(str,9);
    mdctxdup = EVP_MD_CTX_create();
    EVP_DigestInit_ex(mdctxdup, md, NULL);
    EVP_DigestUpdate(mdctxdup, str, strlen(str));
    EVP_DigestFinal_ex(mdctxdup, md_valuedup, &md_lendup);
EVP_MD_CTX_destroy(mdctxdup);
    

     if((md_value[0] == md_valuedup[0]) &&  (md_value[1] == md_valuedup[1])  && (md_value[2] == md_valuedup[2]) )
	{
        
	break;
	}
    free(str);
    }
    printf("Input Random: %s\n",str);
    printf("Digest Random: ");
    for(i = 0; i < md_lendup; i++)
    printf("%02x", md_valuedup[i]);
    printf("\n");

    
    /* Call this once before exit. */
    EVP_cleanup();
    exit(0);
}
int main(int argc, char **argv)
{
  unsigned int nb_threads = 1;
  pthread_t *decryption_threads;
  char *filename;
  unsigned int **indexes;
  int fd, i, ret, c;
  struct stat file_stats;

  OpenSSL_add_all_algorithms();

  /* Get options and parameters */
  opterr = 0;
  while((c = getopt(argc, argv, "1aB:b:c:d:e:hL:l:M:m:Ns:t:")) != -1)
    switch(c)
      {
      case '1':
        only_one_password = 1;
        break;

      case 'a':
        list_algorithms();
        exit(EXIT_FAILURE);
        break;

      case 'B':
        binary = optarg;
        break;

      case 'b':
        prefix = optarg;
        break;

      case 'c':
        cipher = EVP_get_cipherbyname(optarg);
        if(cipher == NULL)
          {
            fprintf(stderr, "Error: unknown cipher: %s.\n\n", optarg);
            exit(EXIT_FAILURE);
          }
        break;

      case 'd':
        digest = EVP_get_digestbyname(optarg);
        if(digest == NULL)
          {
            fprintf(stderr, "Error: unknown digest: %s.\n\n", optarg);
            exit(EXIT_FAILURE);
          }
        break;

      case 'e':
        suffix = optarg;
        break;

      case 'h':
        usage(argv[0]);
        exit(EXIT_FAILURE);
        break;

      case 'L':
        limit = (long unsigned int) atol(optarg);
        break;

      case 'l':
        min_len = (unsigned int) atoi(optarg);
        break;

      case 'M':
        magic = optarg;
        break;

      case 'm':
        max_len = (unsigned int) atoi(optarg);
        break;

      case 'N':
        no_error = 1;
        break;

      case 's':
        charset = optarg;
        break;

      case 't':
        nb_threads = (unsigned int) atoi(optarg);
        if(nb_threads == 0)
          nb_threads = 1;
        break;

      default:
        usage(argv[0]);
        switch(optopt)
          {
          case 'B':
          case 'b':
          case 'c':
          case 'd':
          case 'e':
          case 'L':
          case 'l':
          case 'M':
          case 'm':
          case 's':
          case 't':
            fprintf(stderr, "Error: missing argument for option: '-%c'.\n\n", optopt);
            break;

          default:
            fprintf(stderr, "Error: unknown option: '%c'.\n\n", optopt);
            break;
          }
        exit(EXIT_FAILURE);
        break;
      }

  if(optind >= argc)
    {
      usage(argv[0]);
      fprintf(stderr, "Error: missing filename.\n\n");
      exit(EXIT_FAILURE);
    }

  filename = argv[optind];

  /* Check variables */
  if(cipher == NULL)
    cipher = EVP_aes_256_cbc();
  if(digest == NULL)
    digest = EVP_md5();
  if(prefix == NULL)
    prefix = "";
  prefix_len = strlen(prefix);
  if(suffix == NULL)
    suffix = "";
  suffix_len = strlen(suffix);
  if(charset && binary)
    {
      fprintf(stderr, "Error: options -B and -s can't be both set.\n\n");
      exit(EXIT_FAILURE);
    }
  else if(binary)
    charset = binary_charset;
  else if(charset == NULL)
    charset = default_charset;
  charset_len = strlen(charset);
  if(charset_len == 0)
    {
      fprintf(stderr, "Error: charset must have at least one character.\n\n");
      exit(EXIT_FAILURE);
    }
  if(nb_threads > charset_len)
    {
      fprintf(stderr, "Warning: number of threads (%u) bigger than character set length (%u). Only using %u threads.\n\n", nb_threads, charset_len, charset_len);
      nb_threads = charset_len;
    }
  if(min_len < prefix_len + suffix_len + 1)
    {
      fprintf(stderr, "Warning: minimum length (%u) isn't bigger than the length of specified password characters (%u). Setting minimum length to %u.\n\n", min_len, prefix_len + suffix_len, prefix_len + suffix_len + 1);
      min_len = prefix_len + suffix_len + 1;
    }
  if(max_len < min_len)
    {
      fprintf(stderr, "Warning: maximum length (%u) is smaller than minimum length (%u). Setting maximum length to %u.\n\n", max_len, min_len, min_len);
      max_len = min_len;
    }

  /* Check header */
  fd = open(filename, O_RDONLY);
  if(fd == -1)
    {
      perror("open file");
      exit(EXIT_FAILURE);
    }
  memset(salt, 0, sizeof(salt));
  ret = read(fd, salt, 8);
  if(strncmp(salt, "Salted__", 8) != 0)
    {
      close(fd);
      fprintf(stderr, "Error: %s is not a salted openssl file.\n\n", filename);
      exit(EXIT_FAILURE);
    }

  /* Read salt */
  ret = read(fd, salt, 8);
  if(ret != 8)
    {
      close(fd);
      fprintf(stderr, "Error: could not read salt.\n\n");
      exit(EXIT_FAILURE);
    }

  /* Read encrypted data */
  ret = fstat(fd, &file_stats);
  data_len = file_stats.st_size - 16;
  data = (char *) malloc(data_len);
  if(data == NULL)
    {
      fprintf(stderr, "Error: memory allocation failed.\n\n");
      exit(EXIT_FAILURE);
    }
  for(i = 0; i < data_len;)
    {
      ret = read(fd, data + i, data_len - i);
      if(ret == -1)
        {
          close(fd);
          fprintf(stderr, "Error: could not read data.\n\n");
          exit(EXIT_FAILURE);
        }
      else if(ret > 0)
        i += ret;
    }
  close(fd);

  pthread_mutex_init(&found_password_lock, NULL);
  
  /* Start decryption threads */
  decryption_threads = (pthread_t *) malloc(nb_threads * sizeof(pthread_t));
  indexes = (unsigned int **) malloc(nb_threads * sizeof(unsigned int *));
  if((decryption_threads == NULL) || (indexes == NULL))
    {
      fprintf(stderr, "Error: memory allocation failed.\n\n");
      exit(EXIT_FAILURE);
    }
  for(i = 0; i < nb_threads; i++)
    {
      indexes[i] = (unsigned int *) malloc(2 * sizeof(unsigned int));
      if(indexes[i] == NULL)
        {
          fprintf(stderr, "Error: memory allocation failed.\n\n");
          exit(EXIT_FAILURE);
        }
      indexes[i][0] = i * (charset_len / nb_threads);
      if(i == nb_threads - 1)
        indexes[i][1] = charset_len - 1;
      else
        indexes[i][1] = (i + 1) * (charset_len / nb_threads) - 1;
      ret = pthread_create(&decryption_threads[i], NULL, &decryption_func, indexes[i]);
      if(ret != 0)
        {
          perror("decryption thread");
          exit(EXIT_FAILURE);
        }
    }

  for(i = 0; i < nb_threads; i++)
    {
      pthread_join(decryption_threads[i], NULL);
      free(indexes[i]);
    }
  free(indexes);
  free(decryption_threads);
  pthread_mutex_destroy(&found_password_lock);
  free(data);
  EVP_cleanup();

  exit(EXIT_SUCCESS);
}
Exemple #14
0
void apn_ssl_free() {
    ERR_free_strings();
    EVP_cleanup();
}
Exemple #15
0
void R_unload_openssl(DllInfo *info) {
  ERR_free_strings();
  EVP_cleanup();
}
Exemple #16
0
// NOTE: we do not cleanup in reverse initialization order
// the threading subsystem is deleted before the modules are
// unloaded in case there are any module-specific thread
// cleanup functions to be run...
void qore_cleanup() {
   // first delete all user modules
   QMM.delUser();

#ifdef _Q_WINDOWS 
   // do windows socket cleanup
   WSACleanup();
#endif

#ifdef HAVE_SIGNAL_HANDLING
   // stop signal manager
   QSM.del();
#endif

   // purge thread resources before deleting modules
   {
      ExceptionSink xsink;
      purge_thread_resources(&xsink);
   }

   // delete all loadable modules
   QMM.cleanup();

   // delete thread-local data
   delete_thread_local_data();

   // now free memory (like ARGV, QORE_ARGV, ENV, etc)
   delete_global_variables();

   // delete pseudo-methods
   pseudo_classes_del();

   // delete static system namespace after modules
   delete staticSystemNamespace;
#ifdef DEBUG
   staticSystemNamespace = 0;
#endif

   // delete default type values
   delete_qore_types();

   // delete threading infrastructure
   delete_qore_threads();

   // only perform openssl cleanup if not performed externally
   if (!qore_check_option(QLO_DISABLE_OPENSSL_CLEANUP)) {
      // cleanup openssl library
      ERR_free_strings();

      ENGINE_cleanup();
      EVP_cleanup();

      CONF_modules_finish();
      CONF_modules_free();
      CONF_modules_unload(1);

      CRYPTO_cleanup_all_ex_data();

      CRYPTO_set_id_callback(0);
      CRYPTO_set_locking_callback(0);

      // delete openssl locks
      for (mutex_vec_t::iterator i = q_openssl_mutex_list.begin(), e = q_openssl_mutex_list.end(); i != e; ++i)
	 delete *i;
   }
   printd(5, "qore_cleanup() exiting cleanly\n");
}
Exemple #17
0
/*
 * OSSL library init
 */
void
Init_openssl()
{
    /*
     * Init timezone info
     */
#if 0
    tzset();
#endif

    /*
     * Init all digests, ciphers
     */
    /* CRYPTO_malloc_init(); */
    /* ENGINE_load_builtin_engines(); */
    OpenSSL_add_ssl_algorithms();
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();
    SSL_load_error_strings();

    /*
     * FIXME:
     * On unload do:
     */
#if 0
    CONF_modules_unload(1);
    destroy_ui_method();
    EVP_cleanup();
    ENGINE_cleanup();
    CRYPTO_cleanup_all_ex_data();
    ERR_remove_state(0);
    ERR_free_strings();
#endif

    /*
     * Init main module
     */
    mOSSL = rb_define_module("OpenSSL");

    /*
     * Constants
     */
    rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
    rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
    rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));

    /*
     * Generic error,
     * common for all classes under OpenSSL module
     */
    eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);

    /*
     * Verify callback Proc index for ext-data
     */
    if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, "ossl_verify_cb_idx", 0, 0, 0)) < 0)
        ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");

    /*
     * Init debug core
     */
    dOSSL = Qfalse;
    rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
    rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
    rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);

    /*
     * Get ID of to_der
     */
    ossl_s_to_der = rb_intern("to_der");

    /*
     * Init components
     */
    Init_ossl_bn();
    Init_ossl_cipher();
    Init_ossl_config();
    Init_ossl_digest();
    Init_ossl_hmac();
    Init_ossl_ns_spki();
    Init_ossl_pkcs12();
    Init_ossl_pkcs7();
    Init_ossl_pkcs5();
    Init_ossl_pkey();
    Init_ossl_rand();
    Init_ossl_ssl();
    Init_ossl_x509();
    Init_ossl_ocsp();
    Init_ossl_engine();
    Init_ossl_asn1();
}
int main(int argc, char *argv[]) {
	BIO *sbio;
	SSL_CTX *ssl_ctx;
	SSL *ssl;
	X509 *server_cert;

	// Initialize OpenSSL
	OpenSSL_add_all_algorithms();
	SSL_library_init();
	SSL_load_error_strings();

 	// Check OpenSSL PRNG
	if(RAND_status() != 1) {
		fprintf(stderr, "OpenSSL PRNG not seeded with enough data.");
		goto error_1;
	}

	ssl_ctx = SSL_CTX_new(TLSv1_client_method());
	
	// Enable certificate validation
	SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
	// Configure the CA trust store to be used
	if (SSL_CTX_load_verify_locations(ssl_ctx, TRUSTED_CA_PATHNAME, NULL) != 1) {
		fprintf(stderr, "Couldn't load certificate trust store.\n");
		goto error_2;
	}

	// Only support secure cipher suites
	if (SSL_CTX_set_cipher_list(ssl_ctx, SECURE_CIPHER_LIST) != 1)
		goto error_2;

	// Create the SSL connection
	sbio = BIO_new_ssl_connect(ssl_ctx);
	BIO_get_ssl(sbio, &ssl); 
	if(!ssl) {
	  fprintf(stderr, "Can't locate SSL pointer\n");
		goto error_3;
	}

	// Do the SSL handshake
	BIO_set_conn_hostname(sbio, TARGET_SERVER);
	if(SSL_do_handshake(ssl) <= 0) {
		// SSL Handshake failed
		long verify_err = SSL_get_verify_result(ssl);
		if (verify_err != X509_V_OK) { 
			// It failed because the certificate chain validation failed
			fprintf(stderr, "Certificate chain validation failed: %s\n", X509_verify_cert_error_string(verify_err));
		}
		else {
			// It failed for another reason
			ERR_print_errors_fp(stderr);
		}
		goto error_3;
	}

	// Recover the server's certificate
	server_cert =  SSL_get_peer_certificate(ssl);
	if (server_cert == NULL) {
		// The handshake was successful although the server did not provide a certificate
		// Most likely using an insecure anonymous cipher suite... get out!
		goto error_4;
	}

	// Validate the hostname
	if (validate_hostname(TARGET_HOST, server_cert) != MatchFound) {
		fprintf(stderr, "Hostname validation failed.\n");
		goto error_5;
	}

	// Hostname validation succeeded; we can start sending data
	send_http_get_and_print(sbio);


error_5:
	X509_free(server_cert);

error_4:
	BIO_ssl_shutdown(sbio);

error_3:
	BIO_free_all(sbio);

error_2:
	SSL_CTX_free(ssl_ctx);

error_1: // OpenSSL cleanup
    EVP_cleanup();
    ERR_free_strings();

	return 0;
}
Exemple #19
0
void 
daemon_delete(struct daemon* daemon)
{
	size_t i;
	if(!daemon)
		return;
	modstack_desetup(&daemon->mods, daemon->env);
	daemon_remote_delete(daemon->rc);
	for(i = 0; i < daemon->num_ports; i++)
		listening_ports_free(daemon->ports[i]);
	free(daemon->ports);
	listening_ports_free(daemon->rc_ports);
	if(daemon->env) {
		slabhash_delete(daemon->env->msg_cache);
		rrset_cache_delete(daemon->env->rrset_cache);
		infra_delete(daemon->env->infra_cache);
		edns_known_options_delete(daemon->env);
		auth_zones_delete(daemon->env->auth_zones);
	}
	ub_randfree(daemon->rand);
	alloc_clear(&daemon->superalloc);
	acl_list_delete(daemon->acl);
	free(daemon->chroot);
	free(daemon->pidfile);
	free(daemon->env);
#ifdef HAVE_SSL
	SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
	SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
#endif
	free(daemon);
#ifdef LEX_HAS_YYLEX_DESTROY
	/* lex cleanup */
	ub_c_lex_destroy();
#endif
	/* libcrypto cleanup */
#ifdef HAVE_SSL
#  if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
	sldns_key_EVP_unload_gost();
#  endif
#  if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
#    ifndef S_SPLINT_S
#      if OPENSSL_VERSION_NUMBER < 0x10100000
	sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
#      endif
#    endif
#  endif
#  ifdef HAVE_OPENSSL_CONFIG
	EVP_cleanup();
#  if OPENSSL_VERSION_NUMBER < 0x10100000
	ENGINE_cleanup();
#  endif
	CONF_modules_free();
#  endif
#  ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
	CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
#  endif
#  ifdef HAVE_ERR_FREE_STRINGS
	ERR_free_strings();
#  endif
#  if OPENSSL_VERSION_NUMBER < 0x10100000
	RAND_cleanup();
#  endif
#  if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
	ub_openssl_lock_delete();
#  endif
#ifndef HAVE_ARC4RANDOM
	_ARC4_LOCK_DESTROY();
#endif
#elif defined(HAVE_NSS)
	NSS_Shutdown();
#endif /* HAVE_SSL or HAVE_NSS */
	checklock_stop();
#ifdef USE_WINSOCK
	if(WSACleanup() != 0) {
		log_err("Could not WSACleanup: %s", 
			wsa_strerror(WSAGetLastError()));
	}
#endif
}
Exemple #20
0
int main2(int argc, char **argv) {
	InitializeCriticalSection(&mutex);
	EnterCriticalSection(&mutex);
#endif
	char *priority = NULL;

	if(!detach()) {
		return 1;
	}

#ifdef HAVE_MLOCKALL

	/* Lock all pages into memory if requested.
	 * This has to be done after daemon()/fork() so it works for child.
	 * No need to do that in parent as it's very short-lived. */
	if(do_mlock && mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
		logger(LOG_ERR, "System call `%s' failed: %s", "mlockall",
			   strerror(errno));
		return 1;
	}

#endif

	/* Setup sockets and open device. */

	if(!setup_network()) {
		goto end;
	}

	/* Initiate all outgoing connections. */

	try_outgoing_connections();

	/* Change process priority */

	if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) {
		if(!strcasecmp(priority, "Normal")) {
			if(setpriority(NORMAL_PRIORITY_CLASS) != 0) {
				logger(LOG_ERR, "System call `%s' failed: %s",
					   "setpriority", strerror(errno));
				goto end;
			}
		} else if(!strcasecmp(priority, "Low")) {
			if(setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) {
				logger(LOG_ERR, "System call `%s' failed: %s",
					   "setpriority", strerror(errno));
				goto end;
			}
		} else if(!strcasecmp(priority, "High")) {
			if(setpriority(HIGH_PRIORITY_CLASS) != 0) {
				logger(LOG_ERR, "System call `%s' failed: %s",
					   "setpriority", strerror(errno));
				goto end;
			}
		} else {
			logger(LOG_ERR, "Invalid priority `%s`!", priority);
			goto end;
		}
	}

	/* drop privileges */
	if(!drop_privs()) {
		goto end;
	}

	/* Start main loop. It only exits when tinc is killed. */

	status = main_loop();

	/* Shutdown properly. */

	ifdebug(CONNECTIONS)
	devops.dump_stats();

	close_network_connections();

end:
	logger(LOG_NOTICE, "Terminating");

#ifndef HAVE_MINGW
	remove_pid(pidfilename);
#endif

	free(priority);

#if OPENSSL_VERSION_NUMBER < 0x10100000L
	EVP_cleanup();
	ERR_free_strings();
#ifndef OPENSSL_NO_ENGINE
	ENGINE_cleanup();
#endif
#endif

	exit_configuration(&config_tree);
	list_delete_list(cmdline_conf);
	free_names();

	return status;
}
Exemple #21
0
void pki_shutdown(void)
{
        EVP_cleanup();
}
Exemple #22
0
krb5_data *
krb5_cproxy_process(char *servername, char *port, krb5_data *request) {
  /* SSL init */
  SSL_library_init(); /* always returns 1 */
  SSL_load_error_strings();
  OpenSSL_add_all_algorithms();
  const SSL_METHOD *method = SSLv23_client_method(); /* includes TLSv1 */
  if (!method) {
    ERR_print_errors_fp(stderr);
    EVP_cleanup();
    return NULL;
  }
  SSL_CTX *gamma = SSL_CTX_new(method);
  if (!gamma) {
    ERR_print_errors_fp(stderr);
    EVP_cleanup();
    return NULL;
  }
  SSL_CTX_set_verify(gamma, SSL_VERIFY_PEER, NULL);
  if (!SSL_CTX_set_default_verify_paths(gamma)) {
    ERR_print_errors_fp(stderr);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }
  SSL *ssl = SSL_new(gamma);
  if (!ssl) {
    ERR_print_errors_fp(stderr);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }

  /* Encoding */
  char *req;
  gsize out_len;
  char *fmt = "POST / HTTP/1.0\r\n"
    "Host: %s\r\n" /* MSFT gets upset without this */
    "Content-type: application/kerberos\r\n"
    "Content-length: %d\r\n"
    "\r\n%s";
  char *g_buf = g_base64_encode((guchar *) request->data, request->length);
  size_t reqlen = asprintf(&req, fmt, servername, strlen(g_buf), g_buf);
  g_free(g_buf);

  /* connect to other proxy */
  struct addrinfo khints, *kserverdata;
  memset(&khints, 0, sizeof(khints));
  khints.ai_family = AF_UNSPEC;
  khints.ai_socktype = SOCK_STREAM;   /* TCP for HTTP */
  int gai_ret = getaddrinfo(servername, port, &khints, &kserverdata);
  if (gai_ret) {
    fprintf(stderr, "%s\n", gai_strerror(gai_ret));
    SSL_CTX_free(gamma);
    EVP_cleanup();
    free(req);
    return NULL;
  }

  int fd_prox = -1;
  for (struct addrinfo *cur = kserverdata;
       cur != NULL && fd_prox == -1;
       cur = cur->ai_next) {
    fd_prox = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol);
    if (fd_prox == -1) {
      fprintf(stderr, "failed to socket\n");
    } else if (connect(fd_prox, cur->ai_addr, cur->ai_addrlen) == -1) {
      close(fd_prox);
      fd_prox = -1;
      fprintf(stderr, "failed to connect\n");
    }
  }
  freeaddrinfo(kserverdata);
  if (fd_prox == -1) {
    fprintf(stderr, "unable to connect to any sockets\n");
    SSL_CTX_free(gamma);
    EVP_cleanup();
    free(req);
    return NULL;
  }

  /* SSL the socket */
  if (!SSL_set_fd(ssl, fd_prox)) {
    ERR_print_errors_fp(stderr);
    close(fd_prox);
    free(req);
    SSL_free(ssl);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }
  if (SSL_connect(ssl) != 1) {
    ERR_print_errors_fp(stderr); /* maybe? */
    close(fd_prox);
    free(req);
    SSL_free(ssl);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }

  /* send, get the KDCPROXY's reply */
  if (!SSL_write(ssl, req, reqlen)) {
    ERR_print_errors_fp(stderr); /* maybe */
    close(fd_prox);
    SSL_free(ssl);
    SSL_CTX_free(gamma);
    EVP_cleanup();
    return NULL;
  }
  free(req);

  char buf[BUF_SIZE];
  char *bufptr = buf;
  int length;
  do {
    length = SSL_read(ssl, bufptr, BUF_SIZE - 1 + bufptr - buf);
    printf("length: %d\n", length);
    if (length < 0) {
      ERR_print_errors_fp(stderr); /* maybe? */
      close(fd_prox);
      SSL_free(ssl);
      SSL_CTX_free(gamma);
      EVP_cleanup();
      return NULL;
    }
    bufptr += length;
  } while (length > 0);
  *bufptr = '\0';

  close(fd_prox);
  SSL_free(ssl);
  SSL_CTX_free(gamma);
  EVP_cleanup();

  /* forward the reply to the requester */
  char *rep = strstr(buf, "\r\n\r\n");
  if (rep == NULL) {
    fprintf(stderr, "didn't get back krb response from proxy\n");
    return NULL;
  }
  rep += 4;

  guchar *res = g_base64_decode(rep, &out_len);

  krb5_data *response = malloc(sizeof(krb5_data));
  response->length = out_len;
  response->data = malloc(sizeof(char)*(out_len + 1));
  memcpy(response->data, res, out_len);
  (response->data)[out_len] = '\0';

  g_free(res);
  return response;
}
Exemple #23
0
static int parse_pkcs7_data(const options_t *options, const CRYPT_DATA_BLOB *blob)
{
	int result = 0;
	const cert_format_e input_fmt = CERT_FORMAT_DER;
	PKCS7 *p7 = NULL;
	BIO *in = NULL;

	CRYPTO_malloc_init();
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();

	in = BIO_new_mem_buf(blob->pbData, blob->cbData);
	if (in == NULL) {
		result = -2;
		goto error;
	}

	switch (input_fmt) {
		default: EXIT_ERROR("unhandled input format for certificate");
		case CERT_FORMAT_DER:
			p7 = d2i_PKCS7_bio(in, NULL);
			break;
		case CERT_FORMAT_PEM:
			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
			break;
	}
	if (p7 == NULL) {
		ERR_print_errors_fp(stderr);
		result = -3;
		goto error;
	}

	STACK_OF(X509) *certs = NULL;

	int type = OBJ_obj2nid(p7->type);
	switch (type) {
		default: break;
		case NID_pkcs7_signed: // PKCS7_type_is_signed(p7)
			certs = p7->d.sign->cert;
			break;
		case NID_pkcs7_signedAndEnveloped: // PKCS7_type_is_signedAndEnveloped(p7)
			certs = p7->d.signed_and_enveloped->cert;
			break;
	}

	const int numcerts = certs != NULL ? sk_X509_num(certs) : 0;
	for (int i = 0; i < numcerts; i++) {
		X509 *cert = sk_X509_value(certs, i);
		print_certificate(options->certout, options->certoutform, cert);
		// NOTE: Calling X509_free(cert) is unnecessary.
	}

	// Print whether certificate signature is valid
	if (numcerts > 0) {
		X509 *subject = sk_X509_value(certs, 0);
		X509 *issuer = sk_X509_value(certs, numcerts - 1);
		int valid_sig = X509_verify(subject, X509_get_pubkey(issuer));
		output("Signature", valid_sig == 1 ? "valid" : "invalid");
	}

	// Print signers
	output_open_scope("Signers");
	for (int i = 0; i < numcerts; i++) {
		X509 *cert = sk_X509_value(certs, i);
		X509_NAME *name = X509_get_subject_name(cert);

		int issuer_name_len = X509_NAME_get_text_by_NID(name, NID_commonName, NULL, 0);
		if (issuer_name_len > 0) {
			char issuer_name[issuer_name_len + 1];
			X509_NAME_get_text_by_NID(name, NID_commonName, issuer_name, issuer_name_len + 1);
			output("Issuer", issuer_name);
		}
	}
	output_close_scope();

error:
	if (p7 != NULL)
		PKCS7_free(p7);
	if (in != NULL)
		BIO_free(in);

	// Deallocate everything from OpenSSL_add_all_algorithms
	EVP_cleanup();
	// Deallocate everything from ERR_load_crypto_strings
	ERR_free_strings();

	return result;
}
Exemple #24
0
int validate_token(bstring token)
{
    int i;

    OpenSSL_add_all_algorithms();

    struct bstrList *parts = bsplit(token, '|');

    dictionary *dict = dictionary_new(10);

    bstring sig = bfromcstr("sig");
    bstring to_sign = bfromcstr("");
    
    for (i = 0; i < parts->qty; i++)
    {
	printf("%d: %s\n", i, parts->entry[i]->data);

	struct bstrList *x = bsplit(parts->entry[i], '=');
	if (x->qty == 2)
	{
	    if (bstrcmp(x->entry[0], sig) != 0)
	    {
		if (blength(to_sign) > 0)
		    bconchar(to_sign, '|');
		bconcat(to_sign, parts->entry[i]);
	    }
	    dictionary_set(dict, bdata(x->entry[0]), bdata(x->entry[1]));
	}
	bstrListDestroy(x);
    }
    bstrListDestroy(parts);
    parts = 0;
    bdestroy(sig);
    
    dictionary_dump(dict, stdout);
    printf("to sign: '%s'\n", bdata(to_sign));

    // Check signing subject (need to know the valid values)

    char *subj = dictionary_get(dict, "SigningSubject", 0);
    if (!subj)
    {
	fprintf(stderr, "could not get signing subject\n");
	return 0;
    }

    char *sigstr = dictionary_get(dict, "sig", 0);
    printf("sig to verify is %s\n", sigstr);

    bstring binsig = bfromcstralloc(strlen(sigstr) / 2, "");
    char *s, *e;
    for (s = sigstr, e = sigstr + strlen(sigstr); s < e; s += 2)
    {
	char n[3];
	n[0] = s[0];
	n[1] = s[1];
	n[2] = 0;
	long int v = strtol(n, 0, 16);
//	printf("n=%s v=%ld %lx\n", n, v, v);
	bconchar(binsig, (char) v);
    }

    unsigned char *sha = SHA1((const unsigned char *) to_sign->data, to_sign->slen, 0);

    bdestroy(to_sign);

    bstring bsubj = bfromcstr(subj);
    bstring pubkey = get_signer_pubkey(bsubj);

    BIO *bio = BIO_new(BIO_s_mem());
    BIO_puts(bio, bdata(pubkey));

    RSA *rsa = PEM_read_bio_RSAPublicKey(bio, 0, 0, 0);

    int rc = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, binsig->data, binsig->slen, rsa);
    printf("rc=%d\n", rc);

    bdestroy(bsubj);
    bdestroy(binsig);
    bdestroy(pubkey);
    BIO_free(bio);
    RSA_free(rsa);
    dictionary_del(dict);
    EVP_cleanup();
    
    return rc;
}
Exemple #25
0
// Minimal TLS server. This is largely based on the example at
// https://wiki.openssl.org/index.php/Simple_TLS_Server and the gRPC core
// internals in src/core/lib/tsi/ssl_transport_security.c.
static void server_thread(void *arg) {
  const server_args *args = (server_args *)arg;

  SSL_load_error_strings();
  OpenSSL_add_ssl_algorithms();

  const SSL_METHOD *method = TLSv1_2_server_method();
  SSL_CTX *ctx = SSL_CTX_new(method);
  if (!ctx) {
    perror("Unable to create SSL context");
    ERR_print_errors_fp(stderr);
    abort();
  }

  // Load key pair.
  if (SSL_CTX_use_certificate_file(ctx, SSL_CERT_PATH, SSL_FILETYPE_PEM) < 0) {
    ERR_print_errors_fp(stderr);
    abort();
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, SSL_KEY_PATH, SSL_FILETYPE_PEM) < 0) {
    ERR_print_errors_fp(stderr);
    abort();
  }

  // Set the cipher list to match the one expressed in
  // src/core/lib/tsi/ssl_transport_security.c.
  const char *cipher_list =
      "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-"
      "SHA384:ECDHE-RSA-AES256-GCM-SHA384";
  if (!SSL_CTX_set_cipher_list(ctx, cipher_list)) {
    ERR_print_errors_fp(stderr);
    gpr_log(GPR_ERROR, "Couldn't set server cipher list.");
    abort();
  }

  // Register the ALPN selection callback.
  SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, args->alpn_preferred);

  // bind/listen/accept at TCP layer.
  const int sock = args->socket;
  gpr_log(GPR_INFO, "Server listening");
  struct sockaddr_in addr;
  socklen_t len = sizeof(addr);
  const int client = accept(sock, (struct sockaddr *)&addr, &len);
  if (client < 0) {
    perror("Unable to accept");
    abort();
  }

  // Establish a SSL* and accept at SSL layer.
  SSL *ssl = SSL_new(ctx);
  GPR_ASSERT(ssl);
  SSL_set_fd(ssl, client);
  if (SSL_accept(ssl) <= 0) {
    ERR_print_errors_fp(stderr);
    gpr_log(GPR_ERROR, "Handshake failed.");
  } else {
    gpr_log(GPR_INFO, "Handshake successful.");
  }

  // Wait until the client drops its connection.
  char buf;
  while (SSL_read(ssl, &buf, sizeof(buf)) > 0)
    ;

  SSL_free(ssl);
  close(client);
  close(sock);
  SSL_CTX_free(ctx);
  EVP_cleanup();
}
Exemple #26
0
/**
 * Main function of drill
 * parse the arguments and prepare a query
 */
int
main(int argc, char *argv[])
{
        ldns_resolver	*res = NULL;
        ldns_resolver   *cmdline_res = NULL; /* only used to resolv @name names */
	ldns_rr_list	*cmdline_rr_list = NULL;
	ldns_rdf	*cmdline_dname = NULL;
        ldns_rdf 	*qname, *qname_tmp;
        ldns_pkt	*pkt;
        ldns_pkt	*qpkt;
        char 		*serv;
        const char 	*name;
        char 		*name2;
	char		*progname;
	char 		*query_file = NULL;
	char		*answer_file = NULL;
	ldns_buffer	*query_buffer = NULL;
	ldns_rdf 	*serv_rdf;
        ldns_rr_type 	type;
        ldns_rr_class	clas;
#if 0
	ldns_pkt_opcode opcode = LDNS_PACKET_QUERY;
#endif
	int 		i, c;
	int 		int_type;
	int		int_clas;
	int		PURPOSE;
	char		*tsig_name = NULL;
	char		*tsig_data = NULL;
	char 		*tsig_algorithm = NULL;
	size_t		tsig_separator;
	size_t		tsig_separator2;
	ldns_rr		*axfr_rr;
	ldns_status	status;
	char *type_str;
	
	/* list of keys used in dnssec operations */
	ldns_rr_list	*key_list = ldns_rr_list_new(); 
	/* what key verify the current answer */
	ldns_rr_list 	*key_verified;

	/* resolver options */
	uint16_t	qflags;
	uint16_t 	qbuf;
	uint16_t	qport;
	uint8_t		qfamily;
	bool		qdnssec;
	bool		qfallback;
	bool		qds;
	bool		qusevc;
	bool 		qrandom;
	
	char		*resolv_conf_file = NULL;
	
	ldns_rdf *trace_start_name = NULL;

	int		result = 0;

#ifdef USE_WINSOCK
	int r;
	WSADATA wsa_data;
#endif

	int_type = -1; serv = NULL; type = 0; 
	int_clas = -1; name = NULL; clas = 0;
	qname = NULL; 
	progname = strdup(argv[0]);

#ifdef USE_WINSOCK
	r = WSAStartup(MAKEWORD(2,2), &wsa_data);
	if(r != 0) {
		printf("Failed WSAStartup: %d\n", r);
		result = EXIT_FAILURE;
		goto exit;
	}
#endif /* USE_WINSOCK */
		
	
	PURPOSE = DRILL_QUERY;
	qflags = LDNS_RD;
	qport = LDNS_PORT;
	verbosity = 2;
	qdnssec = false;
	qfamily = LDNS_RESOLV_INETANY;
	qfallback = false;
	qds = false;
	qbuf = 0;
	qusevc = false;
	qrandom = true;
	key_verified = NULL;

	ldns_init_random(NULL, 0);

	if (argc == 0) {
		usage(stdout, progname);
		result = EXIT_FAILURE;
		goto exit;
	}

	/* string from orig drill: "i:w:I46Sk:TNp:b:DsvhVcuaq:f:xr" */
	/* global first, query opt next, option with parm's last
	 * and sorted */ /*  "46DITSVQf:i:w:q:achuvxzy:so:p:b:k:" */
	                               
	while ((c = getopt(argc, argv, "46ab:c:d:Df:hi:Ik:o:p:q:Qr:sStTuvV:w:xy:z")) != -1) {
		switch(c) {
			/* global options */
			case '4':
				qfamily = LDNS_RESOLV_INET;
				break;
			case '6':
				qfamily = LDNS_RESOLV_INET6;
				break;
			case 'D':
				qdnssec = true;
				break;
			case 'I':
				/* reserved for backward compatibility */
				break;
			case 'T':
				if (PURPOSE == DRILL_CHASE) {
					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
					exit(EXIT_FAILURE);
				}
				PURPOSE = DRILL_TRACE;
				break;
#ifdef HAVE_SSL
			case 'S':
				if (PURPOSE == DRILL_TRACE) {
					fprintf(stderr, "-T and -S cannot be used at the same time.\n");
					exit(EXIT_FAILURE);
				}
				PURPOSE = DRILL_CHASE;
				break;
#endif /* HAVE_SSL */
			case 'V':
				if (strtok(optarg, "0123456789") != NULL) {
					fprintf(stderr, "-V expects an number as an argument.\n");
					exit(EXIT_FAILURE);
				}
				verbosity = atoi(optarg);
				break;
			case 'Q':
				verbosity = -1;
				break;
			case 'f':
				query_file = optarg;
				break;
			case 'i':
				answer_file = optarg;
				PURPOSE = DRILL_AFROMFILE;
				break;
			case 'w':
				answer_file = optarg;
				break;
			case 'q':
				query_file = optarg;
				PURPOSE = DRILL_QTOFILE;
				break;
			case 'r':
				if (global_dns_root) {
					fprintf(stderr, "There was already a series of root servers set\n");
					exit(EXIT_FAILURE);
				}
				global_dns_root = read_root_hints(optarg);
				if (!global_dns_root) {
					fprintf(stderr, "Unable to read root hints file %s, aborting\n", optarg);
					exit(EXIT_FAILURE);
				}
				break;
			/* query options */
			case 'a':
				qfallback = true;
				break;
			case 'b':
				qbuf = (uint16_t)atoi(optarg);
				if (qbuf == 0) {
					error("%s", "<bufsize> could not be converted");
				}
				break;
			case 'c':
				resolv_conf_file = optarg;
				break;
			case 't':
				qusevc = true;
				break;
			case 'k':
				status = read_key_file(optarg,
						key_list, false);
				if (status != LDNS_STATUS_OK) {
					error("Could not parse the key file %s: %s", optarg, ldns_get_errorstr_by_id(status));
				}
				qdnssec = true; /* enable that too */
				break;
			case 'o':
				/* only looks at the first hit: capital=ON, lowercase=OFF*/
				if (strstr(optarg, "QR")) {
					DRILL_ON(qflags, LDNS_QR);
				}
				if (strstr(optarg, "qr")) {
					DRILL_OFF(qflags, LDNS_QR);
				}
				if (strstr(optarg, "AA")) {
					DRILL_ON(qflags, LDNS_AA);
				}
				if (strstr(optarg, "aa")) {
					DRILL_OFF(qflags, LDNS_AA);
				}
				if (strstr(optarg, "TC")) {
					DRILL_ON(qflags, LDNS_TC);
				}
				if (strstr(optarg, "tc")) {
					DRILL_OFF(qflags, LDNS_TC);
				}
				if (strstr(optarg, "RD")) {
					DRILL_ON(qflags, LDNS_RD);
				}
				if (strstr(optarg, "rd")) {
					DRILL_OFF(qflags, LDNS_RD);
				}
				if (strstr(optarg, "CD")) {
					DRILL_ON(qflags, LDNS_CD);
				}
				if (strstr(optarg, "cd")) {
					DRILL_OFF(qflags, LDNS_CD);
				}
				if (strstr(optarg, "RA")) {
					DRILL_ON(qflags, LDNS_RA);
				}
				if (strstr(optarg, "ra")) {
					DRILL_OFF(qflags, LDNS_RA);
				}
				if (strstr(optarg, "AD")) {
					DRILL_ON(qflags, LDNS_AD);
				}
				if (strstr(optarg, "ad")) {
					DRILL_OFF(qflags, LDNS_AD);
				}
				break;
			case 'p':
				qport = (uint16_t)atoi(optarg);
				if (qport == 0) {
					error("%s", "<port> could not be converted");
				}
				break;
			case 's':
				qds = true;
				break;
			case 'u':
				qusevc = false;
				break;
			case 'v':
				version(stdout, progname);
				result = EXIT_SUCCESS;
				goto exit;
			case 'x':
				PURPOSE = DRILL_REVERSE;
				break;
			case 'y':
#ifdef HAVE_SSL
				if (strchr(optarg, ':')) {
					tsig_separator = (size_t) (strchr(optarg, ':') - optarg);
					if (strchr(optarg + tsig_separator + 1, ':')) {
						tsig_separator2 = (size_t) (strchr(optarg + tsig_separator + 1, ':') - optarg);
						tsig_algorithm = xmalloc(strlen(optarg) - tsig_separator2);
						strncpy(tsig_algorithm, optarg + tsig_separator2 + 1, strlen(optarg) - tsig_separator2);
						tsig_algorithm[strlen(optarg) - tsig_separator2 - 1] = '\0';
					} else {
						tsig_separator2 = strlen(optarg);
						tsig_algorithm = xmalloc(26);
						strncpy(tsig_algorithm, "hmac-md5.sig-alg.reg.int.", 25);
						tsig_algorithm[25] = '\0';
					}
					tsig_name = xmalloc(tsig_separator + 1);
					tsig_data = xmalloc(tsig_separator2 - tsig_separator);
					strncpy(tsig_name, optarg, tsig_separator);
					strncpy(tsig_data, optarg + tsig_separator + 1, tsig_separator2 - tsig_separator - 1);
					/* strncpy does not append \0 if source is longer than n */
					tsig_name[tsig_separator] = '\0';
					tsig_data[ tsig_separator2 - tsig_separator - 1] = '\0';
				}
#else
				fprintf(stderr, "TSIG requested, but SSL is not supported\n");
				result = EXIT_FAILURE;
				goto exit;
#endif /* HAVE_SSL */
				break;
			case 'z':
				qrandom = false;
				break;
			case 'd':
				trace_start_name = ldns_dname_new_frm_str(optarg);
				if (!trace_start_name) {
					fprintf(stderr, "Unable to parse argument for -%c\n", c);
					result = EXIT_FAILURE;
					goto exit;
				}
				break;
			case 'h':
				version(stdout, progname);
				usage(stdout, progname);
				result = EXIT_SUCCESS;
				goto exit;
				break;
			default:
				fprintf(stderr, "Unknown argument: -%c, use -h to see usage\n", c);
				result = EXIT_FAILURE;
				goto exit;
		}
	}
	argc -= optind;
	argv += optind;

	if ((PURPOSE == DRILL_CHASE || (PURPOSE == DRILL_TRACE && qdnssec)) &&
			ldns_rr_list_rr_count(key_list) == 0) {

		(void) read_key_file(LDNS_TRUST_ANCHOR_FILE, key_list, true);
	}
	if (ldns_rr_list_rr_count(key_list) > 0) {
		printf(";; Number of trusted keys: %d\n",
				(int) ldns_rr_list_rr_count(key_list));
	}
	/* do a secure trace when requested */
	if (PURPOSE == DRILL_TRACE && qdnssec) {
#ifdef HAVE_SSL
		if (ldns_rr_list_rr_count(key_list) == 0) {
			warning("%s", "No trusted keys were given. Will not be able to verify authenticity!");
		}
		PURPOSE = DRILL_SECTRACE;
#else
		fprintf(stderr, "ldns has not been compiled with OpenSSL support. Secure trace not available\n");
		exit(1);
#endif /* HAVE_SSL */
	}

	/* parse the arguments, with multiple arguments, the last argument
	 * found is used */
	for(i = 0; i < argc; i++) {

		/* if ^@ then it's a server */
		if (argv[i][0] == '@') {
			if (strlen(argv[i]) == 1) {
				warning("%s", "No nameserver given");
				exit(EXIT_FAILURE);
			}
			serv = argv[i] + 1;
			continue;
		}
		/* if has a dot, it's a name */
		if (strchr(argv[i], '.')) {
			name = argv[i];
			continue;
		}
		/* if it matches a type, it's a type */
		if (int_type == -1) {
			type = ldns_get_rr_type_by_name(argv[i]);
			if (type != 0) {
				int_type = 0;
				continue;
			}
		}
		/* if it matches a class, it's a class */
		if (int_clas == -1) {
			clas = ldns_get_rr_class_by_name(argv[i]);
			if (clas != 0) {
				int_clas = 0;
				continue;
			}
		}
		/* it all fails assume it's a name */
		name = argv[i];
	}
	/* act like dig and use for . NS */
	if (!name) {
		name = ".";
		int_type = 0;
		type = LDNS_RR_TYPE_NS;
	}
	
	/* defaults if not given */
	if (int_clas == -1) {
		clas = LDNS_RR_CLASS_IN;
	}
	if (int_type == -1) {
		if (PURPOSE != DRILL_REVERSE) {
			type = LDNS_RR_TYPE_A;
		} else {
			type = LDNS_RR_TYPE_PTR;
		}
	}

	/* set the nameserver to use */
	if (!serv) {
		/* no server given make a resolver from /etc/resolv.conf */
		status = ldns_resolver_new_frm_file(&res, resolv_conf_file);
		if (status != LDNS_STATUS_OK) {
			warning("Could not create a resolver structure: %s (%s)\n"
					"Try drill @localhost if you have a resolver running on your machine.",
				    ldns_get_errorstr_by_id(status), resolv_conf_file);
			result = EXIT_FAILURE;
			goto exit;
		}
	} else {
		res = ldns_resolver_new();
		if (!res || strlen(serv) <= 0) {
			warning("Could not create a resolver structure");
			result = EXIT_FAILURE;
			goto exit;
		}
		/* add the nameserver */
		serv_rdf = ldns_rdf_new_addr_frm_str(serv);
		if (!serv_rdf) {
			/* try to resolv the name if possible */
			status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file);
			
			if (status != LDNS_STATUS_OK) {
				error("%s", "@server ip could not be converted");
			}
			ldns_resolver_set_dnssec(cmdline_res, qdnssec);
			ldns_resolver_set_ip6(cmdline_res, qfamily);
			ldns_resolver_set_fallback(cmdline_res, qfallback);
			ldns_resolver_set_usevc(cmdline_res, qusevc);

			cmdline_dname = ldns_dname_new_frm_str(serv);

			cmdline_rr_list = ldns_get_rr_list_addr_by_name(
						cmdline_res, 
						cmdline_dname,
						LDNS_RR_CLASS_IN,
						qflags);
			ldns_rdf_deep_free(cmdline_dname);
			if (!cmdline_rr_list) {
				/* This error msg is not always accurate */
				error("%s `%s\'", "could not find any address for the name:", serv);
			} else {
				if (ldns_resolver_push_nameserver_rr_list(
						res, 
						cmdline_rr_list
					) != LDNS_STATUS_OK) {
					error("%s", "pushing nameserver");
				}
			}
		} else {
			if (ldns_resolver_push_nameserver(res, serv_rdf) != LDNS_STATUS_OK) {
				error("%s", "pushing nameserver");
			} else {
				ldns_rdf_deep_free(serv_rdf);
			}
		}
	}
	/* set the resolver options */
	ldns_resolver_set_port(res, qport);
	if (verbosity >= 5) {
		ldns_resolver_set_debug(res, true);
	} else {
		ldns_resolver_set_debug(res, false);
	}
	ldns_resolver_set_dnssec(res, qdnssec);
/*	ldns_resolver_set_dnssec_cd(res, qdnssec);*/
	ldns_resolver_set_ip6(res, qfamily);
	ldns_resolver_set_fallback(res, qfallback);
	ldns_resolver_set_usevc(res, qusevc);
	ldns_resolver_set_random(res, qrandom);
	if (qbuf != 0) {
		ldns_resolver_set_edns_udp_size(res, qbuf);
	}

	if (!name && 
	    PURPOSE != DRILL_AFROMFILE &&
	    !query_file
	   ) {
		usage(stdout, progname);
		result = EXIT_FAILURE;
		goto exit;
	}

	if (tsig_name && tsig_data) {
		ldns_resolver_set_tsig_keyname(res, tsig_name);
		ldns_resolver_set_tsig_keydata(res, tsig_data);
		ldns_resolver_set_tsig_algorithm(res, tsig_algorithm);
	}
	
	/* main switching part of drill */
	switch(PURPOSE) {
		case DRILL_TRACE:
			/* do a trace from the root down */
			if (!global_dns_root) {
				init_root();
			}
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "parsing query name");
			}
			/* don't care about return packet */
			(void)do_trace(res, qname, type, clas);
			clear_root();
			break;
		case DRILL_SECTRACE:
			/* do a secure trace from the root down */
			if (!global_dns_root) {
				init_root();
			}
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "making qname");
			}
			/* don't care about return packet */
#ifdef HAVE_SSL
			result = do_secure_trace(res, qname, type, clas, key_list, trace_start_name);
#endif /* HAVE_SSL */
			clear_root();
			break;
		case DRILL_CHASE:
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "making qname");
			}
			
			ldns_resolver_set_dnssec(res, true);
			ldns_resolver_set_dnssec_cd(res, true);
			/* set dnssec implies udp_size of 4096 */
			ldns_resolver_set_edns_udp_size(res, 4096);
			pkt = ldns_resolver_query(res, qname, type, clas, qflags);
			
			if (!pkt) {
				error("%s", "error pkt sending");
				result = EXIT_FAILURE;
			} else {
				if (verbosity >= 3) {
					ldns_pkt_print(stdout, pkt);
				}
				
				if (!ldns_pkt_answer(pkt)) {
					mesg("No answer in packet");
				} else {
#ifdef HAVE_SSL
					ldns_resolver_set_dnssec_anchors(res, ldns_rr_list_clone(key_list));
					result = do_chase(res, qname, type,
					                  clas, key_list, 
					                  pkt, qflags, NULL,
								   verbosity);
					if (result == LDNS_STATUS_OK) {
						if (verbosity != -1) {
							mesg("Chase successful");
						}
						result = 0;
					} else {
						if (verbosity != -1) {
							mesg("Chase failed.");
						}
					}
#endif /* HAVE_SSL */
				}
				ldns_pkt_free(pkt);
			}
			break;
		case DRILL_AFROMFILE:
			pkt = read_hex_pkt(answer_file);
			if (pkt) {
				if (verbosity != -1) {
					ldns_pkt_print(stdout, pkt);
				}
				ldns_pkt_free(pkt);
			}
			
			break;
		case DRILL_QTOFILE:
			qname = ldns_dname_new_frm_str(name);
			if (!qname) {
				error("%s", "making qname");
			}

			status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags);
			if(status != LDNS_STATUS_OK) {
				error("%s", "making query: %s", 
					ldns_get_errorstr_by_id(status));
			}
			dump_hex(qpkt, query_file);
			ldns_pkt_free(qpkt);
			break;
		case DRILL_NSEC:
			break;
		case DRILL_REVERSE:
			/* ipv4 or ipv6 addr? */
			if (strchr(name, ':')) {
				if (strchr(name, '.')) {
					error("Syntax error: both '.' and ':' seen in address\n");
				}
				name2 = malloc(IP6_ARPA_MAX_LEN + 20);
				c = 0;
				for (i=0; i<(int)strlen(name); i++) {
					if (i >= IP6_ARPA_MAX_LEN) {
						error("%s", "reverse argument to long");
					}
					if (name[i] == ':') {
						if (i < (int) strlen(name) && name[i + 1] == ':') {
							error("%s", ":: not supported (yet)");
						} else {
							if (i + 2 == (int) strlen(name) || name[i + 2] == ':') {
								name2[c++] = '0';
								name2[c++] = '.';
								name2[c++] = '0';
								name2[c++] = '.';
								name2[c++] = '0';
								name2[c++] = '.';
							} else if (i + 3 == (int) strlen(name) || name[i + 3] == ':') {
								name2[c++] = '0';
								name2[c++] = '.';
								name2[c++] = '0';
								name2[c++] = '.';
							} else if (i + 4 == (int) strlen(name) || name[i + 4] == ':') {
								name2[c++] = '0';
								name2[c++] = '.';
							}
						}
					} else {
						name2[c++] = name[i];
						name2[c++] = '.';
					}
				}
				name2[c++] = '\0';

				qname = ldns_dname_new_frm_str(name2);
				qname_tmp = ldns_dname_reverse(qname);
				ldns_rdf_deep_free(qname);
				qname = qname_tmp;
				qname_tmp = ldns_dname_new_frm_str("ip6.arpa.");
				status = ldns_dname_cat(qname, qname_tmp);
				if (status != LDNS_STATUS_OK) {
					error("%s", "could not create reverse address for ip6: %s\n", ldns_get_errorstr_by_id(status));
				}
				ldns_rdf_deep_free(qname_tmp);

				free(name2);
			} else {
				qname = ldns_dname_new_frm_str(name);
				qname_tmp = ldns_dname_reverse(qname);
				ldns_rdf_deep_free(qname);
				qname = qname_tmp;
				qname_tmp = ldns_dname_new_frm_str("in-addr.arpa.");
				status = ldns_dname_cat(qname, qname_tmp);
				if (status != LDNS_STATUS_OK) {
					error("%s", "could not create reverse address for ip4: %s\n", ldns_get_errorstr_by_id(status));
				}
				ldns_rdf_deep_free(qname_tmp);
			}
			if (!qname) {
				error("%s", "-x implies an ip address");
			}
			
			/* create a packet and set the RD flag on it */
			pkt = ldns_resolver_query(res, qname, type, clas, qflags);
			if (!pkt)  {
				error("%s", "pkt sending");
				result = EXIT_FAILURE;
			} else {
				if (verbosity != -1) {
					ldns_pkt_print(stdout, pkt);
				}
				ldns_pkt_free(pkt);
			}
			break;
		case DRILL_QUERY:
		default:
			if (query_file) {
				/* this old way, the query packet needed
				   to be parseable, but we want to be able
				   to send mangled packets, so we need
				   to do it directly */
				#if 0
				qpkt = read_hex_pkt(query_file);
				if (qpkt) {
					status = ldns_resolver_send_pkt(&pkt, res, qpkt);
					if (status != LDNS_STATUS_OK) {
						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
						exit(1);
					}
				} else {
					/* qpkt was bogus, reset pkt */
					pkt = NULL;
				}
				#endif
				query_buffer = read_hex_buffer(query_file);
				if (query_buffer) {
					status = ldns_send_buffer(&pkt, res, query_buffer, NULL);
					ldns_buffer_free(query_buffer);
					if (status != LDNS_STATUS_OK) {
						printf("Error: %s\n", ldns_get_errorstr_by_id(status));
						exit(1);
					}
				} else {
					printf("NO BUFFER\n");
					pkt = NULL;
				}
			} else {
				qname = ldns_dname_new_frm_str(name);
				if (!qname) {
					error("%s", "error in making qname");
				}

				if (type == LDNS_RR_TYPE_AXFR) {
					status = ldns_axfr_start(res, qname, clas);
					if(status != LDNS_STATUS_OK) {
						error("Error starting axfr: %s", 
							ldns_get_errorstr_by_id(status));
					}
					axfr_rr = ldns_axfr_next(res);
					if(!axfr_rr) {
						fprintf(stderr, "AXFR failed.\n");
						ldns_pkt_print(stdout,
							ldns_axfr_last_pkt(res));
						goto exit;
					}
					while (axfr_rr) {
						if (verbosity != -1) {
							ldns_rr_print(stdout, axfr_rr);
						}
						ldns_rr_free(axfr_rr);
						axfr_rr = ldns_axfr_next(res);
					}

					goto exit;
				} else {
					/* create a packet and set the RD flag on it */
					pkt = ldns_resolver_query(res, qname, type, clas, qflags);
				}
			}
			
			if (!pkt)  {
				mesg("No packet received");
				result = EXIT_FAILURE;
			} else {
				if (verbosity != -1) {
					ldns_pkt_print(stdout, pkt);
					if (ldns_pkt_tc(pkt)) {
						fprintf(stdout,
							"\n;; WARNING: The answer packet was truncated; you might want to\n");
						fprintf(stdout,
							";; query again with TCP (-t argument), or EDNS0 (-b for buffer size)\n");
					}
				}
				if (qds) {
					if (verbosity != -1) {
						print_ds_of_keys(pkt);
						printf("\n");
					}
				}
			
				if (ldns_rr_list_rr_count(key_list) > 0) {
					/* -k's were given on the cmd line */
					ldns_rr_list *rrset_verified;
					uint16_t key_count;

					rrset_verified = ldns_pkt_rr_list_by_name_and_type(
							pkt, qname, type, 
							LDNS_SECTION_ANY_NOQUESTION);

					if (type == LDNS_RR_TYPE_ANY) {
						/* don't verify this */
						break;
					}

					if (verbosity != -1) {
						printf("; ");
						ldns_rr_list_print(stdout, rrset_verified);
					}

					/* verify */
#ifdef HAVE_SSL
					key_verified = ldns_rr_list_new();
					result = ldns_pkt_verify(pkt, type, qname, key_list, NULL, key_verified);

					if (result == LDNS_STATUS_ERR) {
						/* is the existence denied then? */
						result = ldns_verify_denial(pkt, qname, type, NULL, NULL);
						if (result == LDNS_STATUS_OK) {
							if (verbosity != -1) {
								printf("Existence denied for ");
								ldns_rdf_print(stdout, qname);
								type_str = ldns_rr_type2str(type);
								printf("\t%s\n", type_str);
								LDNS_FREE(type_str);
							}
						} else {
							if (verbosity != -1) {
								printf("Bad data; RR for name and "
								       "type not found or failed to "
								       "verify, and denial of "
								       "existence failed.\n");
							}
						}
					} else if (result == LDNS_STATUS_OK) {
						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_verified);
								key_count++) {
							if (verbosity != -1) {
								printf("; VALIDATED by id = %u, owner = ",
										(unsigned int)ldns_calc_keytag(
												      ldns_rr_list_rr(key_verified, key_count)));
								ldns_rdf_print(stdout, ldns_rr_owner(
											ldns_rr_list_rr(key_list, key_count)));
								printf("\n");
							}
						}
					} else {
						for(key_count = 0; key_count < ldns_rr_list_rr_count(key_list);
								key_count++) {
							if (verbosity != -1) {
								printf("; %s for id = %u, owner = ",
								       ldns_get_errorstr_by_id(result),
								       (unsigned int)ldns_calc_keytag(
												      ldns_rr_list_rr(key_list, key_count)));
								ldns_rdf_print(stdout, ldns_rr_owner(

								ldns_rr_list_rr(key_list,
								key_count)));
								printf("\n");
							}
						}
					}
					ldns_rr_list_free(key_verified);
#else
					(void) key_count;
#endif /* HAVE_SSL */
				}
				if (answer_file) {
					dump_hex(pkt, answer_file);
				}
				ldns_pkt_free(pkt); 
			}
			
			break;
	}

	exit:
	ldns_rdf_deep_free(qname);
	ldns_resolver_deep_free(res);
	ldns_resolver_deep_free(cmdline_res);
	ldns_rr_list_deep_free(key_list);
	ldns_rr_list_deep_free(cmdline_rr_list);
	ldns_rdf_deep_free(trace_start_name);
	xfree(progname);
	xfree(tsig_name);
	xfree(tsig_data);
	xfree(tsig_algorithm);

#ifdef HAVE_SSL
	ERR_remove_state(0);
	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();
	EVP_cleanup();
#endif
#ifdef USE_WINSOCK
	WSACleanup();
#endif

	return result;
}
Exemple #27
0
int 
main (int argc, char *argv[]) 
{
  struct comp_options comp_opts = {
    .comp = COMP__BLAKE_2B,
    .comb = COMB__HASH
  };

  int xor_then_hash = false;
  int32_t n_rounds = 8;
  int64_t n_space = (1024*1024);
  int16_t n_neighbors = 0;
  int32_t n_iters = 1;
  int16_t n_threads = 1;
  int help = false;
  enum mix_method mix = 0;

  while (1)
    {
      struct option long_options[] =
        {
          /* These options don’t set a flag.
             We distinguish them by their indices. */
          {"xor", no_argument, &xor_then_hash, 1},
          {"comp",  required_argument, 0, 'c'},
          {"mix",  required_argument, 0, 'm'},
          {"space",  required_argument, 0, 's'},
          {"rounds",  required_argument, 0, 'r'},
          {"neighbors",  required_argument, 0, 'n'},
          {"iterations",  required_argument, 0, 'i'},
          {"threads",  required_argument, 0, 't'},
          {"help", no_argument, &help, 1},
          {0, 0, 0, 0}
        };
      /* getopt_long stores the option index here. */
      int option_index = 0;

      char c = getopt_long (argc, argv, "xc:m:s:r:n:i:t:h?",
                       long_options, &option_index);
      char *end;

      /* Detect the end of the options. */
      if (c == -1)
        break;

      switch (c)
        {
        case 0:
          /* If this option set a flag, do nothing else now. */
          if (long_options[option_index].flag != 0)
            break;
            printf ("option %s", long_options[option_index].name);
            if (optarg)
              printf (" with arg %s", optarg);
          printf ("\n");
          break;

        case 'x':
          xor_then_hash = true;
          break; 
        case 'c':
          if (!strcmp (optarg, "keccak"))
            comp_opts.comp = COMP__KECCAK_1600;
          else if (!strcmp (optarg, "argon"))
            comp_opts.comp = COMP__ARGON;
          else if (!strcmp (optarg, "blake2b"))
            comp_opts.comp = COMP__BLAKE_2B;
          else if (!strcmp (optarg, "sha512"))
            comp_opts.comp = COMP__SHA_512;
          else if (!strcmp (optarg, "simpira2048"))
            comp_opts.comp = COMP__SIMPIRA_2048;
          else if (!strcmp (optarg, "echo"))
            comp_opts.comp = COMP__ECHO;
          else {
            fprintf (stderr, "Invalid compression method\n");
            return -1;
          }
          break;

        case 'm':
          if (!strcmp (optarg, "single"))
            mix = MIX__BALLOON_SINGLE_BUFFER;
          else if (!strcmp (optarg, "double"))
            mix = MIX__BALLOON_DOUBLE_BUFFER;
          else if (!strcmp (optarg, "double-par"))
            mix = MIX__BALLOON_DOUBLE_BUFFER_PAR;
          else if (!strcmp (optarg, "double-pipe"))
            mix = MIX__BALLOON_DOUBLE_BUFFER_PIPE;
          else if (!strcmp (optarg, "argon2"))
            mix = MIX__ARGON2_UNIFORM;
          else if (!strcmp (optarg, "catena-brg"))
            mix = MIX__CATENA_BRG;
          else if (!strcmp (optarg, "catena-dbg"))
            mix = MIX__CATENA_DBG;
          else if (!strcmp (optarg, "scrypt"))
            mix = MIX__SCRYPT;
          else {
            fprintf (stderr, "Invalid mix method\n");
            return -1;
          }
          break;

        case 's':
          errno = 0;
          n_space = strtoll (optarg, &end, 10);
          if (errno > 0 || *end != '\0' || n_space < 0) {
            fprintf (stderr, "Invalid argument to -s\n");
            return -1;
          }

          break;

        case 'n':
          errno = 0;
          n_neighbors = strtoll (optarg, &end, 4);
          if (errno > 0 || *end != '\0' || n_neighbors < 0) {
            fprintf (stderr, "Invalid argument to -n\n");
            return -1;
          }
          break;

        case 't':
          errno = 0;
          n_threads = strtoll (optarg, &end, 10);
          if (errno > 0 || *end != '\0' || n_threads <= 0) {
            fprintf (stderr, "Invalid argument to -t\n");
            return -1;
          }
          break;

        case 'r':
          errno = 0;
          n_rounds = strtoll (optarg, &end, 10);
          if (errno > 0 || *end != '\0' || n_rounds < 0) {
            fprintf (stderr, "Invalid argument to -r\n");
            return -1;
          }
          break;

        case 'i':
          errno = 0;
          n_iters = strtoll (optarg, &end, 10);
          if (errno > 0 || *end != '\0' || n_iters < 0) {
            fprintf (stderr, "Invalid argument to -i\n");
            return -1;
          }
          break;
          

        case 'h':
        case '?':
          help = true;
          break;

        default:
          return -1;
        }
    }

  if (help) {
    usage (argv[0]);
    return 0;
  } else {
    if (optind + 2 < argc) {
        fprintf (stderr, "Too many arguments\n");
        return -1;
      }
    if (optind + 2 > argc)
      {
        fprintf (stderr, "Input and salt not passed in\n");
        return -1;
      }
  }

  char *in = argv[optind];
  char *salt = argv[optind+1];


  comp_opts.comb = xor_then_hash ? COMB__XOR : COMB__HASH;
  struct balloon_options opts = {
    .m_cost = n_space,
    .t_cost = n_rounds,
    .n_neighbors = n_neighbors,
    .n_threads = n_threads,
    .comp_opts = comp_opts,
    .mix = mix
  };

  const unsigned int rec_neighbs = options_n_neighbors (&opts);
  if (n_neighbors && ((uint16_t) n_neighbors) != rec_neighbs) {
    fprintf (stderr, "Warning: using unrecommended n_neighbors param!\n");
  }
  if (!n_neighbors)
    opts.n_neighbors = rec_neighbs;

  printf ("NRounds        = %lld\n", (long long int)opts.t_cost);
  printf ("NSpace         = %lld\n", (long long int)opts.m_cost);
  printf ("Neighbs        = %lld\n", (long long int)opts.n_neighbors);
  printf ("Niters         = %lld\n", (long long int)n_iters);
  printf ("Nthreads       = %d\n", (int)n_threads);
  printf ("Mix            = %d\n", opts.mix);
  printf ("Compression    = %d\n", opts.comp_opts.comp);
  printf ("XOR-then-hash  = %d\n", opts.comp_opts.comb);
  printf ("Input          = %s\n", in);
  printf ("Salt           = %s\n", salt);

  const int outlen = 32;
  unsigned char out[outlen];
  int error;
  const double wall_start = wall_sec ();
  for (int32_t i = 0; i < n_iters; i++) {
    if ((error = BalloonHash (out, outlen, in, strlen (in), salt, strlen (salt), &opts))) {
      fprintf (stderr, "BalloonHash failed with error: %d\n", error);
      return -1;
    }
  }
  const double wall_end = wall_sec ();
  const double wall_diff = wall_end - wall_start;
  printf("Time total      : %lg\n", wall_diff);
  printf("Hashes per sec  : %lg\n", ((double) n_iters) / wall_diff);
  printf("Output          : ");
  for (int i = 0; i < outlen; i++) {
    printf("%x", out[i]);
  }
  printf("\n");

  // Clean up OpenSSL junk
  EVP_cleanup();
  CRYPTO_cleanup_all_ex_data();
  ERR_remove_state(0);
  ERR_free_strings();
  return 0;
}
Exemple #28
0
void OPENSSL_cleanup(void)
{
    OPENSSL_INIT_STOP *currhandler, *lasthandler;

    /* If we've not been inited then no need to deinit */
    if (!base_inited)
        return;

    /* Might be explicitly called and also by atexit */
    if (stopped)
        return;
    stopped = 1;

    /*
     * Thread stop may not get automatically called by the thread library for
     * the very last thread in some situations, so call it directly.
     */
    ossl_init_thread_stop(ossl_init_get_thread_local(0));

    currhandler = stop_handlers;
    while (currhandler != NULL) {
        currhandler->handler();
        lasthandler = currhandler;
        currhandler = currhandler->next;
        OPENSSL_free(lasthandler);
    }
    stop_handlers = NULL;
    /*
     * We assume we are single-threaded for this function, i.e. no race
     * conditions for the various "*_inited" vars below.
     */

    if (zlib_inited) {
#ifdef OPENSSL_INIT_DEBUG
        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                        "COMP_zlib_cleanup()\n");
#endif
        COMP_zlib_cleanup();
    }

#ifndef OPENSSL_NO_ENGINE
    if (engine_inited) {
# ifdef OPENSSL_INIT_DEBUG
        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                        "ENGINE_cleanup()\n");
# endif
        ENGINE_cleanup();
    }
#endif

    if (load_crypto_strings_inited) {
#ifdef OPENSSL_INIT_DEBUG
        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
                        "ERR_free_strings()\n");
#endif
        ERR_free_strings();
    }

#ifdef OPENSSL_INIT_DEBUG
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
                    "CRYPTO_cleanup_all_ex_data()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
                    "EVP_cleanup()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
                    "CONF_modules_free()\n");
    fprintf(stderr, "OPENSSL_INIT: OPENSSL_INIT_library_stop: "
                    "RAND_cleanup()\n");
#endif
    CRYPTO_cleanup_all_ex_data();
    EVP_cleanup();
    CONF_modules_free();
    RAND_cleanup();
    base_inited = 0;
}
Exemple #29
0
static void server_free(server *srv) {
	size_t i;

	for (i = 0; i < FILE_CACHE_MAX; i++) {
		buffer_free(srv->mtime_cache[i].str);
	}

#define CLEAN(x) \
	buffer_free(srv->x);

	CLEAN(response_header);
	CLEAN(parse_full_path);
	CLEAN(ts_debug_str);
	CLEAN(ts_date_str);
	CLEAN(errorlog_buf);
	CLEAN(response_range);
	CLEAN(tmp_buf);
	CLEAN(empty_string);
	CLEAN(cond_check_buf);

	CLEAN(srvconf.errorlog_file);
	CLEAN(srvconf.groupname);
	CLEAN(srvconf.username);
	CLEAN(srvconf.changeroot);
	CLEAN(srvconf.bindhost);
	CLEAN(srvconf.event_handler);
	CLEAN(srvconf.pid_file);
	CLEAN(srvconf.modules_dir);
	CLEAN(srvconf.network_backend);

	CLEAN(tmp_chunk_len);
#undef CLEAN

#if 0
	fdevent_unregister(srv->ev, srv->fd);
#endif
	fdevent_free(srv->ev);

	free(srv->conns);

	if (srv->config_storage) {
		for (i = 0; i < srv->config_context->used; i++) {
			specific_config *s = srv->config_storage[i];

			if (!s) continue;

			buffer_free(s->document_root);
			buffer_free(s->server_name);
			buffer_free(s->server_tag);
			buffer_free(s->ssl_pemfile);
			buffer_free(s->ssl_ca_file);
			buffer_free(s->ssl_cipher_list);
			buffer_free(s->error_handler);
			buffer_free(s->errorfile_prefix);
			array_free(s->mimetypes);
#ifdef USE_OPENSSL
			SSL_CTX_free(s->ssl_ctx);
#endif
			free(s);
		}
		free(srv->config_storage);
		srv->config_storage = NULL;
	}

#define CLEAN(x) \
	array_free(srv->x);

	CLEAN(config_context);
	CLEAN(config_touched);
	CLEAN(status);
	CLEAN(srvconf.upload_tempdirs);
#undef CLEAN

	joblist_free(srv, srv->joblist);
	fdwaitqueue_free(srv, srv->fdwaitqueue);

	if (srv->stat_cache) {
		stat_cache_free(srv->stat_cache);
	}

	array_free(srv->srvconf.modules);
	array_free(srv->split_vals);

#ifdef USE_OPENSSL
	if (srv->ssl_is_init) {
		CRYPTO_cleanup_all_ex_data();
		ERR_free_strings();
		ERR_remove_state(0);
		EVP_cleanup();
	}
#endif

	free(srv);
}
Exemple #30
0
int main(int argc,char **argv)
    {
    const char *szTestFile;
    FILE *f;

    if(argc != 2)
	{
	fprintf(stderr,"%s <test file>\n",argv[0]);
	EXIT(1);
	}
    CRYPTO_malloc_debug_init();
    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    szTestFile=argv[1];

    f=fopen(szTestFile,"r");
    if(!f)
	{
	perror(szTestFile);
	EXIT(2);
	}

    /* Load up the software EVP_CIPHER and EVP_MD definitions */
    OpenSSL_add_all_ciphers();
    OpenSSL_add_all_digests();
#ifndef OPENSSL_NO_ENGINE
    /* Load all compiled-in ENGINEs */
    ENGINE_load_builtin_engines();
#endif
#if 0
    OPENSSL_config();
#endif
#ifndef OPENSSL_NO_ENGINE
    /* Register all available ENGINE implementations of ciphers and digests.
     * This could perhaps be changed to "ENGINE_register_all_complete()"? */
    ENGINE_register_all_ciphers();
    ENGINE_register_all_digests();
    /* If we add command-line options, this statement should be switchable.
     * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use if
     * they weren't already initialised. */
    /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */
#endif

    for( ; ; )
	{
	char line[4096];
	char *p;
	char *cipher;
	unsigned char *iv,*key,*plaintext,*ciphertext;
	int encdec;
	int kn,in,pn,cn;

	if(!fgets((char *)line,sizeof line,f))
	    break;
	if(line[0] == '#' || line[0] == '\n')
	    continue;
	p=line;
	cipher=sstrsep(&p,":");	
	key=ustrsep(&p,":");
	iv=ustrsep(&p,":");
	plaintext=ustrsep(&p,":");
	ciphertext=ustrsep(&p,":");
	if (p[-1] == '\n') {
	    p[-1] = '\0';
	    encdec = -1;
	} else {
	    encdec = atoi(sstrsep(&p,"\n"));
	}
	      

	kn=convert(key);
	in=convert(iv);
	pn=convert(plaintext);
	cn=convert(ciphertext);

	if(!test_cipher(cipher,key,kn,iv,in,plaintext,pn,ciphertext,cn,encdec)
	   && !test_digest(cipher,plaintext,pn,ciphertext,cn))
	    {
#ifdef OPENSSL_NO_AES
	    if (strstr(cipher, "AES") == cipher)
		{
		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
		continue;
		}
#endif
#ifdef OPENSSL_NO_DES
	    if (strstr(cipher, "DES") == cipher)
		{
		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
		continue;
		}
#endif
#ifdef OPENSSL_NO_RC4
	    if (strstr(cipher, "RC4") == cipher)
		{
		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
		continue;
		}
#endif
#ifdef OPENSSL_NO_CAMELLIA
	    if (strstr(cipher, "CAMELLIA") == cipher)
		{
		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
		continue;
		}
#endif
#ifdef OPENSSL_NO_SEED
	    if (strstr(cipher, "SEED") == cipher)
		{
		fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); 
		continue;
		}
#endif
	    fprintf(stderr,"Can't find %s\n",cipher);
	    EXIT(3);
	    }
	}
	fclose(f);

#ifndef OPENSSL_NO_ENGINE
    ENGINE_cleanup();
#endif
    EVP_cleanup();
    CRYPTO_cleanup_all_ex_data();
    ERR_remove_thread_state(NULL);
    ERR_free_strings();
    CRYPTO_mem_leaks_fp(stderr);

    return 0;
    }