⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demux.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
/* demultiplex incoming IKE messages * Copyright (C) 1997 Angelos D. Keromytis. * Copyright (C) 1998-2002  D. Hugh Redelmeier. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * for more details. * * RCSID $Id: demux.c,v 1.187 2004/12/09 06:24:29 mcr Exp $ *//* Ordering Constraints on Payloads * * rfc2409: The Internet Key Exchange (IKE) * * 5 Exchanges: *   "The SA payload MUST precede all other payloads in a phase 1 exchange." * *   "Except where otherwise noted, there are no requirements for ISAKMP *    payloads in any message to be in any particular order." * * 5.3 Phase 1 Authenticated With a Revised Mode of Public Key Encryption: * *   "If the HASH payload is sent it MUST be the first payload of the *    second message exchange and MUST be followed by the encrypted *    nonce. If the HASH payload is not sent, the first payload of the *    second message exchange MUST be the encrypted nonce." * *   "Save the requirements on the location of the optional HASH payload *    and the mandatory nonce payload there are no further payload *    requirements. All payloads-- in whatever order-- following the *    encrypted nonce MUST be encrypted with Ke_i or Ke_r depending on the *    direction." * * 5.5 Phase 2 - Quick Mode * *   "In Quick Mode, a HASH payload MUST immediately follow the ISAKMP *    header and a SA payload MUST immediately follow the HASH." *   [NOTE: there may be more than one SA payload, so this is not *    totally reasonable.  Probably all SAs should be so constrained.] * *   "If ISAKMP is acting as a client negotiator on behalf of another *    party, the identities of the parties MUST be passed as IDci and *    then IDcr." * *   "With the exception of the HASH, SA, and the optional ID payloads, *    there are no payload ordering restrictions on Quick Mode." *//* Unfolding of Identity -- a central mystery * * This concerns Phase 1 identities, those of the IKE hosts. * These are the only ones that are authenticated.  Phase 2 * identities are for IPsec SAs. * * There are three case of interest: * * (1) We initiate, based on a whack command specifying a Connection. *     We know the identity of the peer from the Connection. * * (2) (to be implemented) we initiate based on a flow from our client *     to some IP address. *     We immediately know one of the peer's client IP addresses from *     the flow.  We must use this to figure out the peer's IP address *     and Id.  To be solved. * * (3) We respond to an IKE negotiation. *     We immediately know the peer's IP address. *     We get an ID Payload in Main I2. * *     Unfortunately, this is too late for a number of things: *     - the ISAKMP SA proposals have already been made (Main I1) *       AND one accepted (Main R1) *     - the SA includes a specification of the type of ID *       authentication so this is negotiated without being told the ID. *     - with Preshared Key authentication, Main I2 is encrypted *       using the key, so it cannot be decoded to reveal the ID *       without knowing (or guessing) which key to use. * *     There are three reasonable choices here for the responder: *     + assume that the initiator is making wise offers since it *       knows the IDs involved.  We can balk later (but not gracefully) *       when we find the actual initiator ID *     + attempt to infer identity by IP address.  Again, we can balk *       when the true identity is revealed.  Actually, it is enough *       to infer properties of the identity (eg. SA properties and *       PSK, if needed). *     + make all properties universal so discrimination based on *       identity isn't required.  For example, always accept the same *       kinds of encryption.  Accept Public Key Id authentication *       since the Initiator presumably has our public key and thinks *       we must have / can find his.  This approach is weakest *       for preshared key since the actual key must be known to *       decrypt the Initiator's ID Payload. *     These choices can be blended.  For example, a class of Identities *     can be inferred, sufficient to select a preshared key but not *     sufficient to infer a unique identity. */#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/time.h>	/* only used for belt-and-suspenders select call */#include <sys/poll.h>	/* only used for forensic poll call */#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/queue.h>#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)#  include <asm/types.h>	/* for __u8, __u32 */#  include <linux/errqueue.h>#  include <sys/uio.h>	/* struct iovec */#endif#include <openswan.h>#include "constants.h"#include "oswlog.h"#include "defs.h"#include "cookie.h"#include "id.h"#include "x509.h"#include "pgp.h"#include "certs.h"#include "smartcard.h"#ifdef XAUTH_USEPAM#include <security/pam_appl.h>#endif#include "connections.h"	/* needs id.h */#include "state.h"#include "packet.h"#include "md5.h"#include "sha1.h"#include "crypto.h" /* requires sha1.h and md5.h */#include "ike_alg.h"#include "log.h"#include "demux.h"	/* needs packet.h */#include "ipsec_doi.h"	/* needs demux.h and state.h */#include "timer.h"#include "whack.h"	/* requires connections.h */#include "server.h"#ifdef XAUTH#include "xauth.h"#endif#ifdef NAT_TRAVERSAL#include "nat_traversal.h"#endif#include "vendor.h"/* This file does basic header checking and demux of * incoming packets. *//* forward declarations */static bool read_packet(struct msg_digest *md);static void process_packet(struct msg_digest **mdp);/* Reply messages are built in this buffer. * Only one state transition function can be using it at a time * so suspended STFs must save and restore it. * It could be an auto variable of complete_state_transition except for the fact * that when a suspended STF resumes, its reply message buffer * must be at the same location -- there are pointers into it. */u_int8_t reply_buffer[MAX_OUTPUT_UDP_SIZE];/* state_microcode is a tuple of information parameterizing certain * centralized processing of a packet.  For example, it roughly * specifies what payloads are expected in this message. * The microcode is selected primarily based on the state. * In Phase 1, the payload structure often depends on the * authentication technique, so that too plays a part in selecting * the state_microcode to use. */struct state_microcode {    enum state_kind state, next_state;    lset_t flags;    lset_t req_payloads;	/* required payloads (allows just one) */    lset_t opt_payloads;	/* optional payloads (any mumber) */    /* if not ISAKMP_NEXT_NONE, process_packet will emit HDR with this as np */    u_int8_t first_out_payload;    enum event_type timeout_event;    state_transition_fn *processor;};/* State Microcode Flags, in several groups *//* Oakley Auth values: to which auth values does this entry apply? * Most entries will use SMF_ALL_AUTH because they apply to all. * Note: SMF_ALL_AUTH matches 0 for those circumstances when no auth * has been set. */#define SMF_ALL_AUTH	LRANGE(0, OAKLEY_AUTH_ROOF-1)#define SMF_PSK_AUTH	LELEM(OAKLEY_PRESHARED_KEY)#define SMF_DS_AUTH	(LELEM(OAKLEY_DSS_SIG) | LELEM(OAKLEY_RSA_SIG))#define SMF_PKE_AUTH	(LELEM(OAKLEY_RSA_ENC) | LELEM(OAKLEY_ELGAMAL_ENC))#define SMF_RPKE_AUTH	(LELEM(OAKLEY_RSA_ENC_REV) | LELEM(OAKLEY_ELGAMAL_ENC_REV))/* misc flags */#define SMF_INITIATOR	LELEM(OAKLEY_AUTH_ROOF + 0)#define SMF_FIRST_ENCRYPTED_INPUT	LELEM(OAKLEY_AUTH_ROOF + 1)#define SMF_INPUT_ENCRYPTED	LELEM(OAKLEY_AUTH_ROOF + 2)#define SMF_OUTPUT_ENCRYPTED	LELEM(OAKLEY_AUTH_ROOF + 3)#define SMF_RETRANSMIT_ON_DUPLICATE	LELEM(OAKLEY_AUTH_ROOF + 4)#define SMF_ENCRYPTED (SMF_INPUT_ENCRYPTED | SMF_OUTPUT_ENCRYPTED)/* this state generates a reply message */#define SMF_REPLY   LELEM(OAKLEY_AUTH_ROOF + 5)/* this state completes P1, so any pending P2 negotiations should start */#define SMF_RELEASE_PENDING_P2	LELEM(OAKLEY_AUTH_ROOF + 6)/* if we have canoncalized the authentication from XAUTH mode */#define SMF_XAUTH_AUTH  LELEM(OAKLEY_AUTH_ROOF + 7)/* end of flags */static state_transition_fn	/* forward declaration */    unexpected,    informational;/* state_microcode_table is a table of all state_microcode tuples. * It must be in order of state (the first element). * After initialization, ike_microcode_index[s] points to the * first entry in state_microcode_table for state s. * Remember that each state name in Main or Quick Mode describes * what has happened in the past, not what this message is. */static const struct state_microcode    *ike_microcode_index[STATE_IKE_ROOF - STATE_IKE_FLOOR];static const struct state_microcode state_microcode_table[] = {#define PT(n) ISAKMP_NEXT_##n#define P(n) LELEM(PT(n))    /***** Phase 1 Main Mode *****/    /* No state for main_outI1: --> HDR, SA */    /* STATE_MAIN_R0: I1 --> R1     * HDR, SA --> HDR, SA     */    { STATE_MAIN_R0, STATE_MAIN_R1    , SMF_ALL_AUTH | SMF_REPLY    , P(SA), P(VID) | P(CR), PT(NONE)    , EVENT_RETRANSMIT, main_inI1_outR1},    /* STATE_MAIN_I1: R1 --> I2     * HDR, SA --> auth dependent     * SMF_PSK_AUTH, SMF_DS_AUTH: --> HDR, KE, Ni     * SMF_PKE_AUTH:     *	--> HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r     * SMF_RPKE_AUTH:     *	--> HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]     * Note: since we don't know auth at start, we cannot differentiate     * microcode entries based on it.     */    { STATE_MAIN_I1, STATE_MAIN_I2    , SMF_ALL_AUTH | SMF_INITIATOR | SMF_REPLY    , P(SA), P(VID) | P(CR), PT(NONE) /* don't know yet */    , EVENT_RETRANSMIT, main_inR1_outI2 },    /* STATE_MAIN_R1: I2 --> R2     * SMF_PSK_AUTH, SMF_DS_AUTH: HDR, KE, Ni --> HDR, KE, Nr     * SMF_PKE_AUTH: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r     *	    --> HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i     * SMF_RPKE_AUTH:     *	    HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i, <IDi1_b>Ke_i [,<<Cert-I_b>Ke_i]     *	    --> HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r     */    { STATE_MAIN_R1, STATE_MAIN_R2    , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY#ifdef NAT_TRAVERSAL    , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(KE)#else    , P(KE) | P(NONCE), P(VID) | P(CR), PT(KE)#endif    , EVENT_RETRANSMIT, main_inI2_outR2 },    { STATE_MAIN_R1, STATE_UNDEFINED    , SMF_PKE_AUTH | SMF_REPLY    , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR) | P(HASH), PT(KE)    , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },    { STATE_MAIN_R1, STATE_UNDEFINED    , SMF_RPKE_AUTH | SMF_REPLY    , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR) | P(HASH) | P(CERT), PT(NONCE)    , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },    /* for states from here on, output message must be encrypted */    /* STATE_MAIN_I2: R2 --> I3     * SMF_PSK_AUTH: HDR, KE, Nr --> HDR*, IDi1, HASH_I     * SMF_DS_AUTH: HDR, KE, Nr --> HDR*, IDi1, [ CERT, ] SIG_I     * SMF_PKE_AUTH: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i     *	    --> HDR*, HASH_I     * SMF_RPKE_AUTH: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r     *	    --> HDR*, HASH_I     */    { STATE_MAIN_I2, STATE_MAIN_I3    , SMF_PSK_AUTH | SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY#ifdef NAT_TRAVERSAL    , P(KE) | P(NONCE), P(VID) | P(CR) | P(NATD_RFC), PT(ID)#else    , P(KE) | P(NONCE), P(VID) | P(CR), PT(ID)#endif    , EVENT_RETRANSMIT, main_inR2_outI3 },    { STATE_MAIN_I2, STATE_UNDEFINED    , SMF_PKE_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY    , P(KE) | P(ID) | P(NONCE), P(VID) | P(CR), PT(HASH)    , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },    { STATE_MAIN_I2, STATE_UNDEFINED    , SMF_ALL_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY    , P(NONCE) | P(KE) | P(ID), P(VID) | P(CR), PT(HASH)    , EVENT_RETRANSMIT, unexpected /* ??? not yet implemented */ },    /* for states from here on, input message must be encrypted */    /* STATE_MAIN_R2: I3 --> R3     * SMF_PSK_AUTH: HDR*, IDi1, HASH_I --> HDR*, IDr1, HASH_R     * SMF_DS_AUTH: HDR*, IDi1, [ CERT, ] SIG_I --> HDR*, IDr1, [ CERT, ] SIG_R     * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_I --> HDR*, HASH_R     */    { STATE_MAIN_R2, STATE_MAIN_R3    , SMF_PSK_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED      | SMF_REPLY | SMF_RELEASE_PENDING_P2    , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)    , EVENT_SA_REPLACE, main_inI3_outR3 },    { STATE_MAIN_R2, STATE_MAIN_R3    , SMF_DS_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED      | SMF_REPLY | SMF_RELEASE_PENDING_P2    , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)    , EVENT_SA_REPLACE, main_inI3_outR3 },    { STATE_MAIN_R2, STATE_UNDEFINED    , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED      | SMF_REPLY | SMF_RELEASE_PENDING_P2    , P(HASH), P(VID) | P(CR), PT(NONE)    , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },    /* STATE_MAIN_I3: R3 --> done     * SMF_PSK_AUTH: HDR*, IDr1, HASH_R --> done     * SMF_DS_AUTH: HDR*, IDr1, [ CERT, ] SIG_R --> done     * SMF_PKE_AUTH, SMF_RPKE_AUTH: HDR*, HASH_R --> done     * May initiate quick mode by calling quick_outI1     */    { STATE_MAIN_I3, STATE_MAIN_I4    , SMF_PSK_AUTH | SMF_INITIATOR      | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2    , P(ID) | P(HASH), P(VID) | P(CR), PT(NONE)    , EVENT_SA_REPLACE, main_inR3 },    { STATE_MAIN_I3, STATE_MAIN_I4    , SMF_DS_AUTH | SMF_INITIATOR      | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2    , P(ID) | P(SIG), P(VID) | P(CR) | P(CERT), PT(NONE)    , EVENT_SA_REPLACE, main_inR3 },    { STATE_MAIN_I3, STATE_UNDEFINED    , SMF_PKE_AUTH | SMF_RPKE_AUTH | SMF_INITIATOR      | SMF_FIRST_ENCRYPTED_INPUT | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2    , P(HASH), P(VID) | P(CR), PT(NONE)    , EVENT_SA_REPLACE, unexpected /* ??? not yet implemented */ },    /* STATE_MAIN_R3: can only get here due to packet loss */    { STATE_MAIN_R3, STATE_UNDEFINED    , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RETRANSMIT_ON_DUPLICATE    , LEMPTY, LEMPTY    , PT(NONE), EVENT_NULL, unexpected },    /* STATE_MAIN_I4: can only get here due to packet loss */    { STATE_MAIN_I4, STATE_UNDEFINED    , SMF_ALL_AUTH | SMF_INITIATOR | SMF_ENCRYPTED    , LEMPTY, LEMPTY    , PT(NONE), EVENT_NULL, unexpected },    /***** Phase 1 Aggressive Mode *****/    /* No state for aggr_outI1: -->HDR, SA, KE, Ni, IDii */    /* STATE_AGGR_R0:     * SMF_PSK_AUTH: HDR, SA, KE, Ni, IDii     *                -->  HDR, SA, KE, Nr, IDir, HASH_R     * SMF_DS_AUTH:  HDR, KE, Nr, SIG --> HDR*, IDi1, HASH_I     */    { STATE_AGGR_R0, STATE_AGGR_R1,      SMF_PSK_AUTH| SMF_REPLY,      P(SA) | P(KE) | P(NONCE) | P(ID), P(VID), PT(NONE),      EVENT_RETRANSMIT, aggr_inI1_outR1_psk },    { STATE_AGGR_R0, STATE_AGGR_R1,      SMF_DS_AUTH | SMF_REPLY,      P(SA) | P(KE) | P(NONCE) | P(ID), P(VID), PT(NONE),      EVENT_RETRANSMIT, aggr_inI1_outR1_rsasig },    /* STATE_AGGR_I1:     * SMF_PSK_AUTH: HDR, SA, KE, Nr, IDir, HASH_R     *                                 --> HDR*, HASH_I     * SMF_DS_AUTH: HDR, SA, KE, Nr, IDir, SIG_R     *                                 --> HDR*, SIG_I     */    { STATE_AGGR_I1, STATE_AGGR_I2,      SMF_PSK_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2,      P(SA) | P(KE) | P(NONCE) | P(ID) | P(HASH), P(VID) | P(NATD_RFC) , PT(NONE),      EVENT_SA_REPLACE, aggr_inR1_outI2 },    { STATE_AGGR_I1, STATE_AGGR_I2,      SMF_DS_AUTH | SMF_INITIATOR | SMF_OUTPUT_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2,      P(SA) | P(KE) | P(NONCE) | P(ID) | P(SIG), P(VID) | P(NATD_RFC) , PT(NONE),

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -