Example #1
0
/*
 * Function: FTPInitConf(Packet *p, FTPTELNET_GLOBAL_CONF *GlobalConf,
 *                       FTP_CLIENT_PROTO_CONF **ClientConf,
 *                       FTP_SERVER_PROTO_CONF **ServerConf,
 *                       FTPP_SI_INPUT *SiInput, int *piInspectMode)
 *
 * Purpose: When a session is initialized, we must select the appropriate
 *          server configuration and select the type of inspection based
 *          on the source and destination ports.
 *
 * IMPORTANT NOTE:
 *   We should check to make sure that there are some unique configurations,
 *   otherwise we can just default to the global default and work some magic
 *   that way.
 *
 * Arguments: p                 => pointer to the Packet/Session
 *            GlobalConf        => pointer to the global configuration
 *            ClientConf        => pointer to the address of the client
 *                                 config so we can set it.
 *            ServerConf        => pointer to the address of the server
 *                                 config so we can set it.
 *            SiInput           => pointer to the packet info
 *            piInspectMode     => pointer so we can set the inspection mode
 *
 * Returns: int => return code indicating error or success
 *
 */
static int FTPInitConf(SFSnortPacket *p, FTPTELNET_GLOBAL_CONF *GlobalConf,
                          FTP_CLIENT_PROTO_CONF **ClientConf,
                          FTP_SERVER_PROTO_CONF **ServerConf,
                          FTPP_SI_INPUT *SiInput, int *piInspectMode)
{
    FTP_CLIENT_PROTO_CONF *ClientConfSip;
    FTP_CLIENT_PROTO_CONF *ClientConfDip;
    FTP_SERVER_PROTO_CONF *ServerConfSip;
    FTP_SERVER_PROTO_CONF *ServerConfDip;
    int iServerSip;
    int iServerDip;
    int iErr = 0;
    int iRet = FTPP_SUCCESS;
#ifdef TARGET_BASED
    int16_t app_id = 0;
#endif
    snort_ip sip;
    snort_ip dip;

    //structure copy
    sip = SiInput->sip;
    dip = SiInput->dip;

    if (sip.family == AF_INET)
    {
        sip.ip.u6_addr32[0] = ntohl(sip.ip.u6_addr32[0]);
    }
    if (dip.family == AF_INET)
    {
        dip.ip.u6_addr32[0] = ntohl(dip.ip.u6_addr32[0]);
    }

    /*
     * We find the client configurations for both the source and dest IPs.
     * There should be a check on the global configuration to see if there
     * is at least one unique client configuration.  If there isn't then we
     * assume the global client configuration.
     */
    ClientConfDip = ftpp_ui_client_lookup_find(GlobalConf->client_lookup,
            &dip,
            &iErr);

    if(!ClientConfDip)
    {
        ClientConfDip = GlobalConf->default_ftp_client;
    }

    ClientConfSip = ftpp_ui_client_lookup_find(GlobalConf->client_lookup,
            &sip,
            &iErr);

    if(!ClientConfSip)
    {
        ClientConfSip = GlobalConf->default_ftp_client;
    }

    /*
     * Now, we find the server configurations for both the source and dest IPs.
     * There should be a check on the global configuration to see if there
     * is at least one unique client configuration.  If there isn't then we
     * assume the global client configuration.
     */
    ServerConfDip = ftpp_ui_server_lookup_find(GlobalConf->server_lookup,
            &dip,
            &iErr);

    if(!ServerConfDip)
    {
        ServerConfDip = GlobalConf->default_ftp_server;
    }

    ServerConfSip = ftpp_ui_server_lookup_find(GlobalConf->server_lookup,
            &sip,
            &iErr);

    if(!ServerConfSip)
    {
        ServerConfSip = GlobalConf->default_ftp_server;
    }

    /*
     * We check the IP and the port to see if the FTP client is talking in
     * the session.  This should tell us whether it is client communication
     * or server configuration.  If both IPs and ports are servers, then there
     * is a sort of problem.  We don't know which side is the client and which
     * side is the server so we have to assume one.
     *
     * In stateful processing, we only do this stage on the startup of a
     * session, so we can still assume that the initial packet is the client
     * talking.
     */
    iServerDip = PortMatch((PROTO_CONF*)ServerConfDip, SiInput->dport);
    iServerSip = PortMatch((PROTO_CONF*)ServerConfSip, SiInput->sport);

    /*
     * We default to the no FTP traffic case
     */
    *piInspectMode = FTPP_SI_NO_MODE;
    *ClientConf = NULL;
    *ServerConf = NULL;

    /*
     * Depending on the type of packet direction we get from the
     * state machine, we evaluate client/server differently.
     */
    switch(SiInput->pdir)
    {
        case FTPP_SI_NO_MODE:

#ifdef TARGET_BASED
            app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr);

            if (app_id == ftp_app_id || app_id == 0)
            {
#endif

            /*
             * We check for the case where both SIP and DIP
             * appear to be servers.  In this case, we assume server
             * and process that way.
             */
            if(iServerSip && iServerDip)
            {
                /*
                 * We check for the case where both SIP and DIP
                 * appear to be servers.  In this case, we look at
                 * the first few bytes of the packet to try to
                 * determine direction -- 3 digits indicate server
                 * response.
                 */

                /* look at the first few bytes of the packet.  We might
                 * be wrong if this is a reassembled packet and we catch
                 * a server response mid-stream.
                 */
                *piInspectMode = FTPGetPacketDir(p);
                if (*piInspectMode == FTPP_SI_SERVER_MODE)
                {
                    /* Packet is from server --> src is Server */
                    *ClientConf = ClientConfDip;
                    *ServerConf = ServerConfSip;
                }
                else /* Assume client */
                {
                    /* Packet is from client --> dest is Server */
                    *piInspectMode = FTPP_SI_CLIENT_MODE;
                    *ClientConf = ClientConfSip;
                    *ServerConf = ServerConfDip;
                }
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else if(iServerDip)
            {
                /* Packet is from client --> dest is Server */
                *piInspectMode = FTPP_SI_CLIENT_MODE;
                *ClientConf = ClientConfSip;
                *ServerConf = ServerConfDip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else if(iServerSip)
            {
                /* Packet is from server --> src is Server */
                *piInspectMode = FTPP_SI_SERVER_MODE;
                *ClientConf = ClientConfDip;
                *ServerConf = ServerConfSip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            break;

#ifdef TARGET_BASED
            }
#endif

        case FTPP_SI_CLIENT_MODE:
            /* Packet is from client --> dest is Server */
#ifdef TARGET_BASED
            app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr);

            if ((app_id == ftp_app_id) || (!app_id && iServerDip))
#else
            if(iServerDip)
#endif
            {
                *piInspectMode = FTPP_SI_CLIENT_MODE;
                *ClientConf = ClientConfSip;
                *ServerConf = ServerConfDip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else
            {
                *piInspectMode = FTPP_SI_NO_MODE;
                iRet = FTPP_NONFATAL_ERR;
            }
            break;

        case FTPP_SI_SERVER_MODE:
            /* Packet is from server --> src is Server */
#ifdef TARGET_BASED
            app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr);

            if ((app_id == ftp_app_id) || (!app_id && iServerSip))
#else
            if(iServerSip)
#endif
            {
                *piInspectMode = FTPP_SI_SERVER_MODE;
                *ClientConf = ClientConfDip;
                *ServerConf = ServerConfSip;
                SiInput->pproto = FTPP_SI_PROTO_FTP;
            }
            else
            {
                *piInspectMode = FTPP_SI_NO_MODE;
                iRet = FTPP_NONFATAL_ERR;
            }
            break;

        default:
            *piInspectMode = FTPP_SI_NO_MODE;
            *ClientConf = NULL;
            *ServerConf = NULL;
            break;
    }

    return iRet;
}
Example #2
0
/*
 * Function: FTPStatefulSessionInspection(Packet *p,
 *                          FTPTELNET_GLOBAL_CONF *GlobalConf,
 *                          FTP_SESSION **FtpSession,
 *                          FTPP_SI_INPUT *SiInput, int *piInspectMode)
 *
 * Purpose: Initialize the session and server configurations for this
 *          packet/stream.  In this function, we set the Session pointer
 *          (which includes the correct server configuration).  The actual
 *          processing to find which IP is the server and which is the
 *          client, is done in the InitServerConf() function.
 *
 * Arguments: p                 => pointer to the Packet/Session
 *            GlobalConf        => pointer to the global configuration
 *            Session           => double pointer to the Session structure
 *            SiInput           => pointer to the session information
 *            piInspectMode     => pointer so the inspection mode can be set
 *
 * Returns: int => return code indicating error or success
 *
 */
static int FTPStatefulSessionInspection(SFSnortPacket *p,
        FTPTELNET_GLOBAL_CONF *GlobalConf,
        FTP_SESSION **FtpSession,
        FTPP_SI_INPUT *SiInput, int *piInspectMode)
{
    FTP_CLIENT_PROTO_CONF *ClientConf;
    FTP_SERVER_PROTO_CONF *ServerConf;
    int iRet;
    FTP_SESSION *NewSession;

    /*
     * First, check if there is already a session pointer.
     */
    if (p->stream_session_ptr)
    {
        *FtpSession =
            _dpd.streamAPI->get_application_data(p->stream_session_ptr, PP_FTPTELNET);
        if (*FtpSession)
        {
            if (SiInput->pdir != FTPP_SI_NO_MODE)
            {
                *piInspectMode = SiInput->pdir;
            }
            else
            {
                FTP_SESSION *tmp = *FtpSession;
                /* check session pointer server conf port */

                if (tmp->server_conf && tmp->server_conf->proto_ports.ports[SiInput->sport])
                    *piInspectMode = FTPP_SI_SERVER_MODE;
                else if (tmp->server_conf && tmp->server_conf->proto_ports.ports[SiInput->dport])
                    *piInspectMode = FTPP_SI_CLIENT_MODE;
                else
                    *piInspectMode = FTPGetPacketDir(p);
            }

            return FTPP_SUCCESS;
        }
    }

    /*
     * If not, create a new one, and initialize it.
     */
    iRet = FTPInitConf(p, GlobalConf, &ClientConf, &ServerConf, SiInput, piInspectMode);
    if (iRet)
    {
        return iRet;
    }

    if (*piInspectMode)
    {
        NewSession = (FTP_SESSION *)calloc(1, sizeof(FTP_SESSION));
        if (NewSession == NULL)
        {
            DynamicPreprocessorFatalMessage("%s(%d) => Failed to allocate memory for new FTP session\n",
                                            *(_dpd.config_file), *(_dpd.config_line));
        }

        FTPResetSession(NewSession, 1);

        NewSession->client_conf = ClientConf;
        NewSession->server_conf = ServerConf;
        NewSession->global_conf = GlobalConf;

        *FtpSession = NewSession;
        return FTPP_SUCCESS;
    }

    return FTPP_INVALID_PROTO;
}