Exemplo n.º 1
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
static int
verify_callback(int preverify_ok, X509_STORE_CTX * x509ctx)
{
	X509_NAME      *xn;
	static char     txt[256];

	xn = X509_get_subject_name(x509ctx->current_cert);
	X509_NAME_oneline(xn, txt, sizeof(txt));

	if (preverify_ok == 0) {
		LOG(SPOCP_ERR)
		    traceLog(LOG_ERR,"SSL verify error: depth=%d error=%s cert=%s",
			     x509ctx->error_depth,
			     X509_verify_cert_error_string(x509ctx->error),
			     txt);
		return 0;
	}

	/*
	 * the check against allowed clients are done elsewhere 
	 */

	LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"SSL authenticated peer: %s\n", txt);

	return 1;		/* accept */
}
Exemplo n.º 2
0
/*!
 * \brief if necessary libraries are present this function converts the input 
 * to utf8 and normalizes it.
 * \param s The input string
 * \return Returns a newly allocated zero-terminated string.
 */
char *normalize( char *s )
{
	char *buf;
#ifdef HAVE_LIBIDN
	int	bufsize, rc;
	char	*utf8;


	traceLog(LOG_INFO,"Doing stringprep on %s", s);
	/* stringprep_locale_charset(); */
	utf8 = stringprep_locale_to_utf8(s);

	bufsize = strlen(utf8) * 2;
	buf = (char *) Malloc ( bufsize * sizeof( char ) );
	strcpy(buf,utf8);

	rc = stringprep (buf, bufsize, 0, stringprep_nameprep);
	if (rc != STRINGPREP_OK) {
		traceLog(LOG_INFO,"Stringprep failed with rc %d", rc);
		Free(buf);
		buf = utf8;
	} else 
		Free(utf8);
	
	traceLog(LOG_INFO,"result %s", buf);
#else
	buf = Strdup(s);
#endif

	return buf;
}
Exemplo n.º 3
0
Arquivo: rm.c Projeto: Zabrane/SPOCP
int
rm_endofrule(junc_t * jp, element_t * ep, ruleinst_t * rt)
{
	branch_t	*bp;
	spocp_index_t	*inx;

	DEBUG(SPOCP_DSTORE) traceLog(LOG_DEBUG,"rm end_of_rule");
	bp = ARRFIND(jp, SPOC_ENDOFRULE);

	bp->count--;

	DEBUG(SPOCP_DSTORE) traceLog(LOG_DEBUG,"Branch count=%d", bp->count);
	inx = bp->val.id;

	index_rm(inx, rt);

	if (inx->n == 0) {
		branch_free(bp);
		return 0;
	}

	/*
	 * there is no next element 
	 */

	return 1;
}
Exemplo n.º 4
0
Arquivo: main.c Projeto: Zabrane/SPOCP
spocp_result_t 
get_rules( srv_t *srv )
{
	spocp_result_t  rc = SPOCP_SUCCESS;
	int		nrules = 0, r;
	dbcmd_t         dbc;
	struct timeval  start, end;

	memset( &dbc, 0, sizeof( dbcmd_t ));
	dbc.dback = srv->dback;

	if (srv->dback) {
		/*
		 * does the persistent database store need any initialization
		 * ?? * if( srv.dback->init ) srv.dback->init( dbcmd_t *dbc )
		 * ; 
		 */

		if ((nrules = dback_read_rules(&dbc, srv, &rc)) < 0)
			return rc;
	}

	if (nrules == 0) {
		if (srv->rulefile) {
			LOG(SPOCP_INFO)
				traceLog(LOG_INFO, "Opening rules file \"%s\"",
				    srv->rulefile);

			if (0)
				gettimeofday(&start, NULL);

			/*
			dbc.dback = srv->dback;
			dbc.handle = 0;
			*/

			r = read_rules(srv, srv->rulefile, &dbc) ;
			if( r == -1 ) {
	 			LOG(SPOCP_ERR)
					traceLog(LOG_ERR,"Error while reading rules");
				rc = SPOCP_OPERATIONSERROR;
			}
			if (0) {
				gettimeofday(&end, NULL);
				print_elapsed("readrule time:", start, end);
			}
		}
		else
			LOG(SPOCP_INFO)
				traceLog(LOG_INFO, "No rule file to start with");
	} else {
		LOG(SPOCP_INFO)
		    traceLog(LOG_INFO,
			"Got the rules from the persistent store, will not read the rulefile");
	}

	return rc;
}
Exemplo n.º 5
0
spocp_result_t
is_ipv4(octet_t * op, struct in_addr * ia)
{
	char            c;

	c = op->val[op->len];
	op->val[op->len] = 0;
#ifdef HAVE_INET_NTOP
	if (inet_pton(AF_INET, op->val, ia) <= 0) {
#else
	if (inet_aton( op->val, ia) == 0) {
#endif
		op->val[op->len] = c;
		traceLog(LOG_ERR,"Error in IP number definition: %s", strerror(errno));
		return SPOCP_SYNTAXERROR;
	} else {
		op->val[op->len] = c;
		ia->s_addr = htonl( ia->s_addr );
		return SPOCP_SUCCESS;
	}
}

spocp_result_t
is_ipv4_s(char *ip, struct in_addr * ia)
{
#ifdef HAVE_INET_NTOP
	if (inet_pton(AF_INET, ip, ia) <= 0)
#else
	if (inet_aton( ip, ia) == 0) 
#endif
		return SPOCP_SYNTAXERROR;
	else
		return SPOCP_SUCCESS;
}

#ifdef USE_IPV6
spocp_result_t
is_ipv6(octet_t * op, struct in6_addr * ia)
{
	char            c;

	c = op->val[op->len];
	op->val[op->len] = 0;
	if (inet_pton(AF_INET6, op->val, ia) <= 0) {
		op->val[op->len] = c;
		traceLog(LOG_ERR,"Error in IP number definition: %s", strerror(errno));
		return SPOCP_SYNTAXERROR;
	} else {
		op->val[op->len] = c;
		return SPOCP_SUCCESS;
	}
}
Exemplo n.º 6
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
static int
tls_error(int level, conn_t * conn, char *msg)
{
	char            errorstr[1024];
	unsigned long   e;

	e = ERR_get_error();
	ERR_error_string_n(e, errorstr, 1024);

	LOG(level) traceLog(LOG_ERR,"TLS error on connection from %s (%s): %s",
			    conn->sri.hostname, conn->sri.hostaddr, msg);
	LOG(level) traceLog(LOG_ERR,"\"%s\"", errorstr);

	return FALSE;
}
Exemplo n.º 7
0
Arquivo: rm.c Projeto: Zabrane/SPOCP
spocp_result_t
rule_rm(junc_t * jp, octet_t * rule, ruleinst_t * rt)
{
	element_t      *ep = 0;
	int             r = 1;	/* default SUCCESS? well sort of */
	spocp_result_t  rc;
	octet_t         loc;

	DEBUG(SPOCP_DSTORE) {
		oct_print(LOG_DEBUG,"- rm rule", rule);
	}

	/*
	 * decouple 
	 */
	loc.val = rule->val;
	loc.len = rule->len;

	if ((rc = element_get(&loc, &ep)) != SPOCP_SUCCESS)
		return rc;

	DEBUG(SPOCP_DSTORE) traceLog(LOG_DEBUG,"---");

	if (ep) {
		r = element_rm(jp, ep, rt);
	}

	if (r == 1)
		return SPOCP_SUCCESS;
	else
		return SPOCP_OPERATIONSERROR;
}
Exemplo n.º 8
0
Arquivo: rm.c Projeto: Zabrane/SPOCP
int
list_rm(branch_t * bp, element_t * ep, ruleinst_t * rt)
{
	element_t      *elemp;
	list_t         *lp = ep->e.list;
	junc_t         *njp = bp->val.list;
	int             r;

	DEBUG(SPOCP_DSTORE) traceLog(LOG_DEBUG,"rm list");

	elemp = lp->head;

	r = element_rm(njp, elemp, rt);

	/*
	 * DEBUG(SPOCP_DSTORE) traceLog(LOG_DEBUG, "rm list; is there anything more?") ;
	 * 
	 * if( r == 0 ) { njp->item[ elemp->type ] = 0 ;
	 * 
	 * if( junction_index( njp ) == 0 ) { junc_free( njp ) ; bp->val.list
	 * = 0 ; } } 
	 */

	return 1;
}
Exemplo n.º 9
0
static bcspec_t *
bcspec_new(plugin_t * plt, octet_t * spec)
{
	octet_t         oct;
	bcspec_t       *bcs = 0;
	plugin_t       *p;
	int             n;

	/*
	 * two parts name ":" typespec 
	 */
	if ((n = octchr(spec, ':')) < 0) {
		oct_print( LOG_ERR,
		    "Error in boundary condition specification", spec);
		return 0;
	}

	oct.len = spec->len - n - 1;
	oct.val = spec->val + n + 1;
	spec->len = n;

	if ((p = plugin_match(plt, spec)) == 0) {
		traceLog(LOG_ERR,"Doesn't match any known plugin",spec);
		return 0;
	}

	bcs = (bcspec_t *) Calloc(1,sizeof(bcspec_t));

	bcs->plugin = p;
	bcs->name = oct2strdup(spec, 0);
	bcs->spec = octdup(&oct);

	return bcs;
}
Exemplo n.º 10
0
Arquivo: rm.c Projeto: Zabrane/SPOCP
static int
ssn_rm(branch_t * bp, ssn_t * ssn, char *sp, int direction, element_t * ep,
       ruleinst_t * rt)
{
	junc_t         *jp;
	int             r;

	jp = ssn_delete(&ssn, sp, direction);

	if (ssn == 0) {
		branch_free(bp);
		return 0;
	}

	if (jp) {
		r = rm_next(jp, ep, rt);

		if (r == 0) {	/* one branch gone from the junction */

			/*
			 * could this really happen ?? 
			 */
			if (junction_index(jp) == 0) {
				DEBUG(SPOCP_DSTORE)
					traceLog(LOG_DEBUG,
					    "Junction without any branches");
				junc_free(jp);
				return -1;
			}
		}
	}

	return 1;
}
Exemplo n.º 11
0
Arquivo: rm.c Projeto: Zabrane/SPOCP
int
range_rm(branch_t * bp, element_t * ep, ruleinst_t * rt)
{
	junc_t         *jp;
	int             rc, dtype = ep->e.range->lower.type & 0x07;

	jp = sl_range_rm(bp->val.range[dtype], ep->e.range, &rc);

	if (rc == 1) {
		junc_free(jp);
		branch_free(bp);
		return 0;
	}

	rc = rm_next(jp, ep, rt);

	if (rc == 0) {		/* one branch gone from the junction */

		/*
		 * could this really happen ?? 
		 */
		if (junction_index(jp) == 0) {
			DEBUG(SPOCP_DSTORE)
			    traceLog(LOG_DEBUG,"Junction without any branches");
			junc_free(jp);
			return -1;
		}
	}

	return 1;
}
Exemplo n.º 12
0
LONG CALLBACK MJCore_Exception_Filter(_EXCEPTION_POINTERS *ex) {
	CodeConv::tostringstream dmsg, lmsg;
#ifdef _MSC_VER
	PIMAGEHLP_SYMBOL pSymbol;
#endif
	DWORD disp;
	ErrorInfo *errinf = nullptr;

	lmsg << _T("ハンドルされていない例外 ") <<
	std::hex << std::setw(8) << std::setfill(_T('0')) << ex->ExceptionRecord->ExceptionCode <<
	_T(" が発生したため、強制終了されます。");
	fatal(lmsg.str().c_str()); dmsg << lmsg.str() << std::endl; lmsg.str(_T(""));

	CONTEXT context; memcpy(&context, ex->ContextRecord, sizeof(CONTEXT));
	switch (ex->ExceptionRecord->ExceptionCode) {
	case EXCEPTION_MJCORE_SUBSCRIPT_OUT_OF_RANGE:
	case EXCEPTION_MJCORE_INVALID_ARGUMENT:
	case EXCEPTION_MJCORE_INVALID_DATA:
	case EXCEPTION_MJCORE_OVERFLOW:
	case EXCEPTION_MJCORE_DECOMPRESSION_FAILURE:
	case EXCEPTION_MJCORE_HASH_MISMATCH:
		errinf = (ErrorInfo *)(ex->ExceptionRecord->ExceptionInformation[0]);
		lmsg << _T(">>> ") << errinf->msg;
		fatal(lmsg.str().c_str()); dmsg << lmsg.str() << std::endl; lmsg.str(_T(""));
#if defined(_MSC_VER) && defined(_DEBUG)
		lmsg << _T(">>> ファイル: ") << errinf->file <<
		_T(" 行: ") << errinf->line <<
		_T(" 関数名: ") << errinf->func;
		fatal(lmsg.str().c_str()); dmsg << lmsg.str() << std::endl; lmsg.str(_T(""));

		pSymbol = (PIMAGEHLP_SYMBOL)GlobalAlloc(GMEM_FIXED, 16384);
		pSymbol->SizeOfStruct = 16384; pSymbol->MaxNameLength = 16384 - sizeof(IMAGEHLP_SYMBOL);
		SymInitialize(GetCurrentProcess(), nullptr, TRUE);
		for (unsigned int i = 0; true; i++) {
			if (i >= ADDRBUF) break;
			if (errinf->traceBack[i] == 0) break;
			if (SymGetSymFromAddr(GetCurrentProcess(), errinf->traceBack[i], &disp, pSymbol))
				lmsg << std::hex << std::setw(8) << std::setfill(_T('0')) << errinf->traceBack[i] <<
				_T(" ") << pSymbol->Name << _T("() + ") <<
				std::setfill(_T('0')) << disp;
			else lmsg << std::hex << std::setw(8) << std::setfill(_T('0')) << errinf->traceBack[i] <<
				_T(" Unknown");
			debug(lmsg.str().c_str()); lmsg.str(_T(""));
		}
		SymCleanup(GetCurrentProcess());
		GlobalFree(pSymbol);
#endif
		break;
#ifdef _MSC_VER
	default:
		traceLog(ex->ContextRecord, nullptr, 0);
#endif
	}

#ifdef _MSC_VER
	terminate();
#else
	abort();
#endif
}
Exemplo n.º 13
0
Arquivo: main.c Projeto: Zabrane/SPOCP
static void
sig_term( int signo )
{
	received_sigterm = signo;
	traceLog(LOG_NOTICE, "Received SIGTERM");
	wake_listener(1);
}
Exemplo n.º 14
0
Arquivo: rdb.c Projeto: Zabrane/SPOCP
void rdb_print( void *r )
{
	int		i;
	varr_t	*va;

	va = rdb_all( r );

	if (va) {
		for( i = 0; i < va->n; i++ )
			traceLog( LOG_DEBUG, "RDB %s", ((ruleinst_t *) va->arr[i])->uid);

		varr_free(va );
	}
	else
			traceLog( LOG_DEBUG, "RDB EMPTY");
}
Exemplo n.º 15
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
static int
add_entropy(const char *file)
{
	struct stat     st;
	int             n = -1;

	if (!file)
		return 0;

	if (stat(file, &st) == -1)
		return errno == ENOENT ? 0 : -1;

	/*
	 * check that the file permissions are secure 
	 */
	if (st.st_uid != getuid() ||
	    ((st.st_mode & (S_IWGRP | S_IRGRP)) != 0) ||
	    ((st.st_mode & (S_IWOTH | S_IROTH)) != 0)) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"TLS: %s has insecure permissions!",
					file);
		return -1;
	}
