/*
 * NAME:
 *	sslc - routines useful for SSL clients
 *
 * DESCRIPTION:
 *	These routines provide for client authentication using
 *	Eric Young's SSLeay library.
 *
 * AUTHOR:
 *	Simon J. Gerraty <sjg@quick.com.au>
 */
/*
 *      @(#)Copyright (c) 1996 Simon J. Gerraty.
 *      
 *      This is free software.  It comes with NO WARRANTY.
 *      Permission to use, modify and distribute this source code 
 *      is granted subject to the following conditions.
 *      1/ that the above copyright notice and this notice 
 *      are preserved in all copies and that due credit be given 
 *      to the author.  
 *      2/ that any changes to this code are clearly commented 
 *      as such so that the author does not get blamed for bugs 
 *      other than his own.
 *      
 *      Please send copies of changes and bug-fixes to:
 *      sjg@quick.com.au
 */
#ifndef lint
static char RCSid[] = "$Id: sslc.c,v 1.10 1997/02/08 07:13:06 sjg Exp $";
#endif

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <syslog.h>
#include <string.h>


#include "x509.h"
#include "ssl.h"

#include "sslfd.h"

extern SSL_CTX *ssl_ctx;
extern SSL *ssl_con;
static int ssl_verify_verbose = 0;
char *MyId = "SSLc";

/*
 * <sjg> a simplified cb, so we can print useful errors
 */
static int
ssl_verify_cb(ok, xs, xi, depth, error)
	int ok;
	const char *xs, *xi;
	int depth, error;
{
	char *name = (char *)X509_NAME_oneline(X509_get_subject_name((X509 *)xs));
	if (!ok) {
		char *err = X509_cert_verify_error_string(error);

		if ((ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0)
			ok=1;
		
		fprintf(stderr, "%s: %s: SSL cert verify: depth=%d,err=%s,xs=%s\n",
			MyId, (ok) ? "WARNING" : "ERROR", depth, err, name);
	} else if (ssl_verify_verbose) {
		fprintf(stderr, "%s: SSL cert verify: depth=%d,xs=%s\n",
			MyId, depth, name);
	}
	free(name);
	return ok;
}

const char *
setMyId(myname)
	const char *myname;
{
	static char myid[64];
	char prompt[80];
	register const char *rcp;

	if (rcp = strrchr(myname, '/'))
		rcp++;
	else
		rcp = myname;
	sprintf(myid, "%.*s[%d]", sizeof(myid) - 10, rcp, getpid());
	MyId = myid;
#ifndef NO_EVP_set_pw_prompt			/* old SSLeay versions */
	sprintf(prompt, "%s: Enter PEM pass phrase:", MyId);
	EVP_set_pw_prompt(prompt);
#endif
	return rcp;
}

int
sslc_init(cert_file, key_file, cipher_list, verify_flag, flags)
	const char *cert_file, *key_file, *cipher_list;
	int verify_flag;
	int flags;
{
	ssl_verify_verbose = (flags & 1);
	
	return ssl_init(cert_file, key_file, cipher_list, verify_flag,
			ssl_verify_cb, -1, flags);
}

int
sslc_start(fd, active, flags)
	int fd;
	int active;
	int flags;
{
	int sts = ssl_start(fd, -1, active);

	if (sts > 0 && (flags & 1)) {
		(void) fprintf(stderr,
			       "%s: SSL Connected - Cipher %s\n",
			       MyId, SSL_get_cipher(ssl_con));
	}
	return sts;
}

