/* * 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 */