Пример #1
0
static int matchStringProtocol(struct ndpi_detection_module_struct *ndpi_struct, 
			struct ndpi_flow_struct *flow, 
			char *string_to_match, 
			u_int string_to_match_len) {
  int i = 0, end = string_to_match_len-1, num_found = 0;
  struct ndpi_packet_struct *packet = &flow->packet;
#ifdef AHOCORASICK
  AC_TEXT_t ac_input_text;
#endif

  while(end > 0) {
    if(string_to_match[end] == '.') {
      num_found++;
      if(num_found == 2) {
	end++;
	break;
      }
    }
    end--;
  }

  strncpy(flow->l4.tcp.host_server_name, 
	  &string_to_match[end], 
	  ndpi_min(sizeof(flow->l4.tcp.host_server_name)-1, string_to_match_len-end));

#ifdef AHOCORASICK
  matching_protocol_id = -1;

  ac_input_text.astring = string_to_match;
  ac_input_text.length = string_to_match_len;
  ac_automata_search (ac_automa, &ac_input_text, 0);
  
  ac_automata_reset(ac_automa);

  if (matching_protocol_id != -1) {
    packet->detected_protocol_stack[0] = matching_protocol_id;
    return(packet->detected_protocol_stack[0]);
  }
#else
  for (i = 0; i < host_match_num_items; i++) {
    if(ndpi_strnstr(string_to_match, 
		    host_match[i].string_to_match, 
		    string_to_match_len) != NULL) {
      packet->detected_protocol_stack[0] = host_match[i].protocol_id;
      return(packet->detected_protocol_stack[0]);
    } else
      i++;
  }
#endif

#ifdef DEBUG
  string_to_match[string_to_match_len] = '\0';
  printf("[NTOP] Unable to find a match for '%s'\n", string_to_match);
#endif

  return(-1);
}
Пример #2
0
/* Code fixes courtesy of Alexsandro Brahm <*****@*****.**> */
int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
		      struct ndpi_flow_struct *flow,
		      char *buffer, int buffer_len) {
  struct ndpi_packet_struct *packet = &flow->packet;

#ifdef CERTIFICATE_DEBUG
  {
    static u_int8_t id = 0;

    printf("-> [%u] %02X\n", ++id, packet->payload[0] & 0xFF);
  }
#endif

  /*
    Nothing matched so far: let's decode the certificate with some heuristics
    Patches courtesy of Denys Fedoryshchenko <*****@*****.**>
   */
  if(packet->payload[0] == 0x16 /* Handshake */) {
    u_int16_t total_len  = (packet->payload[3] << 8) + packet->payload[4] + 5 /* SSL Header */;
    u_int8_t handshake_protocol = packet->payload[5]; /* handshake protocol a bit misleading, it is message type according TLS specs */

    memset(buffer, 0, buffer_len);

    /* Truncate total len, search at least in incomplete packet */
    if(total_len > packet->payload_packet_len)
	total_len = packet->payload_packet_len;

    /* At least "magic" 3 bytes, null for string end, otherwise no need to waste cpu cycles */
    if(total_len > 4) {
      int i;

      if(handshake_protocol == 0x02 || handshake_protocol == 0xb /* Server Hello and Certificate message types are interesting for us */) {
	u_int num_found = 0;

	flow->l4.tcp.ssl_seen_server_cert = 1;

	/* Check after handshake protocol header (5 bytes) and message header (4 bytes) */
	for(i = 9; i < packet->payload_packet_len-3; i++) {
	  if(((packet->payload[i] == 0x04) && (packet->payload[i+1] == 0x03) && (packet->payload[i+2] == 0x0c))
	     || ((packet->payload[i] == 0x55) && (packet->payload[i+1] == 0x04) && (packet->payload[i+2] == 0x03))) {
	    u_int8_t server_len = packet->payload[i+3];

	    if(packet->payload[i] == 0x55) {
	      num_found++;

	      if(num_found != 2) continue;
	    }

	    if(server_len+i+3 < packet->payload_packet_len) {
	      char *server_name = (char*)&packet->payload[i+4];
	      u_int8_t begin = 0, len, j, num_dots;

	      while(begin < server_len) {
		if(!ndpi_isprint(server_name[begin]))
		  begin++;
		else
		  break;
	      }

	      // len = ndpi_min(server_len-begin, buffer_len-1);
	      len = buffer_len-1;
	      strncpy(buffer, &server_name[begin], len);
	      buffer[len] = '\0';

	      /* We now have to check if this looks like an IP address or host name */
	      for(j=0, num_dots = 0; j<len; j++) {
		if(!ndpi_isprint((buffer[j]))) {
		  num_dots = 0; /* This is not what we look for */
		  break;
		} else if(buffer[j] == '.') {
		  num_dots++;
		  if(num_dots >=2) break;
		}
	      }

	      if(num_dots >= 2) {
		stripCertificateTrailer(buffer, buffer_len);
		snprintf(flow->protos.ssl.server_certificate,
			 sizeof(flow->protos.ssl.server_certificate), "%s", buffer);
		return(1 /* Server Certificate */);
	      }
	    }
	  }
	}
      } else if(handshake_protocol == 0x01 /* Client Hello */) {
	u_int offset, base_offset = 43;
	u_int16_t session_id_len = packet->payload[base_offset];

	if((session_id_len+base_offset+2) <= total_len) {
	  u_int16_t cypher_len =  packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
	  offset = base_offset + session_id_len + cypher_len + 2;

	  flow->l4.tcp.ssl_seen_client_cert = 1;

	  if(offset < total_len) {
	    u_int16_t compression_len;
	    u_int16_t extensions_len;

	    compression_len = packet->payload[offset+1];
	    offset += compression_len + 3;

	    if(offset < total_len) {
	      extensions_len = packet->payload[offset];

	      if((extensions_len+offset) < total_len) {
		u_int16_t extension_offset = 1; /* Move to the first extension */

		while(extension_offset < extensions_len) {
		  u_int16_t extension_id, extension_len;

		  memcpy(&extension_id, &packet->payload[offset+extension_offset], 2);
		  extension_offset += 2;

		  memcpy(&extension_len, &packet->payload[offset+extension_offset], 2);
		  extension_offset += 2;

		  extension_id = ntohs(extension_id), extension_len = ntohs(extension_len);

		  if(extension_id == 0) {
		    u_int begin = 0,len;
		    char *server_name = (char*)&packet->payload[offset+extension_offset];

		    while(begin < extension_len) {
		      if((!ndpi_isprint(server_name[begin]))
			 || ndpi_ispunct(server_name[begin])
			 || ndpi_isspace(server_name[begin]))
			begin++;
		      else
			break;
		    }

		    len = (u_int)ndpi_min(extension_len-begin, buffer_len-1);
		    strncpy(buffer, &server_name[begin], len);
		    buffer[len] = '\0';
		    stripCertificateTrailer(buffer, buffer_len);

		    snprintf(flow->protos.ssl.client_certificate,
			     sizeof(flow->protos.ssl.client_certificate), "%s", buffer);

		    /* We're happy now */
		    return(2 /* Client Certificate */);
		  }

		  extension_offset += extension_len;
		}
	      }
	    }
	  }
	}
      }
    }
  }

  return(0); /* Not found */
}
Пример #3
0
static void check_content_type_and_change_protocol(struct ndpi_detection_module_struct
						   *ndpi_struct, struct ndpi_flow_struct *flow)
{
#ifdef NDPI_PROTOCOL_MPEG
  struct ndpi_packet_struct *packet = &flow->packet;
#endif
#ifdef NDPI_PROTOCOL_AVI
#endif
  //      struct ndpi_id_struct         *src=ndpi_struct->src;
  //      struct ndpi_id_struct         *dst=ndpi_struct->dst;

  u_int8_t a;

  if (packet->content_line.ptr != NULL && packet->content_line.len != 0) {
    NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Content Type Line found %.*s\n",
	    packet->content_line.len, packet->content_line.ptr);
#ifdef NDPI_PROTOCOL_MPEG
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_MPEG) != 0)
      mpeg_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_FLASH
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_FLASH) != 0)
      flash_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_QUICKTIME
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_QUICKTIME) != 0)
      qt_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_REALMEDIA
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_REALMEDIA) != 0)
      realmedia_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_WINDOWSMEDIA
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_WINDOWSMEDIA) != 0)
      windowsmedia_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_MMS
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_MMS) != 0)
      mms_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_OFF
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OFF) != 0)
      off_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_OGG
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_OGG) != 0)
      ogg_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_MOVE
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_MOVE) != 0)
      move_parse_packet_contentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_WEBM
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_WEBM) != 0)
      webm_parse_packet_contentline(ndpi_struct, flow);
