DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦5b304c84d⟧ TextFile

    Length: 15027 (0x3ab3)
    Types: TextFile
    Names: »conn_init.c«

Derivation

└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/quipu/conn_init.c« 

TextFile

/* conn_init.c - deal with incoming association requests */

#ifndef lint
static char *rcsid = "$Header: /f/osi/quipu/RCS/conn_init.c,v 7.2 89/12/19 16:20:03 mrose Exp $";
#endif

/*
 * $Header: /f/osi/quipu/RCS/conn_init.c,v 7.2 89/12/19 16:20:03 mrose Exp $
 *
 *
 * $Log:	conn_init.c,v $
 * Revision 7.2  89/12/19  16:20:03  mrose
 * sync
 * 
 * Revision 7.1  89/11/24  16:21:53  mrose
 * sync
 * 
 * Revision 7.0  89/11/23  22:16:46  mrose
 * Release 6.0
 * 
 */

/*
 *                                NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


#include "acsap.h"
#include "rosap.h"
#include "tsap.h"
#include "quipu/util.h"
#include "quipu/connection.h"

extern LLog * log_dsap;
#ifndef NO_STATS
extern LLog * log_stat;
#endif


Conn    conn_alloc();
void    acs_log();

extern	OID	acse_pci;
extern	OID	x500_da_ac;
extern	OID	x500_ds_ac;
extern	OID	quipu_ds_ac;
extern	struct PSAPctxlist	* x500_da_pcdl;
extern	struct PSAPctxlist	* x500_ds_pcdl;
extern	struct PSAPctxlist	* quipu_ds_pcdl;
extern  time_t time ();

char	  check_acs_ctx(acs_ctx)
OID	  acs_ctx;
{
    DLOG (log_dsap, LLOG_TRACE, ("check_acs_ctx"));

    if(oid_cmp(acs_ctx, x500_da_ac) == 0)
	return(CN_CTX_X500_DAP);

    if(oid_cmp(acs_ctx, x500_ds_ac) == 0)
	return(CN_CTX_X500_DSP);

    if(oid_cmp(acs_ctx, quipu_ds_ac) == 0)
	return(CN_CTX_QUIPU_DSP);

    return(CN_CTX_UNKNOWN);
}

/* ARGSUSED */
int	  judge_ctxlist(req_ctxlist, ok_ctxlist)
struct PSAPctxlist      * req_ctxlist;
struct PSAPctxlist      * ok_ctxlist;
{
    int			  ctxlist_notok = 0;
    int                   i;
    int                   j;
    OID                   ok_asn;
    OID                   req_asn;

    DLOG (log_dsap, LLOG_TRACE, ("judge_ctxlist"));

    for(i=0; i<req_ctxlist->pc_nctx; i++)
    {
	DLOG (log_dsap, LLOG_DEBUG, ("Context (%d): id=%d, %s",
		i,
		req_ctxlist->pc_ctx[i].pc_id,
		oid2ode (req_ctxlist->pc_ctx[i].pc_asn)));

	if(req_ctxlist->pc_ctx[i].pc_result == PC_ACCEPT)
	    req_ctxlist->pc_ctx[i].pc_result = PC_REJECTED;
    }

    for(j=0; j<ok_ctxlist->pc_nctx; j++)
    {
	ok_asn = ok_ctxlist->pc_ctx[j].pc_asn;
	for(i=0; i<req_ctxlist->pc_nctx; i++)
	{
	    if((req_asn = req_ctxlist->pc_ctx[i].pc_asn) == NULLOID) {
		LLOG (log_dsap,LLOG_EXCEPTIONS,( "Reject: asn is NULLOID"));
		continue;
	    }

	    if((oid_cmp(req_asn, ok_asn) == 0))
		break;
	}
	if(i < req_ctxlist->pc_nctx) {
	    req_ctxlist->pc_ctx[i].pc_result = PC_ACCEPT;
	} else {
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("Missing Context: %s", oid2ode (ok_asn)));
	    ctxlist_notok = 1;
	}
    }

#ifdef	DEBUG
    for(i=0; i<req_ctxlist->pc_nctx; i++)
    {
	DLOG(log_dsap, LLOG_DEBUG, ("ctx[%d] id = %d, res = %d.", i,
		req_ctxlist->pc_ctx[i].pc_id,
		req_ctxlist->pc_ctx[i].pc_result));

	if(req_ctxlist->pc_ctx[i].pc_result == PC_REJECTED)
		DLOG (log_dsap, LLOG_DEBUG, ("Context Rejected: id=%d, %s",
			req_ctxlist->pc_ctx[i].pc_id,
			oid2ode (req_ctxlist->pc_ctx[i].pc_asn)));
	    
    }
#endif

    return(ctxlist_notok);
}

int	  find_ctx_id(pcdl, ctx_oid)
struct PSAPctxlist	* pcdl;
OID			  ctx_oid;
{
    int	  i;

    DLOG (log_dsap, LLOG_TRACE, ("find_ctx_id"));

    for(i=0; i<pcdl->pc_nctx; i++)
    {
	if(oid_cmp(ctx_oid, pcdl->pc_ctx[i].pc_asn) == 0)
	    break;
    }

    if(i < pcdl->pc_nctx)
	return(pcdl->pc_ctx[i].pc_id);

    LLOG(log_dsap, LLOG_EXCEPTIONS, ("Couldn't find context identifier %s", sprintoid(ctx_oid)));

    return(NOTOK);
}

conn_init(cn)
Conn                          cn;
{
    struct AcSAPstart           * acs;
    struct AcSAPindication        aci_s;
    struct AcSAPindication      * aci = &aci_s;
    struct AcSAPabort           * aca = &(aci->aci_abort);
    struct TSAPdisconnect       td_s;
    struct TSAPdisconnect       *td = &td_s;
    struct ds_bind_arg          * bind_arg;
    char ** vec;

    DLOG (log_dsap,LLOG_TRACE,( "conn_init()"));

    acs = (struct AcSAPstart *) smalloc(sizeof(struct AcSAPstart));

    vec = cn->cn_init_act.ia_vec;

    watch_dog ("AcInit");
    if(AcInit(cn->cn_init_act.ia_vecp, vec, acs, aci) != OK)
    {
	watch_dog_reset();
	LLOG (log_dsap,LLOG_EXCEPTIONS,( "net_wait_init_request() : AcInit() NOTOK"));
	acs_log(aca, "initialization fails");
	ACAFREE(aca);
	conn_extract (cn);
	free((char *)acs);
	return;
    }

    watch_dog_reset();
    DLOG (log_dsap,LLOG_TRACE,( "net_wait_init_request() : AcInit() OK"));

   /*
    * Log the arrival of a connection request.
    */
    DLOG (log_dsap,LLOG_NOTICE,
		("A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d> <%s>",
		acs->acs_sd, oid2ode(acs->acs_context),
		sprintaei (&acs->acs_callingtitle),
		sprintaei (&acs->acs_calledtitle), acs->acs_ninfo,
		paddr2str (&(acs->acs_start.ps_calling), NULLNA)));

    if(SetROPS(acs->acs_sd) != OK)
    {
	DLOG (log_dsap,LLOG_NOTICE,( "Calling AcUAbort directly (no cn)"));
#ifndef NO_STATS
	LLOG (log_stat,LLOG_EXCEPTIONS,("Failed association: %s",paddr2str(&(acs->acs_start.ps_calling),NULLNA)));
#endif
	(void) AcUAbortRequest(acs->acs_sd, NULLPEP, 0, aci);
	ACSFREE(acs);
	conn_extract (cn);
	free((char *)acs);
	return;
    }

    cn->cn_ad = acs->acs_sd;
    cn->cn_initiator = INITIATED_BY_THAT;
    cn->cn_init_act.ia_acs = acs;
    LLOG (log_dsap,LLOG_NOTICE, ("Association (%d) from %s",
	   cn->cn_ad, paddr2str(&(acs->acs_start.ps_calling),NULLNA)));

    /*
    *	Peel off the remote operations BIND tag. Continue
    *	if it is not present even though this is in error.
    */
    if (acs->acs_info[0] != NULLPE)
    {
	PE	  pe;

	pe = pe_cpy (acs->acs_info[0]);
	pe_free(acs->acs_info[0]);
	if (parse_Remote__Operations__Notation_BindArgumentValue (pe, 
		1, NULL, NULLCP, &acs->acs_info[0]) != OK)
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("parse_Remote__Operations__Notation_BindArgumentValue failed - continuing"));
	    acs->acs_info[0] = pe_cpy(pe);
	}
	pe_free (pe);
    }
    else
    {
	LLOG (log_dsap, LLOG_EXCEPTIONS, ("No DirectoryBindArgument"));
	conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0);
	return;
    }

    /*
    * Check application context.
    */
    switch(cn->cn_ctx = check_acs_ctx(acs->acs_context))
    {
    case CN_CTX_X500_DAP:

#ifndef NO_STATS
		LLOG (log_stat,LLOG_NOTICE,("X500 DAP context association (%d): %s",cn->cn_ad,
			paddr2str(&(acs->acs_start.ps_calling),NULLNA)));
#endif

	if(judge_ctxlist(&(acs->acs_start.ps_ctxlist), x500_da_pcdl) == 0)
	{
	    cn->cn_context_id = find_ctx_id(&(acs->acs_start.ps_ctxlist), DIR_ACCESS_AS);
	}
	else
	{
	    LLOG(log_dsap,LLOG_EXCEPTIONS, ("Unacceptable Abstract Syntaxes for X.500 DAP"));
	    cn->cn_context_id = NOTOK;
	    conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0);
	    return;
	}
    break;

    case CN_CTX_X500_DSP:

