/* * Function: TelnetSessionInspection(Packet *p, * FTPTELNET_GLOBAL_CONF *GlobalConf, * FTPP_SI_INPUT *SiInput, * int *piInspectMode) * * Purpose: The Session Inspection module selects the appropriate * configuration for the session, and the type of inspection * to be performed (client or server.) * * When the Session Inspection module is in stateful mode, it * checks to see if there is a TELNET_SESSION pointer already * associated with the stream. If there is, then it uses that * session pointer, otherwise it calculates the server configuration * using the FTP_SI_INPUT and returns a TELNET_SESSION pointer. In * stateful mode, this means that memory is allocated, but in * stateless mode, the same session pointer is used for all packets * to reduce the allocation overhead. * * The inspection mode can be either client or server. * * Arguments: p => pointer to the packet/stream * GlobalConf => pointer to the global configuration * Session => double pointer to the Session structure * SiInput => pointer to the session information * piInspectMode => pointer for setting inspection mode * * Returns: int => return code indicating error or success * */ int TelnetSessionInspection(SFSnortPacket *p, FTPTELNET_GLOBAL_CONF *GlobalConf, TELNET_SESSION **TelnetSession, FTPP_SI_INPUT *SiInput, int *piInspectMode) { int iRet; int iTelnetSip; int iTelnetDip; #ifdef TARGET_BASED int16_t app_id = SFTARGET_UNKNOWN_PROTOCOL; /* If possible, use Stream API to determine protocol. */ if (_dpd.streamAPI) { app_id = _dpd.streamAPI->get_application_protocol_id(p->stream_session_ptr); } if (app_id == SFTARGET_UNKNOWN_PROTOCOL) { return FTPP_INVALID_PROTO; } if (app_id == telnet_app_id) { if (SiInput->pdir == FTPP_SI_CLIENT_MODE || SiInput->pdir == FTPP_SI_SERVER_MODE) { *piInspectMode = (int)SiInput->pdir; } } else if (app_id && app_id != telnet_app_id) { return FTPP_INVALID_PROTO; } else { #endif iTelnetSip = PortMatch((PROTO_CONF*)GlobalConf->telnet_config, SiInput->sport); iTelnetDip = PortMatch((PROTO_CONF*)GlobalConf->telnet_config, SiInput->dport); if (iTelnetSip) { *piInspectMode = FTPP_SI_SERVER_MODE; } else if (iTelnetDip) { *piInspectMode = FTPP_SI_CLIENT_MODE; } else { return FTPP_INVALID_PROTO; } #ifdef TARGET_BASED } #endif /* * We get the server configuration and the session structure differently * depending on what type of inspection we are doing. In the case of * stateful processing, we may get the session structure from the Stream * Reassembly module (which includes the server configuration) or the * structure will be allocated and added to the stream pointer for the * rest of the session. * * In stateless mode, we just use a static variable that is contained in * the function here. */ if(GlobalConf->inspection_type == FTPP_UI_CONFIG_STATEFUL) { iRet = TelnetStatefulSessionInspection(p, GlobalConf, TelnetSession, SiInput); if (iRet) return iRet; } else { /* Assume stateless processing otherwise */ iRet = TelnetStatelessSessionInspection(p, GlobalConf, TelnetSession, SiInput); if (iRet) return iRet; } return FTPP_SUCCESS; }
/* * 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; }
/* * Function: TelnetSessionInspection(Packet *p, * FTPTELNET_GLOBAL_CONF *GlobalConf, * FTPP_SI_INPUT *SiInput, * int *piInspectMode) * * Purpose: The Session Inspection module selects the appropriate * configuration for the session, and the type of inspection * to be performed (client or server.) * * When the Session Inspection module is in stateful mode, it * checks to see if there is a TELNET_SESSION pointer already * associated with the stream. If there is, then it uses that * session pointer, otherwise it calculates the server configuration * using the FTP_SI_INPUT and returns a TELNET_SESSION pointer. In * stateful mode, this means that memory is allocated, but in * stateless mode, the same session pointer is used for all packets * to reduce the allocation overhead. * * The inspection mode can be either client or server. * * Arguments: p => pointer to the packet/stream * GlobalConf => pointer to the global configuration * Session => double pointer to the Session structure * SiInput => pointer to the session information * piInspectMode => pointer for setting inspection mode * * Returns: int => return code indicating error or success * */ int TelnetSessionInspection(SFSnortPacket *p, FTPTELNET_GLOBAL_CONF *GlobalConf, FTPP_SI_INPUT *SiInput, int *piInspectMode) { TELNET_SESSION *TelnetSession; int iRet; int iTelnetSip; int iTelnetDip; iTelnetSip = PortMatch((PROTO_CONF*)&GlobalConf->global_telnet, SiInput->sport); iTelnetDip = PortMatch((PROTO_CONF*)&GlobalConf->global_telnet, SiInput->dport); if (iTelnetSip) { *piInspectMode = FTPP_SI_SERVER_MODE; } else if (iTelnetDip) { *piInspectMode = FTPP_SI_CLIENT_MODE; } else { return FTPP_INVALID_PROTO; } SiInput->pproto = FTPP_SI_PROTO_TELNET; /* * We get the server configuration and the session structure differently * depending on what type of inspection we are doing. In the case of * stateful processing, we may get the session structure from the Stream * Reassembly module (which includes the server configuration) or the * structure will be allocated and added to the stream pointer for the * rest of the session. * * In stateless mode, we just use a static variable that is contained in * the function here. */ if(GlobalConf->inspection_type == FTPP_UI_CONFIG_STATEFUL) { iRet = TelnetStatefulSessionInspection(p, GlobalConf, &TelnetSession, SiInput); if (iRet) { return iRet; } if (p->stream_session_ptr) { _dpd.streamAPI->set_application_data(p->stream_session_ptr, PP_TELNET, TelnetSession, &TelnetFreeSession); } else { /* Uh, can't create the session info */ /* Free session data, to avoid memory leak */ TelnetFreeSession(TelnetSession); return FTPP_NONFATAL_ERR; } } else { /* * Assume stateless processing otherwise */ iRet = TelnetStatelessSessionInspection(p, GlobalConf, &TelnetSession, SiInput); if (iRet) { return iRet; } if (p->stream_session_ptr) { /* Set the free function pointer to NULL, * since this is a static one */ _dpd.streamAPI->set_application_data(p->stream_session_ptr, PP_TELNET, TelnetSession, NULL); } else { /* Uh, can't create the session info */ return FTPP_NONFATAL_ERR; } } SiInput->pproto = FTPP_SI_PROTO_TELNET; return FTPP_SUCCESS; }