#endif
  }
  /* check user agent here too */
  if (packet->user_agent_line.ptr != NULL && packet->user_agent_line.len != 0) {
    NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "User Agent Type Line found %.*s\n",
	    packet->user_agent_line.len, packet->user_agent_line.ptr);
#ifdef NDPI_PROTOCOL_XBOX
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_XBOX) != 0)
      xbox_parse_packet_useragentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_WINDOWS_UPDATE    
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_WINDOWS_UPDATE) != 0)
      windows_update_packet_useragentline(ndpi_struct, flow);
#endif
#ifdef NDPI_PROTOCOL_WINDOWSMEDIA
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_WINDOWSMEDIA) != 0)
      winmedia_parse_packet_useragentline(ndpi_struct, flow);
#endif

  }
  /* check for host line */
  if (packet->host_line.ptr != NULL) {
    u_int len;

    NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "HOST Line found %.*s\n",
	    packet->host_line.len, packet->host_line.ptr);
#ifdef NDPI_PROTOCOL_QQ
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_QQ) != 0) {
      qq_parse_packet_URL_and_hostname(ndpi_struct, flow);
    }
#endif

    /* Copy result for nDPI apps */
    len = ndpi_min(packet->host_line.len, sizeof(flow->host_server_name)-1);
    strncpy((char*)flow->host_server_name, (char*)packet->host_line.ptr, len);
    flow->host_server_name[len] = '\0';

    parseHttpSubprotocol(ndpi_struct, flow);
    
    if(packet->detected_protocol_stack[0] != NDPI_PROTOCOL_HTTP) {
      ndpi_int_http_add_connection(ndpi_struct, flow, packet->detected_protocol_stack[0]);
      return; /* We have identified a sub-protocol so we're done */
    }
  }
   
  /* check for accept line */
  if (packet->accept_line.ptr != NULL) {
    NDPI_LOG(NDPI_PROTOCOL_HTTP, ndpi_struct, NDPI_LOG_DEBUG, "Accept Line found %.*s\n",
	    packet->accept_line.len, packet->accept_line.ptr);
#ifdef NDPI_PROTOCOL_RTSP
    if (NDPI_COMPARE_PROTOCOL_TO_BITMASK(ndpi_struct->detection_bitmask, NDPI_PROTOCOL_RTSP) != 0) {
      rtsp_parse_packet_acceptline(ndpi_struct, flow);
    }
#endif
  }
  /* search for line startin with "Icy-MetaData" */
#ifdef NDPI_PROTOCOL_MPEG
  for (a = 0; a < packet->parsed_lines; a++) {
    if (packet->line[a].len > 11 && memcmp(packet->line[a].ptr, "Icy-MetaData", 12) == 0) {
      NDPI_LOG(NDPI_PROTOCOL_MPEG, ndpi_struct, NDPI_LOG_DEBUG, "MPEG: Icy-MetaData found.\n");
      ndpi_int_http_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_MPEG);
      return;
    }
  }
#ifdef NDPI_PROTOCOL_AVI
#endif
#endif

}