#ifndef NO_STATS
	LLOG (log_stat,LLOG_NOTICE,("X500 DSP context association (%d): %s",cn->cn_ad,
		paddr2str(&(acs->acs_start.ps_calling),NULLNA)));
#endif

	if(judge_ctxlist(&(acs->acs_start.ps_ctxlist), x500_ds_pcdl) == 0)
	{
	    cn->cn_context_id = find_ctx_id(&(acs->acs_start.ps_ctxlist), DIR_SYSTEM_AS);
	}
	else
	{
	    LLOG(log_dsap,LLOG_EXCEPTIONS, ("Unacceptable Abstract Syntaxes for X.500 DSP"));
	    cn->cn_context_id = NOTOK;
	    conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0);
	    return;
	}
    break;

    case CN_CTX_QUIPU_DSP:

#ifndef NO_STATS
	LLOG (log_stat,LLOG_NOTICE,("QUIPU DSP context association (%d): %s",cn->cn_ad,
		paddr2str(&(acs->acs_start.ps_calling),NULLNA)));
#endif

	if(judge_ctxlist(&(acs->acs_start.ps_ctxlist), quipu_ds_pcdl) == 0)
	{
	    cn->cn_context_id = find_ctx_id(&(acs->acs_start.ps_ctxlist), DIR_QUIPU_AS);
	}
	else
	{
	    LLOG(log_dsap,LLOG_EXCEPTIONS, ("Unacceptable Abstract Syntaxes for QUIPU DSP"));
	    cn->cn_context_id = NOTOK;
	    conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0);
	    return;
	}
    break;

    default:

#ifndef NO_STATS
	LLOG (log_stat,LLOG_EXCEPTIONS,("UNKNOWN context association (%d): %s",cn->cn_ad,
		paddr2str(&(acs->acs_start.ps_calling),NULLNA)));
