/*
 * Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

/*
**  SMTPS - SMAR communication module
*/

#include "sm/generic.h"
SM_RCSID("@(#)$Id: s2a.c,v 1.22 2007/10/23 03:57:40 ca Exp $")

#include "sm/assert.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/reccom.h"
#include "statethreads/st.h"
#include "sm/rcbst.h"
#include "sm/stthreads.h"
#include "smtps-str.h"
#include "s2q.h"
#include "smtps.h"

#include "sm/smar.h"
#include "log.h"

/*
**  SM_S2A_RCPT -- send recipient to SMAR
**
**	Parameters:
**		ss_sess -- session context
**		s2a_ctx -- S2A context
**		tid -- transaction id
**		rcpt_idx -- rcpt idx
**		lt -- lookup type
**		lfl -- lookup flags
**		rcpt -- rcpt to address
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_s2a_rcptid(ss_sess_P ss_sess, s2q_ctx_P s2a_ctx, sessta_id_P tid, int rcpt_idx, uint32_t lt, uint32_t lfl, sm_str_P rcpt)
{
	sm_ret_T ret;
	sm_rcb_P rcb;

	SM_REQUIRE(s2a_ctx != NULL);
	SM_IS_SS_SESS(ss_sess);

	rcb = ss_sess->ssse_rcb;
	ret = sm_rcb_putrec(rcb, RCB_PUTR_DFLT, 0, -1,
		SM_RCBV_INT, RT_PROT_VER, PROT_VER_RT,
		SM_RCBV_INT, RT_S2A_ID, s2a_ctx->s2q_ss_ctx->ssc_id,
		SM_RCBV_BUF, RT_S2A_TAID, tid, SMTP_STID_SIZE,
		SM_RCBV_STR, RT_S2A_RCPT, rcpt,
		SM_RCBV_INT, RT_S2A_RCPT_IDX, rcpt_idx,
		SM_RCBV_INT2, RT_S2A_LTYPE, lt, lfl,
		SM_RCBV_STR,
			SSC_IS_CFLAG(ss_sess->ssse_sctx, SSC_CFL_PROTBYMAIL)
			? RT_S2A_MAIL : RT_NOSEND,
			ss_sess->ssse_ta->ssta_mail->ssm_pa,
		SM_RCBV_INT,
			(SSC_IS_CFLAG(ss_sess->ssse_sctx, SSC_CFL_PROTBYCLTADDR)
			|| SM_IS_FLAG(lt, SMARA_LT_GREY))
			? RT_S2A_IPV4 : RT_NOSEND,
			(uint32_t) ss_sess->ssse_client.s_addr,
		SM_RCBV_INT,
			SM_IS_FLAG(lt, SMARA_LT_GREY)
			? RT_S2A_TIME : RT_NOSEND,
			(uint32_t) ss_sess->ssse_connect,
		SM_RCBV_END);
	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_rcptid, sess=%p, sm_rcb_putrec=%m\n",
			ss_sess, ret));
		goto error;
	}
	ret = ss_send_rq(ss_sess, tid, s2a_ctx, rcb, true);
	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_rcptid, sess=%p, ss_send_rq=%m\n",
			ss_sess, ret));
		goto error;
	}
	return SM_SUCCESS;

  error:
	return ret;
}

/*
**  SM_S2A_ADDR -- send (mail) address to SMAR
**
**	Parameters:
**		ss_sess -- session context
**		s2a_ctx -- S2A context
**		tid -- transaction id
**		addr -- mail from address
**		what -- record type
**		ltype -- lookup type
**		lflags -- lookup flags
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_s2a_addr(ss_sess_P ss_sess, s2q_ctx_P s2a_ctx, sessta_id_P tid, sm_str_P addr, uint32_t what, uint32_t ltype, uint32_t lflags)
{
	sm_ret_T ret;
	sm_rcb_P rcb;

	SM_REQUIRE(s2a_ctx != NULL);
	SM_IS_SS_SESS(ss_sess);

	rcb = ss_sess->ssse_rcb;
	ret = sm_rcb_putrec(rcb, RCB_PUTR_DFLT, 0, -1,
		SM_RCBV_INT, RT_PROT_VER, PROT_VER_RT,
		SM_RCBV_INT, RT_S2A_ID, s2a_ctx->s2q_ss_ctx->ssc_id,
		SM_RCBV_BUF, RT_S2A_TAID, tid, SMTP_STID_SIZE,
		SM_RCBV_STR, what, addr,
		SM_RCBV_INT2, RT_S2A_LTYPE, ltype, lflags,
		SM_RCBV_END);
	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_addr, sess=%p, sm_rcb_putrec=%m\n",
			ss_sess, ret));
		goto error;
	}
	ret = ss_send_rq(ss_sess, tid, s2a_ctx, rcb, true);
	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_addr, sess=%p, ss_send_rq=%m\n",
			ss_sess, ret));
		goto error;
	}
	return SM_SUCCESS;

  error:
	rcb = ss_sess->ssse_rcb;
	return ret;
}

/*
**  SM_S2A_CLT -- send client address to SMAR
**
**	Parameters:
**		ss_sess -- session context
**		s2a_ctx -- S2A context
**		sid -- session id
**		addr -- address
**		what -- record type
**		ltype -- lookup type
**		lflags -- lookup flags
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_s2a_clt(ss_sess_P ss_sess, s2q_ctx_P s2a_ctx, sessta_id_P sid, sm_str_P clt, uint32_t what, uint32_t ltype, uint32_t lflags)
{
	sm_ret_T ret;
	sm_rcb_P rcb;

	SM_REQUIRE(s2a_ctx != NULL);
	SM_IS_SS_SESS(ss_sess);

#if SS_TEST
	if (SM_IS_FLAG(s2a_ctx->s2q_ss_ctx->ssc_cnf.ss_cnf_tests, SS_TEST_S2A_FAIL))
	{
		ret = sm_error_perm(SM_EM_AQ, SM_E_FULL);
		goto error;
	}
#endif
	rcb = ss_sess->ssse_rcb;
	ret = sm_rcb_putrec(rcb, RCB_PUTR_DFLT, 0, -1,
		SM_RCBV_INT, RT_PROT_VER, PROT_VER_RT,
		SM_RCBV_INT, RT_S2A_ID, s2a_ctx->s2q_ss_ctx->ssc_id,
		SM_RCBV_BUF, RT_S2A_SEID, sid, SMTP_STID_SIZE,
		SM_RCBV_STR, what, clt,
		SM_RCBV_INT2, RT_S2A_LTYPE, ltype, lflags,
		SM_RCBV_END);
	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_clt, sess=%p, sm_rcb_putrec=%m\n",
			ss_sess, ret));
		goto error;
	}
	ret = ss_send_rq(ss_sess, sid, s2a_ctx, rcb, true);
	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_clt, sess=%p, ss_send_rq=%m\n",
			ss_sess, ret));
		goto error;
	}
	return SM_SUCCESS;

  error:
	return ret;
}

#if MTA_USE_TLS
/*
**  SM_S2A_TLS -- send TLS related information to SMAR
**
**	Parameters:
**		ss_sess -- session context
**		s2a_ctx -- S2A context
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_s2a_tls(ss_sess_P ss_sess, s2q_ctx_P s2a_ctx)
{
	sm_ret_T ret;
	sm_rcb_P rcb;

	SM_REQUIRE(s2a_ctx != NULL);
	SM_IS_SS_SESS(ss_sess);

	rcb = ss_sess->ssse_rcb;
	ret = sm_rcb_putrec(rcb, RCB_PUTR_DFLT, 0, -1,
		SM_RCBV_INT, RT_PROT_VER, PROT_VER_RT,
		SM_RCBV_INT, RT_S2A_ID, s2a_ctx->s2q_ss_ctx->ssc_id,
		SM_RCBV_BUF, RT_S2A_SEID, ss_sess->ssse_id, SMTP_STID_SIZE,
		SM_RCBV_STR, RT_S2A_CERTISS,
			ss_sess->ssse_tlsi->tlsi_cert_issuer,
		SM_RCBV_INT2, RT_S2A_LTYPE, SMARA_LT_CERT_RELAY, SMARA_LFL_CERT,
		SM_RCBV_STR, RT_S2A_CERTSUB,
			ss_sess->ssse_tlsi->tlsi_cert_subject,
		SM_RCBV_END);

	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_tls, sess=%p, sm_rcb_putrec=%m\n",
			ss_sess, ret));
		goto error;
	}
	ret = ss_send_rq(ss_sess, ss_sess->ssse_id, s2a_ctx, rcb, true);
	if (sm_is_err(ret))
	{
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_tls, sess=%p, ss_send_rq=%m\n",
			ss_sess, ret));
		goto error;
	}
	return SM_SUCCESS;

  error:
	rcb = ss_sess->ssse_rcb;
	return ret;
}
#endif /* MTA_USE_TLS */