#ifdef HAVE_RAND_EGD
	n = RAND_egd(file);
#endif

	if (n <= 0)
		n = RAND_load_file(file, -1);

	return n;
}
Exemplo n.º 16
0
static void
element_set_reduce( element_t *ep )
{
    varr_t      *va;
    size_t      i;
    element_t   *te;
#ifdef XYDEBUG
    octet_t     *op;
    char        *tmp;

    op = oct_new( 512, NULL);
    element_print( op, ep );
    tmp = oct2strdup( op, 0 );
    traceLog(LOG_DEBUG,"Reducing: [%s]", tmp );
    Free( tmp );
#endif

    varr_rm_dup( ep->e.set, P_element_cmp, P_element_free ); 

#ifdef XYDEBUG
    op->len = 0;
    element_print( op, ep );
    tmp = oct2strdup( op, 0 );
    traceLog(LOG_DEBUG, "1:st Reduction to [%s]", tmp);
    Free(tmp);
#endif

    va = ep->e.set;
    if( va->n > 1 ) {
        for( i = 0; i < va->n; i++) {
            if( va->arr[i] == 0 ) continue;

            te = (element_t *) va->arr[i];
            va->arr[i] = element_reduce(te);
        }
    }

#ifdef XYDEBUG
    op->len = 0;
    element_print( op, ep );
    tmp = oct2strdup( op, 0 );
    traceLog(LOG_DEBUG, "2:nd Reduction to [%s]", tmp);
    Free(tmp);
    oct_free( op );
#endif

}
Exemplo n.º 17
0
/* expects 
 * "what" +SP "=" +SP <base> "/" attr *( ',' attr ) in the configuration
 * file
 */