#endif

	cn->cn_context_id = NOTOK;
	conn_respond(cn, ACS_TRANSIENT, ACS_CONTEXT, NULLPEP, 0);
	return;
    }

    /*
    *  The following takes advantage of the fact that all 3 contexts
    *  have the same BIND ARGUMENT.
    */
    if(cn->cn_context_id != NOTOK)
    {
	bind_arg = &(cn->cn_init_act.ia_req);
	if(decode_DAS_DirectoryBindArgument(
	      acs->acs_info[0], 1, NULLCP, NULLIP, bind_arg) == OK)
	{
	    DLOG(log_dsap,LLOG_DEBUG, ("Bind Argument decoded"));
	    (void) dn_decode(bind_arg->dba_dn);
	    cn->cn_who = dn_cpy(bind_arg->dba_dn);
	    if(cn->cn_ctx != CN_CTX_X500_DAP)
	    {
		cn->cn_what = dn_cpy(bind_arg->dba_dn);
	    }
	}
	else
	{
	    LLOG (log_dsap,LLOG_EXCEPTIONS,( "Unable to parse DirectoryBindArgument"));
	    conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0);
	    return;
	}
    }

    /*
    *  If we haven't returned yet then the protocol for binding has been
    *  satisfactorily completed.
    *  Now attempt to perform the ds_bind for the argument decoded, which
    *  can either succeed, fail or suspend waiting for a remote compare.
    *  If a remote compare has been scheduled then return, otherwise
    *  complete the connection initialisation by sending an AcAssocResponse.
    */

    if (TSetQueuesOK (cn->cn_ad, 1, td) == NOTOK) 
	td_log (td, "TSetQueuesOK (incoming)");

    switch(ds_bind_init(cn))
    {
    case DS_OK:
	conn_init_res(cn);
	break;
    case DS_ERROR_CONNECT:
	conn_init_err(cn);
	break;
    case DS_CONTINUE:
	cn->cn_state = CN_INDICATED;
	break;
    default:
	LLOG(log_dsap, LLOG_EXCEPTIONS, ("Unexpected return by ds_bind_init"));
	conn_respond(cn, ACS_TRANSIENT, ACS_USER_NOREASON, NULLPEP, 0);
	break;
    }
}

conn_init_res(cn)
struct connection       * cn;
{
    PE		  data;
    PE		  ro_data;
    PE		* ro_datap = &(ro_data);
    int		  ndata;
    int		  status = ACS_ACCEPT;
    int		  reason = ACS_USER_NULL;

    DLOG(log_dsap,LLOG_TRACE, ("conn_init_res()"));

    *ro_datap = NULLPE;

    if(encode_DAS_DirectoryBindResult(&data, 1,
	NULLIP, NULLCP, &(cn->cn_init_act.ia_res)) == OK)
    {
	DLOG(log_dsap,LLOG_TRACE, ("Encoded DirectoryBindResult"));
	if (build_Remote__Operations__Notation_BindResultValue (ro_datap, 1, NULL, NULLCP, data) == OK)
	{
	    DLOG(log_dsap,LLOG_TRACE, ("Built BindResultValue"));
	    ndata = 1;
	}
	else
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("build_Remote__Operations__Notation_BindResultValue failed"));
	    status = ACS_TRANSIENT;
	    reason = ACS_USER_NOREASON;
	    ndata = 0;
	}
	pe_free(data);
    }
    else
    {
	LLOG(log_dsap,LLOG_EXCEPTIONS, ("Failed to encode DirectoryBindResult"));
	status = ACS_TRANSIENT;
	reason = ACS_USER_NOREASON;
	ndata = 0;
    }

    if(ndata != 0)
    {
	(*ro_datap) -> pe_context = cn->cn_context_id;
    }

    conn_respond(cn, status, reason, ro_datap, ndata);

    if (ro_data != NULLPE)
	pe_free (ro_data);
}

conn_init_err(cn)
struct connection       * cn;
{
    PE                          data;
    PE                          ro_data;
    PE				*ro_datap = &(ro_data);
    int                         ndata;
    int				  status = ACS_ACCEPT;
    int				  reason = ACS_USER_NULL;

    DLOG(log_dsap,LLOG_TRACE, ("conn_init_err()"));

    *ro_datap = NULLPE;

#ifndef NO_STATS
    LLOG (log_stat,LLOG_EXCEPTIONS,("Bind (%d) rejected",cn->cn_ad));
#endif
    LLOG (log_dsap,LLOG_NOTICE,("association %d rejected - authentication failed",cn->cn_ad));

    if(encode_DAS_DirectoryBindError(&data, 1,
	NULLIP, NULLCP, &(cn->cn_init_act.ia_err)) == OK)
    {
	DLOG(log_dsap,LLOG_TRACE, ("Encoded DirectoryBindError"));
	if (build_Remote__Operations__Notation_BindErrorValue (ro_datap, 1, NULL, NULLCP, data) == OK)
	{
	    DLOG(log_dsap,LLOG_TRACE, ("Built BindErrorValue"));
	    status = ACS_PERMANENT;
	    reason = ACS_USER_NOREASON;
	    ndata = 1;
	}
	else
	{
	    LLOG (log_dsap, LLOG_EXCEPTIONS, ("build_Remote__Operations__Notation_BindErrorValue failed"));
	    status = ACS_TRANSIENT;
	    reason = ACS_USER_NOREASON;
	    ndata = 0;
	}
	pe_free(data);
    }
    else
    {
	LLOG(log_dsap,LLOG_EXCEPTIONS, ("Failed to encode DirectoryBindError"));
	status = ACS_TRANSIENT;
	reason = ACS_USER_NOREASON;
	ndata = 0;
    }