#if SS_EHLO_ACCESS_CHK
/*
**  SM_S2A_STR -- send string to SMAR
**
**	Parameters:
**		ss_sess -- session context
**		s2a_ctx -- S2A context
**		sid -- session id
**		str -- string
**		lt -- lookup type
**		lfl -- lookup flags
**
**	Returns:
**		usual sm_error code
*/

sm_ret_T
sm_s2a_str(ss_sess_P ss_sess, s2q_ctx_P s2a_ctx, sessta_id_P sid, sm_str_P str, uint32_t rt, uint32_t lt, uint32_t lfl)
{
	sm_ret_T ret;
	sm_rcb_P rcb;

	SM_REQUIRE(s2a_ctx != NULL);
	SM_IS_SS_SESS(ss_sess);

	rcb = ss_sess->ssse_rcb;
	ret = sm_rcb_putrec(rcb, RCB_PUTR_DFLT, 0, -1,
		SM_RCBV_INT, RT_PROT_VER, PROT_VER_RT,
		SM_RCBV_INT, RT_S2A_ID, s2a_ctx->s2q_ss_ctx->ssc_id,
		SM_RCBV_BUF, RT_S2A_SEID, sid, SMTP_STID_SIZE,
		SM_RCBV_STR, rt, str,
		SM_RCBV_INT2, RT_S2A_LTYPE, lt, lfl,
		SM_RCBV_END);
	if (sm_is_err(ret)) {
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_str, sess=%p, sm_rcb_putrec=%m\n",
			ss_sess, ret));
		goto error;
	}
	ret = ss_send_rq(ss_sess, sid, s2a_ctx, rcb, true);
	if (sm_is_err(ret)) {
		SSQ_DPRINTF((smioerr,
			"sev=ERROR, func=sm_s2a_str, sess=%p, ss_send_rq=%m\n",
			ss_sess, ret));
		goto error;
	}
	return SM_SUCCESS;

  error:
	return ret;
}
#endif /* SS_EHLO_ACCESS_CHK */


syntax highlighted by Code2HTML, v. 0.9.1