spocp_result_t 
set_attr( void **vpp, void *cd, int argc, char **argv)
{
	ainfo_t *ai=0, *newai ;
	char	*sp;
	char	*buf;
	int	n;
	LDAPDN	dn = NULL;
	void	*vp;

	traceLog( LOG_DEBUG, "argc: %d, argv[0]: %s", argc, argv[0]);
	if( argc != 1 )
		return SPOCP_PARAM_ERROR;


	buf = normalize( argv[0]) ;
	sp = index( buf, '/' );

	if ( !sp)
		return SPOCP_PARAM_ERROR;

	*sp++ = '\0';

	newai = ( ainfo_t * ) calloc (1, sizeof( ainfo_t ));

	traceLog( LOG_DEBUG, "Base DN[0]: %s", buf );
	ldap_str2dn( buf, &dn, LDAP_DN_FORMAT_LDAPV3);
	ldap_dn2str( dn, &buf, LDAP_DN_FORMAT_LDAPV3);

	ldap_memfree( dn );

	traceLog( LOG_DEBUG, "Base DN[1]: %s", buf);
	newai->base = buf;
	newai->attr = line_split( sp, ',', 0, 1, 0, &n);

	vp = (void *) newai;

	if( *vpp != 0 ) {
		ai = (ainfo_t *) *vpp;
		newai->next = ai;
	}

	*vpp = vp;

	return SPOCP_SUCCESS;
}
Exemplo n.º 18
0
Arquivo: rm.c Projeto: Zabrane/SPOCP
int
suffix_rm(branch_t * bp, element_t * elemp, ruleinst_t * rt)
{
	atom_t         *ap = elemp->e.atom;

	DEBUG(SPOCP_DSTORE) traceLog(LOG_DEBUG,"rm suffix \"%s\"", ap->val.val);

	return ssn_rm(bp, bp->val.suffix, ap->val.val, BACKWARD, elemp, rt);
}
Exemplo n.º 19
0
Arquivo: rm.c Projeto: Zabrane/SPOCP
int
rm_endoflist(junc_t * jp, element_t * ep, ruleinst_t * rt)
{
	branch_t       *bp;
	junc_t         *rjp;
	int             r;

	bp = ARRFIND(jp, SPOC_ENDOFLIST);

	bp->count--;

	DEBUG(SPOCP_DSTORE) traceLog(LOG_DEBUG,"EOL Branch [%d]", bp->count);

	rjp = bp->val.list;

	if (bp->count == 0) {
		DEBUG(SPOCP_DSTORE)
		    traceLog(LOG_DEBUG,"Get rid of the rest of this branch");

		branch_free(bp);

		DEBUG(SPOCP_DSTORE)
		    traceLog(LOG_DEBUG,"No type %d branch at this junction any more",
			     SPOC_ENDOFLIST);

		jp->item[SPOC_ENDOFLIST] = 0;

		return 0;
	}

	r = rm_next(rjp, ep, rt);

	if (r == 0) {		/* one branch gone from the junction */

		if (junction_index(rjp) == 0) {
			DEBUG(SPOCP_DSTORE)
			    traceLog(LOG_DEBUG,"Junction without any branches");
			junc_free(rjp);
			bp->val.list = 0;
		}
	}

	return 1;
}
Exemplo n.º 20
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
static int
generate_eph_rsa_key(SSL_CTX * ctx, int keylength)
{
	RSA            *rsa_key;

	LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"Generating %d bit RSA key...\n", keylength);

	rsa_key = RSA_generate_key(keylength, RSA_F4, NULL, NULL);

	if (!SSL_CTX_set_tmp_rsa(ctx, rsa_key)) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"TLS error (RSA_generate_key): %s",
					ssl_errstring);
		return FALSE;
	}

	RSA_free(rsa_key);

	return TRUE;
}
Exemplo n.º 21
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
static int
init_dh(SSL_CTX * ctx, unsigned char *dhparam)
{
	int             rc = TRUE;
	BIO            *bio = 0;
	DH             *dh = 0;

	if (dhparam == NULL)
		return TRUE;

	if ((bio = BIO_new_file((char *) dhparam, "r")) == NULL) {
		LOG(SPOCP_ERR)
		    traceLog(LOG_ERR,"DH: could not read %s: %s", dhparam,
			     strerror(errno));
		rc = FALSE;
	} else {

		if ((dh =
		     PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) == NULL) {
			LOG(SPOCP_ERR)
			    traceLog(LOG_ERR,"DH: could not load params from %s",
				     dhparam);
			rc = FALSE;
		} else {
			if (SSL_CTX_set_tmp_dh(ctx, dh) < 0) {
				LOG(SPOCP_DEBUG)
					traceLog(LOG_ERR,
					    "Couldn't set Diffie-Hellman parameters");
				rc = FALSE;
			} else
				LOG(SPOCP_DEBUG)
				    traceLog(LOG_ERR,
					"Diffie-Hellman initialised from %s with %d-bit key",
				    	 dhparam, 8 * DH_size(dh));

			DH_free(dh);
		}

		BIO_free(bio);
	}

	return rc;
}
Exemplo n.º 22
0
void translateException(unsigned int code, _EXCEPTION_POINTERS* ep) {
	CodeConv::tostringstream lmsg;
	lmsg << _T("構造化例外 ") <<
	std::hex << std::setw(8) << std::setfill(_T('0')) << ep->ExceptionRecord->ExceptionCode <<
	_T(" をC++例外に変換します。");
	info(lmsg.str().c_str());

	CONTEXT context; memcpy(&context, ep->ContextRecord, sizeof(CONTEXT));
	traceLog(ep->ContextRecord, nullptr, 0);
	throw ep;
}
Exemplo n.º 23
0
void StackTraceToArray() {
	CONTEXT context; memset(&context, 0, sizeof(context));
	context.ContextFlags = CONTEXT_FULL;
	__asm	call(x);
	__asm x:	pop eax;
	__asm	mov context.Eip, eax;
	__asm	mov context.Ebp, ebp;
	__asm	mov context.Esp, esp;

	traceLog(&context, errorInfo.traceBack, sizeof(errorInfo.traceBack));
}
Exemplo n.º 24
0
Arquivo: init.c Projeto: Zabrane/SPOCP
int
run_plugin_init(srv_t * srv)
{
	plugin_t       *pl;

	for (pl = srv->plugin; pl; pl = pl->next) {
		if (strcmp(pl->name, "dback") == 0)
			continue;

		if (pl->init) {
			traceLog(LOG_INFO,"Running the init function for %s", pl->name);
			pl->init(&pl->conf, &pl->dyn);
		}
	}
	return 0;
}
Exemplo n.º 25
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
static int
password_cb(char *buf, int num, int rwflag, void *userdata)
{
	char	*passwd = (char *) userdata;
	int	len;

	len = (int) strlen(passwd);
	if (num < len + 1) {
		LOG(SPOCP_ERR)
		    traceLog(LOG_ERR,"Not big enough place for the password (%d)",
			     num);
		return (0);
	}

	strcpy(buf, passwd);
	return (len);
}
Exemplo n.º 26
0
Arquivo: main.c Projeto: Zabrane/SPOCP
static void
sig_usr1( int signo )
{
	struct stat	statbuf;
	work_info_t	wi;
	conn_t		*con;

	traceLog(LOG_NOTICE, "Received SIGUSR1");
	stat( srv.rulefile, &statbuf );
	if (statbuf.st_mtime != srv.mtime ) {
		srv.mtime = statbuf.st_mtime;
		con = conn_new();
		con->srv = &srv;
		con->rs = srv.root;
		memset( &wi, 0, sizeof( work_info_t ));
		wi.conn = con;
		wi.routine = &do_reread_rulefile;

		reread_rulefile = 1;
		tpool_add_work( srv.work, &wi);
	}
}
Exemplo n.º 27
0
int
main(int argc, char **argv)
{
	char buf[BUFSIZ], *cp, *dfile = 0, *subject = 0;
	int tls = 0, i, transaction = 0, rid = 0;
	FILE *fp;
	int res;
	char *certificate = 0;
	char *passwd = 0;
	char *privatekey = 0;
	char *calist = 0;
	char *server = 0;
	char *path, *ruleid, *s;
	SPOCP *spocp;
	queres_t qres;

	spocpc_debug = 0;

	while ((i = getopt(argc, argv, "dhtTua:c:s:f:p:l:")) != EOF) {
		switch (i) {
		case 'a':
			subject = strdup(optarg);
			break;

		case 'c':
			certificate = strdup(optarg);
			break;

		case 'd':
			spocpc_debug = 1;
			break;

		case 'f':
			dfile = strdup(optarg);
			break;

		case 'l':
			calist = strdup(optarg);
			break;

		case 'p':
			privatekey = strdup(optarg);
			break;

		case 's':
			server = strdup(optarg);
			break;

		case 't':
			tls = 1;
			break;

		case 'T':
			transaction = 1;
			break;

		case 'u':
			rid = 1;
			break;

		case 'w':
			passwd = strdup(optarg);
			break;

		case 'h':
		default:
			fprintf(stderr,
			    "Usage: %s -s server -f rulefile [-d] [-T] [-a subject] or\n",
			    argv[0]);
			fprintf(stderr, "%s -t -s server -f rulefile [-d]\n",
			    argv[0]);
			fprintf(stderr,
			    "\t -c certificate -l calist -p privatekey\n");
			fprintf(stderr,
			    "\t -w passwd\n");
			exit(0);
		}
	}

	if (server == 0)
		print_usage(argv[0]);

	spocp = spocpc_init(server, 0, 0);

#ifdef HAVE_SSL
	if (tls) {
		spocpc_use_tls(spocp);
		spocpc_tls_use_cert(spocp, certificate);
		spocpc_tls_use_calist(spocp, calist);
		spocpc_tls_use_key(spocp, privatekey);
		spocpc_tls_use_passwd(spocp, passwd);

		if (tls & DEMAND)
			spocpc_tls_set_demand_server_cert(spocp);
		if (tls & VERIFY)
			spocpc_tls_set_verify_server_cert(spocp);
	}
#else
	{
		fprintf(stderr, "Can't use TLS/SSL, ignoring\n");
		tls = 0;
	}
#endif

	if (spocpc_debug)
		traceLog(LOG_DEBUG,"Spocpserver [%s]", server);

	if ((spocp = spocpc_open(spocp, 0, 5)) == 0) {
		fprintf(stderr, "Could not open connection to \"%s\"\n",
		    server);
		exit(1);
	}

	if (dfile) {
		if ((fp = fopen(dfile, "r")) == 0) {
			fprintf(stderr, "Could not open file \"%s\"\n", dfile);
			exit(1);
		}
	} else {
		if (spocpc_debug)
			traceLog(LOG_DEBUG,"reading stdin");
		fp = stdin;
	}

	memset(&qres, 0, sizeof(queres_t));

#ifdef HAVE_SSL
	if (tls) {
		if (spocpc_attempt_tls(spocp, &qres) == SPOCPC_OK &&
		    qres.rescode == SPOCP_SSL_START) {
			if (spocpc_start_tls(spocp) == 0)
				exit(1);
		} else
			exit(1);
	}
	memset(&qres, 0, sizeof(queres_t));
#endif

	if (transaction) {
		if (spocpc_open_transaction(spocp, &qres) != SPOCPC_OK ||
		    qres.rescode != SPOCP_SUCCESS)
			exit(1);

	}

	while (fgets(buf, BUFSIZ, fp)) {
		cp = &buf[strlen(buf) - 1];
		while (*cp == '\n' || *cp == '\r' || *cp == ' ')
			*cp-- = '\0';

		if (spocpc_debug)
			traceLog(LOG_DEBUG,"Got [%s]", buf);

		if (strncmp(buf, "---", 3) == 0 ||
		    strncmp(buf, "+++", 3) == 0 ||
		    strncmp(buf, "@@", 2) == 0 || *buf == ' ')
			continue;

		s = cp = buf;
		if (*s == ' ')
			continue;

		/* should have path SP [ruleid SP] rule */
		/* should do some error checking here ! */
		path = ++cp;
		cp = index(path, ' ');
		*cp++ = '\0';

		if (rid) {	/* get ruleid */
			ruleid = cp;
			cp = index(ruleid, ' ');
			*cp++ = '\0';
		} else
			ruleid = 0;

		if (spocpc_debug)
			traceLog(LOG_DEBUG,"path [%s]", path);

		memset(&qres, 0, sizeof(queres_t));

		if (*s == '+') {
			if (spocpc_debug)
				traceLog(LOG_DEBUG,"rule [%s]", cp);
			res = spocpc_str_send_add(spocp, path, cp, 0, 0, &qres);
		} else if (rid) {	/* can't do delete without a ruleid */
			if (spocpc_debug)
				traceLog(LOG_DEBUG,"ruleid [%s]", ruleid);
			res = spocpc_str_send_delete(spocp, path, ruleid, &qres);
		} else
			res = SPOCPC_PARAM_ERROR;

		if (res == SPOCPC_OK) {
			if (qres.rescode == SPOCP_SUCCESS)
				printf("OK\n");
			else if (qres.rescode == SPOCP_DENIED)
				printf("DENIED\n");
			else
				printf("ERROR (%d): %s", qres.rescode,
				    qres.str);
		} else
			printf("PROCESS ERROR: %d", res);
	}

	if (transaction) {
		memset(&qres, 0, sizeof(queres_t));
		if (spocpc_commit(spocp, &qres) != SPOCPC_OK ||
		    qres.rescode != SPOCP_SUCCESS)
			printf("ERROR commiting");
	}

	memset(&qres, 0, sizeof(queres_t));
	spocpc_send_logout(spocp);
	spocpc_close(spocp);
	free_spocp(spocp);

	exit(0);
}
Exemplo n.º 28
0
Arquivo: main.c Projeto: Zabrane/SPOCP
int
main(int argc, char **argv)
{
	int             debug = 0, conftest = 0, nodaemon = 0;
	int             i = 0;
	unsigned int    clilen;
	struct sockaddr_in cliaddr;
	struct timeval  start, end;
	char           *cnfg = DEF_CNFG;
	char		localhost[MAXNAMLEN + 1], path[MAXNAMLEN + 1];
	FILE           *pidfp;
	octet_t         oct;
	ruleset_t      *rs;

	/*
	 * Who am I running as ? 
	 */

	uname(&myname);

	/*
	 * spocp_err = 0 ;
	 */

	memset(&srv, 0, sizeof(srv_t));

	pthread_mutex_init(&(srv.mutex), NULL);
	pthread_mutex_init(&(srv.mlock), NULL);

	gethostname(localhost, MAXNAMLEN);
#ifdef HAVE_GETDOMAINNAME
	getdomainname(path, MAXNAMLEN);
#else
	{
		char *pos;
		if(pos = strstr(localhost, ".")) strncpy(path, pos+1, MAXNAMLEN);
		else strcpy(path, "");
	}
#endif

	if (0)
		printf("Domain: %s\n", path);

	srv.hostname = Strdup(localhost);

	/*
	 * truncating input strings to reasonable length
	 */
	for (i = 0; i < argc; i++)
		if (strlen(argv[i]) > 512)
			argv[i][512] = '\0';

	while ((i = getopt(argc, argv, "Dhrtf:d:")) != EOF) {
		switch (i) {

		case 'D':
			nodaemon = 1;
			break;

		case 'f':
			cnfg = Strdup(optarg);
			break;

		case 'd':
			debug = atoi(optarg);
			if (debug < 0)
				debug = 0;
			break;

		case 't':
			conftest = 1;
			break;

		case 'r':
			srv.readonly = 1;

		case 'h':
		default:
			fprintf(stderr, "Usage: %s [-t] ", argv[0]);
			fprintf(stderr, "[-f configfile] ");
			fprintf(stderr, "[-D] [-d debuglevel]\n");
			exit(0);
		}
	}

	srv.root = ruleset_new(0);

	if (srv_init(&srv, cnfg) < 0)
		exit(1);

	if (srv.port && srv.uds) {
		fprintf(stderr,
			"Sorry are not allowed to listen on both a unix domain socket and a port\n");
		exit(1);
	}

	if (srv.logfile)
		spocp_open_log(srv.logfile, debug);
	else if (debug)
		spocp_open_log(0, debug);

	if (srv.name){
		localcontext = (char *) Calloc(strlen(srv.name) + strlen("//") + 1,
				       sizeof(char));

		/* Flawfinder: ignore */
		sprintf(localcontext, "//%s", srv.name);		
	}
	else {
		localcontext = (char *) Calloc(strlen(localhost) + strlen("//") + 1,
				       sizeof(char));

		/* Flawfinder: ignore */
		sprintf(localcontext, "//%s", localhost);
	}

	/*
	 * where I put the access rules for access to this server and its
	 * rules 
	 */
	snprintf(path, MAXNAMLEN, "%s/server", localcontext);
	oct_assign(&oct, path);
	if ((rs = ruleset_create(&oct, srv.root)) == 0)
		exit(1);

	rs->db = db_new();

	/*
	 * access rules for operations 
	 */
	snprintf(path, MAXNAMLEN, "%s/operation", localcontext);
	oct_assign(&oct, path);
	if ((rs = ruleset_create(&oct, srv.root)) == 0)
		exit(1);

	rs->db = db_new();


	LOG(SPOCP_INFO) {
		traceLog(LOG_INFO, "Local context: \"%s\"", localcontext);
		traceLog(LOG_INFO, "initializing backends");
		if (srv.root->db)
			plugin_display(srv.plugin);
	}

	if (srv.plugin) {
		run_plugin_init(&srv);
	}

	if ( get_rules( &srv ) != SPOCP_SUCCESS ) 
		exit(1);

	/*ruleset_tree( srv.root, 0);*/

	/* If only testing configuration and rulefile this is as far as I go */
	if (conftest) {
		traceLog(LOG_INFO,"Configuration was OK");
		exit(0);
	}

	gettimeofday(&start, NULL);

	if (srv.port || srv.uds) {

		/*
		 * stdin and stdout will not be used from here on, close to
		 * save file descriptors 
		 */

		fclose(stdin);
		fclose(stdout);

#ifdef HAVE_SSL
		/*
		 * ---------------------------------------------------------- 
		 */
		/*
		 * build our SSL context, whether it will ever be used or not 
		 */

		/*
		 * mutex'es for openSSL to use 
		 */
		THREAD_setup();

		if (srv.certificateFile && srv.privateKey && srv.caList) {
			traceLog(LOG_INFO,"Initializing the TLS/SSL environment");
			if (!(srv.ctx = tls_init(&srv))) {
				return FALSE;
			}
		}

		/*
		 * ---------------------------------------------------------- 
		 */
#endif

#ifdef HAVE_SASL
		{
			int             r = sasl_server_init(sasl_cb, "spocp");
			if (r != SASL_OK) {
				traceLog( LOG_ERR,
				    "Unable to initialized SASL library: %s",
				     sasl_errstring(r, NULL, NULL));
				return FALSE;
			}
		}
#endif

		saci_init();
		if( nodaemon == 0 ) { 
#ifdef HAVE_DAEMON
			if (daemon(1, 1) < 0) {
				fprintf(stderr, "couldn't go daemon\n");
				exit(1);
			}
#else
			daemon_init("spocp", 0);
#endif
		}

		if (srv.pidfile) {
			/*
			 * Write the PID file. 
			 */
			pidfp = fopen(srv.pidfile, "w");

			if (pidfp == (FILE *) 0) {
				fprintf(stderr,
					"Couldn't open pidfile \"%s\"\n",
					srv.pidfile);
				exit(1);
			}
			fprintf(pidfp, "%d\n", (int) getpid());
			fclose(pidfp);
		}

		if (srv.port) {
			LOG(SPOCP_INFO) traceLog( LOG_INFO,
				"Asked to listen on port %d", srv.port);

			if ((srv.listen_fd =
			     spocp_stream_socket(srv.port)) < 0)
				exit(1);

			srv.id = (char *) Malloc(16);
			sprintf(srv.id, "spocp-%d", srv.port);

			srv.type = AF_INET;
		} else {
			LOG(SPOCP_INFO)
			    traceLog(LOG_INFO,"Asked to listen on unix domain socket");
			if ((srv.listen_fd =
			     spocp_unix_domain_socket(srv.uds)) < 0)
				exit(1);

			srv.id = (char *) Malloc(7 + strlen(srv.uds));
			/* Flawfinder: ignore */
			sprintf(srv.id, "spocp-%s", srv.uds);

			srv.type = AF_UNIX;
		}

		xsignal(SIGCHLD, sig_chld);
		xsignal(SIGPIPE, sig_pipe);
		xsignal(SIGINT, sig_int);
		xsignal(SIGTERM, sig_term);
		xsignal(SIGUSR1, sig_usr1);

		clilen = sizeof(cliaddr);

		DEBUG(SPOCP_DSRV) traceLog(LOG_DEBUG,"Creating threads");
		/*
		 * returns the pool the threads are picking work from 
		 */
		srv.work = tpool_init(srv.threads, 64, 1);

		spocp_srv_run(&srv);

	} else {
		conn_t         *conn;

		saci_init();
		DEBUG(SPOCP_DSRV) traceLog(LOG_DEBUG,"---->");

		LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading STDIN");

		/*
		 * If I want to use this I have to do init_server() first
		 * conn = spocp_open_connection( STDIN_FILENO, &srv ) ; 
		 */
		/*
		 * this is much simpler 
		 */
		conn = conn_new();
		conn_setup(conn, &srv, STDIN_FILENO, "localhost", "127.0.0.1");

		LOG(SPOCP_INFO) traceLog(LOG_INFO,"Running server");

		spocp_server((void *) conn);

		gettimeofday(&end, NULL);

		print_elapsed("query time:", start, end);

		conn_free( conn );
	}

	srv_free( &srv );
	if (cnfg != DEF_CNFG)
		Free( cnfg );

	exit(0);
}
Exemplo n.º 29
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
spocp_result_t
tls_start(conn_t * conn, ruleset_t * rs)
{
	SSL            *ssl;
	SSL_CTX        *ctx = (SSL_CTX *) conn->srv->ctx;
	int             maxbits, r, n = 0;
	char           *sid_ctx = "spocp";
	SSL_CIPHER     *cipher;

	if (conn->ssl != NULL) {
		tls_error(SPOCP_WARNING, conn,
			  "STARTTLS received on already encrypted connection");
		return SPOCP_STATE_VIOLATION;
	}

	if (!(ssl = SSL_new(ctx))) {
		tls_error(SPOCP_ERR, conn, "Error creating SSL context");
		return SPOCP_OPERATIONSERROR;
	}

	/*
	 * do these never fail ?? 
	 */

	SSL_set_session_id_context(ssl, (unsigned char *) sid_ctx,
				   strlen(sid_ctx));

	if (SSL_set_fd(ssl, conn->fd) == 0) {
		traceLog(LOG_ERR,"Couldn't set filedescriptor in SSL");
		return SPOCP_OPERATIONSERROR;
	}

	n = iobuf_content(conn->in);
	traceLog(LOG_INFO,"tls_start: %d bytes in input buffer", n);
	if (n) {
		traceLog(LOG_INFO,"tls_start: %x%x%x%x", conn->in->r[0], conn->in->r[1],
			 conn->in->r[2], conn->in->r[3]);
	}

	LOG(SPOCP_DEBUG)
	    traceLog(LOG_DEBUG,"Waiting for client on %d to initiate handshake",
		     conn->fd);

	/*
	 * waits for the client to initiate the handshake 
	 */
	{
		fd_set rset ; int retval ;
	  
		FD_ZERO( &rset );
		FD_SET( conn->fd, &rset );
		traceLog(LOG_DEBUG, "Waiting for the client" ) ;
		retval = select(conn->fd+1,&rset,NULL,NULL,0) ;
	}
	if ((r = SSL_accept(ssl)) <= 0) {
		int se ;

		if ((se = SSL_get_error(ssl, r)) == SSL_ERROR_WANT_READ) {
			traceLog(LOG_DEBUG,"Want_read");
		} else if (se == SSL_ERROR_SYSCALL) {
			unsigned long err ;

			err = ERR_get_error();
			if( err == 0L && r == 0 ) {
				traceLog(LOG_DEBUG,"EOF observed") ;
			}
			else 
				traceLog(LOG_ERR,"I/O error occured (%ld/%d)", err, r);
		} else {
			traceLog(LOG_ERR,"SSL_get_error: %d", se);
			tls_error(SPOCP_ERR, conn, "SSL accept error");
			SSL_free(ssl);
		}
		conn->status = CNST_ACTIVE;
		return SPOCP_SSL_ERR;
	}
	/*
	 * } 
	 */

	LOG(SPOCP_DEBUG) {
		traceLog(LOG_DEBUG,"SSL accept done");
		traceLog(LOG_DEBUG,"Checking client certificate");
	 }

	if (!check_cert_chain(conn, ssl, rs)) {
		traceLog(LOG_ERR,"Certificate chain check failed");
		SSL_free(ssl);
		conn->status = CNST_ACTIVE;
		return SPOCP_CERT_ERR;
	}

	/*
	 * So the cert is OK and the hostname is in the DN, but do I want to
	 * talk to this guy ?? 
	 */

	cipher = SSL_get_current_cipher(ssl);

	conn->cipher = Strdup((char *) SSL_CIPHER_get_name(cipher));

	conn->ssl_vers = Strdup(SSL_CIPHER_get_version(cipher));

	if (server_access(conn) == 0) {
		traceLog(LOG_ERR,"Client not allowed access");
		SSL_free(ssl);

		conn->status = CNST_ACTIVE;
		return SPOCP_CERT_ERR;
	}

	LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"SSL accept done");

	/*
	 * TLS has been set up. Change input/output to read via TLS instead 
	 */

	conn->readn = ssl_socket_readn;
	conn->writen = ssl_socket_writen;
	conn->close = tls_close;

	conn->ssl = (void *) ssl;
	conn->tls_ssf = SSL_CIPHER_get_bits(cipher, &maxbits);
	conn->status = CNST_ACTIVE;

	return SPOCP_SUCCESS;
}
Exemplo n.º 30
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
/*
 * Check that the common name matches the host name
 */
