using namespace snort;
-#define FTP_PORT 21
+#define FTP_PORT 21
enum FTPState
{
tcp_patterns =
{
- { (const uint8_t*)FTP_PATTERN1, sizeof(FTP_PATTERN1) - 1, 0, 0, 0 },
- { (const uint8_t*)FTP_PATTERN2, sizeof(FTP_PATTERN2) - 1, 0, 0, 0 },
+ { (const uint8_t*)FTP_PATTERN1, sizeof(FTP_PATTERN1) - 1, 0, 0, 0 },
+ { (const uint8_t*)FTP_PATTERN2, sizeof(FTP_PATTERN2) - 1, 0, 0, 0 },
{ (const uint8_t*)FTP_PATTERN3, sizeof(FTP_PATTERN3) - 1, -1, 0, 0 },
{ (const uint8_t*)FTP_PATTERN4, sizeof(FTP_PATTERN4) - 1, -1, 0, 0 }
};
appid_registry =
{
{ APP_ID_FTP_CONTROL, APPINFO_FLAG_SERVICE_ADDITIONAL },
- { APP_ID_FTP_ACTIVE, APPINFO_FLAG_SERVICE_ADDITIONAL },
+ { APP_ID_FTP_ACTIVE, APPINFO_FLAG_SERVICE_ADDITIONAL },
{ APP_ID_FTP_PASSIVE, APPINFO_FLAG_SERVICE_ADDITIONAL },
- { APP_ID_FTPS, APPINFO_FLAG_SERVICE_ADDITIONAL }
+ { APP_ID_FTPS, APPINFO_FLAG_SERVICE_ADDITIONAL }
};
service_ports =
static inline void CopyVendorString(ServiceFTPData& fd, const uint8_t* vendor, unsigned int
vendorLen)
{
- unsigned int copyLen = vendorLen < sizeof(fd.vendor)-1 ? vendorLen : sizeof(fd.vendor)-1;
+ unsigned int copyLen = vendorLen < sizeof(fd.vendor) - 1 ? vendorLen : sizeof(fd.vendor) - 1;
memcpy(fd.vendor, vendor, copyLen);
fd.vendor[copyLen] = '\0';
}
static inline void CopyVersionString(ServiceFTPData& fd, const uint8_t* version, unsigned int
versionLen)
{
- unsigned int copyLen = versionLen < sizeof(fd.version)-1 ? versionLen : sizeof(fd.version)-1;
- while (copyLen > 0 && !isalnum(version[copyLen-1]))
+ unsigned int copyLen = versionLen < sizeof(fd.version) - 1 ? versionLen :
+ sizeof(fd.version) - 1;
+ while (copyLen > 0 && !isalnum(version[copyLen - 1]))
{
copyLen--;
}
int ret = 0; // no match
p = &data[init_offset];
- end = &data[offset-1];
+ end = &data[offset - 1];
/* Search for the vendorCandidate string */
if (vvp_parse_type == VVP_PARSE_WU)
{
ver = p + versionLen;
p = ver;
verlen = 0;
- while (p < end && *p && *p != ' ' )
+ while (p < end && *p && *p != ' ')
{
p++; verlen++;
}
CopyVersionString(fd, ver, verlen);
}
}
- else if ((p=service_strstr(p, end-p, vendorCandidate, vendorCandidateLen)))
+ else if ((p = service_strstr(p, end - p, vendorCandidate, vendorCandidateLen)))
{
/* Found vendorCandidate string */
CopyVendorString(fd, vendorCandidate, vendorCandidateLen);
if (optionalVersion)
{
/* Search for the version string */
- if ((p = service_strstr(p, end-p, optionalVersion, versionLen)))
+ if ((p = service_strstr(p, end - p, optionalVersion, versionLen)))
{
/* Found the version string. Move just past the version string */
ver = p + versionLen;
}
break;
case VVP_PARSE_MS:
- while (p < end && *p && *p != ')' )
+ while (p < end && *p && *p != ')')
{
p++; verlen++;
}
break;
case VVP_PARSE_PRO_FTPD:
- while (p < end && *p && *p != ' ' )
+ while (p < end && *p && *p != ' ')
{
p++; verlen++;
}
{
case VVP_PARSE_HP:
return VendorVersionParse(data, init_offset, offset,fd,
- ven_hp, sizeof(ven_hp)-1,
- ver_hp, sizeof(ver_hp)-1,
+ ven_hp, sizeof(ven_hp) - 1,
+ ver_hp, sizeof(ver_hp) - 1,
VVP_PARSE_HP);
case VVP_PARSE_FILEZILLA:
return VendorVersionParse(data, init_offset, offset,fd,
- ven_fzilla, sizeof(ven_fzilla)-1,
- ver_fzilla, sizeof(ver_fzilla)-1,
+ ven_fzilla, sizeof(ven_fzilla) - 1,
+ ver_fzilla, sizeof(ver_fzilla) - 1,
VVP_PARSE_FILEZILLA);
case VVP_PARSE_MS:
return VendorVersionParse(data, init_offset, offset,fd,
- ven_ms, sizeof(ven_ms)-1,
- ver_ms, sizeof(ver_ms)-1,
+ ven_ms, sizeof(ven_ms) - 1,
+ ver_ms, sizeof(ver_ms) - 1,
VVP_PARSE_MS);
case VVP_PARSE_WU:
return VendorVersionParse(data, init_offset, offset,fd,
- ven_wu, sizeof(ven_wu)-1,
- ver_wu, sizeof(ver_wu)-1,
+ ven_wu, sizeof(ven_wu) - 1,
+ ver_wu, sizeof(ver_wu) - 1,
VVP_PARSE_WU);
case VVP_PARSE_PRO_FTPD:
return VendorVersionParse(data, init_offset, offset,fd,
- ven_proftpd, sizeof(ven_proftpd)-1,
- (const uint8_t*)" ", sizeof(" ")-1,
+ ven_proftpd, sizeof(ven_proftpd) - 1,
+ (const uint8_t*)" ", sizeof(" ") - 1,
VVP_PARSE_PRO_FTPD);
case VVP_PARSE_PURE_FTPD:
return VendorVersionParse(data, init_offset, offset,fd,
- ven_pureftpd, sizeof(ven_pureftpd)-1,
+ ven_pureftpd, sizeof(ven_pureftpd) - 1,
nullptr, 0,
VVP_PARSE_PURE_FTPD);
case VVP_PARSE_NC_FTPD:
return VendorVersionParse(data, init_offset, offset,fd,
- ven_ncftpd, sizeof(ven_ncftpd)-1,
+ ven_ncftpd, sizeof(ven_ncftpd) - 1,
nullptr, 0,
VVP_PARSE_NC_FTPD);
}
return FTP_NOT_FOUND_EOL;
}
-static bool check_ret_digit_code(const uint8_t* code_raw, int start_digit_place, int end_digit_place, int& code, const ServiceFTPData& fd)
+static bool check_ret_digit_code(const uint8_t* code_raw, int start_digit_place,
+ int end_digit_place, int& code, const ServiceFTPData& fd)
{
bool ret = true;
for (int index = 0; start_digit_place >= end_digit_place; start_digit_place--, index++)
switch (start_digit_place)
{
case 3:
- if (code_raw[index] >='1' and code_raw[index] <= '5')
+ if (code_raw[index] >= '1' and code_raw[index] <= '5')
code += (code_raw[index] - '0') * 100;
else
ret = false;
break;
case 2:
- if (ret and fd.rstate == FTP_REPLY_BEGIN and code_raw[index ] >='0' and code_raw[index] <= '5')
+ if (ret and fd.rstate == FTP_REPLY_BEGIN and code_raw[index] >='0'
+ and code_raw[index] <= '5')
code += (code_raw[index] - '0') * 10;
- else if (ret and fd.rstate != FTP_REPLY_BEGIN and code_raw[index ] >='1' and code_raw[index] <= '5')
+ else if (ret and fd.rstate != FTP_REPLY_BEGIN and code_raw[index] >='1'
+ and code_raw[index] <= '5')
code += (code_raw[index] - '0') * 10;
else
ret = false;
break;
case 1:
- if (ret and isdigit(code_raw[index ]))
+ if (ret and isdigit(code_raw[index]))
code += (code_raw[index] - '0') ;
else
ret = false;
return ret;
}
-static int ftp_validate_reply(const uint8_t* data, uint16_t& offset,
- uint16_t size, ServiceFTPData& fd)
+static int ftp_validate_reply(const uint8_t* data, uint16_t& offset, uint16_t size,
+ ServiceFTPData& fd)
{
const ServiceFTPCode* code_hdr;
- int tmp = 0 ;
+ int tmp = 0;
bool ret_code;
+ FtpEolReturn parse_ret;
FTPReplyState tmp_state;
for (; offset < size; ++offset)
code_hdr = (const ServiceFTPCode*)(data + offset);
fd.code = 0;
- ret_code = check_ret_digit_code(code_hdr->code, 3,1, fd.code, fd );
+ ret_code = check_ret_digit_code(code_hdr->code, 3, 1, fd.code, fd);
if(!ret_code)
return -1;
const unsigned char* end;
const unsigned char* p;
const unsigned char* ver;
- end = &data[size-1];
+ end = &data[size - 1];
for (p=&data[offset]; p<end and *p and *p!='('; p++)
;
if (p < end)
p++;
const unsigned char* ven = p;
- for (; p<end and *p and *p!=' '; p++)
- ;
+ for (; p<end and *p and *p!=' '; p++);
if (p < end and *p)
{
CopyVendorString(fd, ven, p-ven);
ver = p + 1;
- for (p=ver; p<end and *p and *p!=':'; p++)
- ;
+ for (p=ver; p<end and *p and *p!=':'; p++);
if (p>=end or !(*p))
- {
- for (p=ver; p<end and *p and *p!=')'; p++)
- ;
- }
+ for (p=ver; p<end and *p and *p!=')'; p++);
if (p < end and *p)
{
CopyVersionString(fd, ver, p-ver);
fd.rstate = FTP_REPLY_MID;
- if ( ftp_parse_response(data, offset, size, fd, tmp_state ) == FTP_INCORRECT_EOL)
+ if (ftp_parse_response(data, offset, size, fd, tmp_state) == FTP_INCORRECT_EOL)
return -1;
if (fd.rstate == FTP_REPLY_MID)
fd.rstate = FTP_REPLY_LONG;
{
fd.rstate = FTP_REPLY_MID;
int temp = offset;
- FtpEolReturn parse_ret = ftp_parse_response(data, offset, size, fd, FTP_REPLY_MULTI);
- if( parse_ret == FTP_INCORRECT_EOL)
+ parse_ret = ftp_parse_response(data, offset, size, fd,
+ FTP_REPLY_MULTI);
+ if (parse_ret == FTP_INCORRECT_EOL)
return -1;
else if (parse_ret == FTP_PARTIAL_EOL)
fd.rstate = FTP_REPLY_PARTIAL_EOL;
else if (parse_ret == FTP_NOT_FOUND_EOL)
{
- ret_code = check_ret_digit_code((data+temp), 3, 4 - (size - (temp)), fd.part_code_resp, fd );
+ ret_code = check_ret_digit_code((data+temp), 3, 4 - (size - (temp)),
+ fd.part_code_resp, fd );
if(!ret_code)
return -1;
fd.rstate = FTP_REPLY_PARTIAL_RESP;
- fd.part_code_len = 3 - (size - (temp ));
+ fd.part_code_len = 3 - (size - (temp));
}
if (fd.rstate == FTP_REPLY_MID)
code_hdr = (const ServiceFTPCode*)(data + offset);
tmp = 0;
- if (check_ret_digit_code(code_hdr->code, 3,1, tmp, fd) and (code_hdr->sp == ' ' or code_hdr->sp == 0x09))
+ if (check_ret_digit_code(code_hdr->code, 3, 1, tmp, fd) and (code_hdr->sp == ' '
+ or code_hdr->sp == 0x09))
{
if (tmp == fd.code)
{
if (fd.rstate != FTP_REPLY_PARTIAL_RESP)
{
fd.rstate = FTP_REPLY_MID;
- if (ftp_parse_response(data, offset, size, fd, FTP_REPLY_LONG)== FTP_INCORRECT_EOL)
+ parse_ret = ftp_parse_response(data, offset, size, fd, FTP_REPLY_LONG);
+ if (parse_ret == FTP_INCORRECT_EOL)
return -1;
if (++offset >= size)
{
if (size - offset < (int)sizeof(ServiceFTPCode))
{
fd.rstate = FTP_REPLY_MID;
- if (ftp_parse_response(data, offset, size, fd, FTP_REPLY_LONG) == FTP_INCORRECT_EOL)
+ parse_ret = ftp_parse_response(data, offset, size, fd, FTP_REPLY_LONG);
+ if (parse_ret == FTP_INCORRECT_EOL)
return -1;
if (fd.rstate == FTP_REPLY_MID)
fd.rstate = FTP_REPLY_LONG;
if (fd.rstate == FTP_REPLY_PARTIAL_RESP)
{
tmp = 0;
- ret_code = check_ret_digit_code(data + offset, fd.part_code_len ,1, tmp, fd);
+ ret_code = check_ret_digit_code(data + offset, fd.part_code_len , 1, tmp, fd);
if(!ret_code)
return -1;
fd.code = tmp + fd.part_code_resp;
fd.part_code_resp = 0;
- if (ftp_parse_response(data, offset, size, fd, FTP_REPLY_LONG) == FTP_INCORRECT_EOL)
+ parse_ret = ftp_parse_response(data, offset, size, fd, FTP_REPLY_LONG);
+ if (parse_ret == FTP_INCORRECT_EOL)
return -1;
}
if (code_hdr->sp == ' ' or code_hdr->sp == 0x09)
{
fd.rstate = FTP_REPLY_MID;
- if (ftp_parse_response(data, offset, size, fd, FTP_REPLY_BEGIN) == FTP_INCORRECT_EOL)
+ parse_ret = ftp_parse_response(data, offset, size, fd, FTP_REPLY_BEGIN);
+ if (parse_ret == FTP_INCORRECT_EOL)
return -1;
}
else if (code_hdr->sp == '-')
{
fd.rstate = FTP_REPLY_MID;
- if (ftp_parse_response(data, offset, size, fd, FTP_REPLY_MULTI) == FTP_INCORRECT_EOL)
+ parse_ret = ftp_parse_response(data, offset, size, fd, FTP_REPLY_MULTI);
+ if (parse_ret == FTP_INCORRECT_EOL)
return -1;
}
if (fd.rstate == FTP_REPLY_MID)
{
const uint8_t* local_data;
uint32_t local_number = 0;
- for (local_data = *data; local_data < end && *local_data == ' '; local_data++)
- ;
+ for (local_data = *data; local_data < end && *local_data == ' '; local_data++);
+
if (local_data < end && *local_data == delimiter)
{
*number = 0;
return -1;
}
*number = local_number;
- *data = local_data+1;
+ *data = local_data + 1;
return 0;
}
return 0;
}
-static int ftp_validate_pasv(const uint8_t* data, uint16_t size,
- uint32_t* address, uint16_t* port)
+static int ftp_validate_pasv(const uint8_t* data, uint16_t size, uint32_t* address, uint16_t* port)
{
const uint8_t* end;
uint32_t tmp;
end = data + size;
data += sizeof(ServiceFTPCode);
- for (; data<end && *data!='('; data++)
- ;
+ for (; data<end && *data!='('; data++);
+
data++;
if (data >= end)
return 1;
return 0;
}
-static int ftp_validate_epsv(const uint8_t* data, uint16_t size,
- uint16_t* port)
+static int ftp_validate_epsv(const uint8_t* data, uint16_t size, uint16_t* port)
{
const uint8_t* end;
uint8_t delimiter;
end = data + size;
data += sizeof(ServiceFTPCode);
- for (; data<end && *data!='('; data++)
- ;
+ for (; data<end && *data!='('; data++);
+
data++;
if (data >= end)
return 1;
if (data >= end)
return 1;
- for (; data<end && *data!=delimiter; data++)
- ;
+ for (; data<end && *data!=delimiter; data++);
+
data++;
if (data >= end)
return 1;
- for (; data<end && *data!=delimiter; data++)
- ;
+ for (; data<end && *data!=delimiter; data++);
+
data++;
if (data >= end)
return 1;
return 0;
}
-static int ftp_validate_port(const uint8_t* data, uint16_t size,
- SfIp* address, uint16_t* port)
+static int ftp_validate_port(const uint8_t* data, uint16_t size, SfIp* address, uint16_t* port)
{
const uint8_t* end;
const uint8_t* p;
for (index = 0; !addrFamilySupported && RFC2428_known_address_families[index].eprt_fam != 0;
index++)
{
- if ( RFC2428_known_address_families[index].eprt_fam == (uint16_t)tmp )
+ if (RFC2428_known_address_families[index].eprt_fam == (uint16_t)tmp)
{
addrFamilySupported = RFC2428_known_address_families[index].sfaddr_fam;
}
if (data[size-1] != 0x0a)
goto inprocess;
- if (size > sizeof(FTP_PORT_CMD)-1 &&
- strncasecmp((const char*)data, FTP_PORT_CMD, sizeof(FTP_PORT_CMD)-1) == 0)
+ if (size > sizeof(FTP_PORT_CMD) - 1 &&
+ strncasecmp((const char*)data, FTP_PORT_CMD, sizeof(FTP_PORT_CMD) - 1) == 0)
{
- if (ftp_validate_port(data+(sizeof(FTP_PORT_CMD)-1),
- size-(sizeof(FTP_PORT_CMD)-1),
+ if (ftp_validate_port(data + (sizeof(FTP_PORT_CMD) - 1),
+ size - (sizeof(FTP_PORT_CMD) - 1),
&fd->address, &fd->port) == 0)
{
const SfIp* dip = args.pkt->ptrs.ip_api.get_dst();
WatchForCommandResult(fd, args.asd, FTP_CMD_PORT_EPRT);
}
}
- else if (size > sizeof(FTP_EPRT_CMD)-1 &&
- strncasecmp((const char*)data, FTP_EPRT_CMD, sizeof(FTP_EPRT_CMD)-1) == 0)
+ else if (size > sizeof(FTP_EPRT_CMD) - 1 &&
+ strncasecmp((const char*)data, FTP_EPRT_CMD, sizeof(FTP_EPRT_CMD) - 1) == 0)
{
- if (ftp_validate_eprt(data+(sizeof(FTP_EPRT_CMD)-1),
- size-(sizeof(FTP_EPRT_CMD)-1),
+ if (ftp_validate_eprt(data+(sizeof(FTP_EPRT_CMD) - 1),
+ size - (sizeof(FTP_EPRT_CMD) - 1),
&fd->address, &fd->port) == 0)
{
const SfIp* dip = args.pkt->ptrs.ip_api.get_dst();
WatchForCommandResult(fd, args.asd, FTP_CMD_PORT_EPRT);
}
}
- else if ( size > sizeof(FTP_PASV_CMD)-1 &&
- ( strncasecmp((const char*)data, FTP_PASV_CMD, sizeof(FTP_PASV_CMD)-1) == 0 ||
- strncasecmp((const char*)data, FTP_EPSV_CMD, sizeof(FTP_EPSV_CMD)-1) == 0 )
- )
+ else if (size > sizeof(FTP_PASV_CMD) - 1 &&
+ (strncasecmp((const char*)data, FTP_PASV_CMD, sizeof(FTP_PASV_CMD) - 1) == 0 ||
+ strncasecmp((const char*)data, FTP_EPSV_CMD, sizeof(FTP_EPSV_CMD) - 1) == 0))
{
WatchForCommandResult(fd, args.asd, FTP_CMD_PASV_EPSV);
}
while (offset < size)
{
init_offset = offset;
- if ((code=ftp_validate_reply(data, offset, size, *fd)) < 0)
+ if ((code = ftp_validate_reply(data, offset, size, *fd)) < 0)
goto fail;
if (!code)
goto inprocess;
case 227:
{
code = ftp_validate_pasv(data + init_offset,
- (uint16_t)(offset-init_offset),
+ (uint16_t)(offset - init_offset),
&address, &port);
if (!code)
{
case 229:
{
code = ftp_validate_epsv(data + init_offset,
- (uint16_t)(offset-init_offset), &port);
+ (uint16_t)(offset - init_offset), &port);
if (!code)
{
case APPID_NOMATCH:
fail:
- if (!args.asd.is_service_detected())
- fail_service(args.asd, args.pkt, args.dir);
- args.asd.clear_session_flags(APPID_SESSION_CONTINUE);
+ if (args.asd.is_service_detected())
+ {
+ args.asd.clear_session_flags(APPID_SESSION_CONTINUE);
+ return APPID_SUCCESS;
+ }
+
+ fail_service(args.asd, args.pkt, args.dir);
return APPID_NOMATCH;
}
}