    if(ndata != 0)
    {
	(*ro_datap) -> pe_context = cn->cn_context_id;
    }

    conn_respond(cn, status, reason, ro_datap, ndata);

    if (ro_data != NULLPE)
	pe_free (ro_data);
}

conn_respond(cn, status, reason, data_p, ndata)
struct connection       * cn;
int	  status;
int	  reason;
PE	* data_p;
int	  ndata;
{
    struct AcSAPindication      aci_s;
    struct AcSAPindication      *aci = &aci_s;
    struct AcSAPabort           *aca = &aci->aci_abort;
    struct AcSAPstart           * acs = cn->cn_init_act.ia_acs;
    struct PSAPstart            * ps = &(acs->acs_start);

    DLOG(log_dsap,LLOG_TRACE, ("conn_respond()"));

    DLOG(log_dsap,LLOG_NOTICE, ("A-ASSOCIATE.RESPONSE: %s%s%s", 
		AcErrString (status),
	        ((status == ACS_ACCEPT) ? "" : ", "),
	        ((status == ACS_ACCEPT) ? "" : AcErrString (reason))));

#ifdef DEBUG
    {
	int	  i;

	for(i=0; i<ps->ps_ctxlist.pc_nctx; i++)
	{
	    DLOG(log_dsap, LLOG_DEBUG, ("ctx[%d] id = %d, res = %d.", i,
		ps->ps_ctxlist.pc_ctx[i].pc_id,
		ps->ps_ctxlist.pc_ctx[i].pc_result));
	}
    }
#endif

    watch_dog ("AcAssocResponse");
    if(AcAssocResponse(cn->cn_ad, status, reason,
      acs->acs_context, NULLAEI, mydsaaddr, &(ps->ps_ctxlist),
      ps->ps_defctxresult, PR_MYREQUIRE, ROS_MYREQUIRE, SERIAL_NONE,
      ps->ps_settings, &(ps->ps_connect), data_p, ndata, aci) == OK)
    {
	watch_dog_reset();
	DLOG(log_dsap,LLOG_TRACE, ("AcAssocResponse OK"));
	if(status == ACS_ACCEPT)
	{
	    cn->cn_state = CN_OPEN;
	}
	else
	{
	    DLOG(log_dsap,LLOG_TRACE, ("status != ACS_ACCEPT"));
	    DLOG(log_dsap, LLOG_DEBUG, ("conn_respond calling conn_extract 1"));
	    conn_extract(cn);
	}
    }
    else
    {
	watch_dog_reset();
	acs_log(aca, "A-ASSOCIATE.RESPONSE");
	ACAFREE(aca);
	DLOG(log_dsap, LLOG_DEBUG, ("conn_respond calling conn_extract 2"));
	conn_extract(cn);
    }

    ACSFREE(acs);
    free ((char *) acs);
}


conn_pre_init(newfd, vecp, vec)
int newfd;
int	  vecp;
char	**vec;
{
    Conn                          cn;

    cn = conn_alloc();

    cn->cn_next = connlist;
    connlist = cn;
    conns_used++;

    cn->cn_ad = newfd;
    cn->cn_initiator = INITIATED_BY_THAT;

    cn->cn_init_act.ia_vecp = vecp;
    if (vec[0])
	cn->cn_init_act.ia_vec[0] = strdup (vec[0]);
    if (vec[1])
	cn->cn_init_act.ia_vec[1] = strdup (vec[1]);
    if (vec[2])
	cn->cn_init_act.ia_vec[2] = strdup (vec[2]);
    if (vec[3])
	cn->cn_init_act.ia_vec[3] = strdup (vec[3]);

    cn->cn_state = CN_OPENING;

    cn->cn_last_used = time ((time_t*)0);

    if (newfd == NOTOK)
	conn_init (cn);
    else 
	DLOG (log_dsap,LLOG_NOTICE, ("opening association on %d",newfd ));
}