static int
check_cert_chain(conn_t * conn, SSL * ssl, ruleset_t * rs)
{
	X509           *peer;
	X509_NAME      *xn;
	static char     subject[1024];
	int             r = FALSE, extc;

	if (SSL_get_verify_result(ssl) != X509_V_OK) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"Certificate doesn't verify");
		return FALSE;
	}

	/*
	 * Check the cert chain. The chain length is automatically checked by
	 * OpenSSL when we set the verify depth in the ctx 
	 */

	peer = SSL_get_peer_certificate(ssl);
	if (!peer) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"No peer certificate");
		return TRUE;
	}

	/*
	 * check subjectaltname 
	 */

	if ((extc = X509_get_ext_count(peer)) > 0) {
		int             i;

		for (i = 0; r == FALSE && i < extc; i++) {
			X509_EXTENSION *ext;
			const char     *extstr;

			ext = X509_get_ext(peer, i);
			extstr =
			    OBJ_nid2sn(OBJ_obj2nid
				       (X509_EXTENSION_get_object(ext)));

			if (strcmp(extstr, "subjectAltName") == 0) {
				int             j;
				unsigned char  *data;
				STACK_OF(CONF_VALUE) * val;
				CONF_VALUE     *nval;
				X509V3_EXT_METHOD *meth;

				if ((meth = X509V3_EXT_get(ext)) == 0)
					break;

				data = ext->value->data;

				val =
				    meth->i2v(meth,
					      meth->d2i(NULL, &data,
							ext->value->length),
					      NULL);

				for (j = 0;
				     r == FALSE && i < sk_CONF_VALUE_num(val);
				     j++) {
					nval = sk_CONF_VALUE_value(val, j);
					if (strcasecmp(nval->name, "DNS") == 0
					    && strcasecmp(nval->value,
							  conn->sri.
							  hostname)) {
						r = TRUE;
					}
				}
			}
		}
	}

	if (r == FALSE) {
		/*
		 * Check the subject name 
		 */
		xn = X509_get_subject_name(peer);
		X509_NAME_get_text_by_NID(xn, NID_commonName, subject, 1024);
		subject[1023] = '\0';

		traceLog(LOG_DEBUG,"\"%s\" = \"%s\" ?", subject, conn->sri.hostname);
		if (strcasecmp(subject, conn->sri.hostname) == 0) {
			r = TRUE;
		}
	}

	if (r == TRUE) {
		conn->subjectDN =
		    X509_NAME_oneline(X509_get_subject_name(peer), NULL, 0);
		conn->issuerDN =
		    X509_NAME_oneline(X509_get_issuer_name(peer), NULL, 0);
	}

	X509_free(peer);

	return r;
}