|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 15027 (0x3ab3)
Types: TextFile
Names: »conn_init.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z«
└─⟦de7628f85⟧
└─⟦this⟧ »isode-6.0/quipu/conn_init.c«
/* 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 ));
}