Esempio n. 1
0
krb5_boolean
krb5int_cc_creds_match_request(krb5_context context, krb5_flags whichfields, krb5_creds *mcreds, krb5_creds *creds)
{
    if (((set(KRB5_TC_MATCH_SRV_NAMEONLY) &&
		   srvname_match(context, mcreds, creds)) ||
	       standard_fields_match(context, mcreds, creds))
	      &&
	      (! set(KRB5_TC_MATCH_IS_SKEY) ||
	       mcreds->is_skey == creds->is_skey)
	      &&
	      (! set(KRB5_TC_MATCH_FLAGS_EXACT) ||
	       mcreds->ticket_flags == creds->ticket_flags)
	      &&
	      (! set(KRB5_TC_MATCH_FLAGS) ||
	       flags_match(mcreds->ticket_flags, creds->ticket_flags))
	      &&
	      (! set(KRB5_TC_MATCH_TIMES_EXACT) ||
	       times_match_exact(&mcreds->times, &creds->times))
	      &&
	      (! set(KRB5_TC_MATCH_TIMES) ||
	       times_match(&mcreds->times, &creds->times))
	      &&
	      ( ! set(KRB5_TC_MATCH_AUTHDATA) ||
	       authdata_match(mcreds->authdata, creds->authdata))
	      &&
	      (! set(KRB5_TC_MATCH_2ND_TKT) ||
	       data_match (&mcreds->second_ticket, &creds->second_ticket))
	      &&
	     ((! set(KRB5_TC_MATCH_KTYPE))||
		(mcreds->keyblock.enctype == creds->keyblock.enctype)))
        return TRUE;
    return FALSE;
}
Esempio n. 2
0
/* Sniff an interface, looking for port-knock sequences
 */
void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
{
	/* packet structs */
	struct ether_header* eth = NULL;
	struct ip* ip = NULL;
	struct tcphdr* tcp = NULL;
	struct udphdr* udp = NULL;
	char proto[8];
	/* TCP/IP data */
	struct in_addr inaddr;
	unsigned short sport, dport;
	char srcIP[16], dstIP[16];
	/* timestamp */
	time_t pkt_secs = hdr->ts.tv_sec;
	struct tm* pkt_tm;
	char pkt_date[11];
	char pkt_time[9];
	PMList *lp;
	knocker_t *attempt = NULL;
	PMList *found_attempts = NULL;

	if(lltype == DLT_EN10MB) {
		eth = (struct ether_header*)packet;
		if(ntohs(eth->ether_type) != ETHERTYPE_IP) {
			return;
		}

		ip = (struct ip*)(packet + sizeof(struct ether_header));
#ifdef __linux__
	} else if(lltype == DLT_LINUX_SLL) {
		ip = (struct ip*)((u_char*)packet + 16);
#endif
	} else if(lltype == DLT_RAW) {
		ip = (struct ip*)((u_char*)packet);
	} else {
		dprint("link layer header type of packet not recognized, ignoring...\n");
		return;
	}

	if(ip->ip_v != 4) {
		/* no IPv6 yet */
		dprint("packet is not IPv4, ignoring...\n");
		return;
	}
	if(ip->ip_p == IPPROTO_ICMP) {
		/* we don't do ICMP */
		return;
	}

	sport = dport = 0;

	if(ip->ip_p == IPPROTO_TCP) {
		strncpy(proto, "tcp", sizeof(proto));
		tcp = (struct tcphdr*)((u_char*)ip + (ip->ip_hl *4));
		sport = ntohs(tcp->th_sport);
		dport = ntohs(tcp->th_dport);
	}
	if(ip->ip_p == IPPROTO_UDP) {
		strncpy(proto, "udp", sizeof(proto));
		udp = (struct udphdr*)((u_char*)ip + (ip->ip_hl * 4));
		sport = ntohs(udp->uh_sport);
		dport = ntohs(udp->uh_dport);
	}

	/* get the date/time */
	pkt_tm = localtime(&pkt_secs);
	snprintf(pkt_date, 11, "%04d-%02d-%02d", pkt_tm->tm_year+1900, pkt_tm->tm_mon,
			pkt_tm->tm_mday);
	snprintf(pkt_time, 9, "%02d:%02d:%02d", pkt_tm->tm_hour, pkt_tm->tm_min,
			pkt_tm->tm_sec);

	/* convert IPs from binary to string */
	inaddr.s_addr = ip->ip_src.s_addr;
	strncpy(srcIP, inet_ntoa(inaddr), sizeof(srcIP)-1);
	srcIP[sizeof(srcIP)-1] = '\0';
	inaddr.s_addr = ip->ip_dst.s_addr;
	strncpy(dstIP, inet_ntoa(inaddr), sizeof(dstIP)-1);
	dstIP[sizeof(dstIP)-1] = '\0';

	dprint("%s %s: %s: %s:%d -> %s:%d %d bytes\n", pkt_date, pkt_time,
			proto, srcIP, sport, dstIP, dport, hdr->len);

	/* clean up expired/completed/failed attempts */
	lp = attempts;
	while(lp != NULL) {
		int nix = 0; /* Clear flag */
		PMList *lpnext = lp->next;

		attempt = (knocker_t*)lp->data;

		/* Check if the sequence has been completed */
		if(attempt->stage >= attempt->door->seqcount) {
			dprint("removing successful knock attempt (%s)\n", attempt->src);
			nix = 1;
		}

		/* Signed integer overflow check.
		   If we received more than 32767 packets the sign will be negative*/
		if(attempt->stage < 0) {
			dprint("removing failed knock attempt (%s)\n", attempt->src);
			nix = 1;
		}

		/* Check if timeout has been reached */
		if(!nix && (pkt_secs - attempt->seq_start) >= attempt->door->seq_timeout) {

			/* Do we know the hostname? */
			if(attempt->srchost) {
				/* Log the hostname */
				vprint("%s (%s): %s: sequence timeout (stage %d)\n", attempt->src, attempt->srchost,
						attempt->door->name, attempt->stage);
				logprint("%s (%s): %s: sequence timeout (stage %d)\n", attempt->src, attempt->srchost,
						attempt->door->name, attempt->stage);
			} else {
				/* Log the IP */
				vprint("%s: %s: sequence timeout (stage %d)\n", attempt->src,
						attempt->door->name, attempt->stage);
				logprint("%s: %s: sequence timeout (stage %d)\n", attempt->src,
						attempt->door->name, attempt->stage);
			}
			nix = 1;
		}

		/* If clear flag is set */
		if(nix) {
			/* splice this entry out of the list */
			if(lp->prev) lp->prev->next = lp->next;
			if(lp->next) lp->next->prev = lp->prev;
			/* If lp is the only element of the list then empty the list */
			if(lp == attempts) attempts = NULL;
			lp->prev = lp->next = NULL;
			if (attempt->srchost) {
				free(attempt->srchost);
				attempt->srchost = NULL;
			}
			list_free(lp);
		}

		lp = lpnext;
	}

	attempt = NULL;
	/* look for this guy in our attempts list */
	for(lp = attempts; lp; lp = lp->next) {
		knocker_t *att = (knocker_t*)lp->data;
		if(!strcmp(srcIP, att->src) &&
		   !target_strcmp(dstIP, att->door->target)) {
			found_attempts = list_add(found_attempts, att);
		}
	}

	if (found_attempts == NULL) {
		found_attempts = list_add(found_attempts, NULL);
	}

	while (found_attempts != NULL) {
		attempt = (knocker_t*)found_attempts->data;

		if(attempt) {
			int flagsmatch = flags_match(attempt->door, ip, tcp);
			if(flagsmatch && ip->ip_p == attempt->door->protocol[attempt->stage] &&
					dport == attempt->door->sequence[attempt->stage]) {
				process_attempt(attempt);
			} else if(flagsmatch == 0) {
				/* TCP flags didn't match -- just ignore this packet, don't
				 * invalidate the knock.
				 */
			} else {
				/* invalidate the knock sequence, it will be removed in the
				 * next sniff() call.
				 */
				attempt->stage = -1;
			}
		} else {
			/* did they hit the first port correctly? */
			for(lp = doors; lp; lp = lp->next) {
				opendoor_t *door = (opendoor_t*)lp->data;
				/* if we're working with TCP, try to match the flags */
				if(!flags_match(door, ip, tcp)) {
					continue;
				}
				if(ip->ip_p == door->protocol[0] && dport == door->sequence[0] &&
				   !target_strcmp(dstIP, door->target)) {
					struct hostent *he;
					/* create a new entry */
					attempt = (knocker_t*)malloc(sizeof(knocker_t));
					attempt->srchost = NULL;
					if(attempt == NULL) {
						perror("malloc");
						exit(1);
					}
					strcpy(attempt->src, srcIP);
					/* try a reverse lookup if enabled  */
					if (o_lookup) {
						inaddr.s_addr = ip->ip_src.s_addr;
						he = gethostbyaddr((void *)&inaddr, sizeof(inaddr), AF_INET);
						if(he) {
							attempt->srchost = strdup(he->h_name);
						}
					}

					attempt->stage = 0;
					attempt->seq_start = pkt_secs;
					attempt->door = door;
					attempts = list_add(attempts, attempt);
					process_attempt(attempt);
				}
			}
		}

		found_attempts = found_attempts->next;
	}
}
Esempio n. 3
0
	void ProcessSolidBlock( unsigned short x_base, unsigned short y_base, MapWriter& mapwriter )
	{
	  unsigned int idx2_offset = 0;
	  SOLIDX2_ELEM idx2_elem;
	  memset( &idx2_elem, 0, sizeof idx2_elem );
	  idx2_elem.baseindex = mapwriter.NextSolidIndex();

	  unsigned short x_add_max = SOLIDX_X_SIZE, y_add_max = SOLIDX_Y_SIZE;
	  if ( x_base + x_add_max > uo_map_width )
		x_add_max = uo_map_width - x_base;
	  if ( y_base + y_add_max > uo_map_height )
		y_add_max = uo_map_height - y_base;

	  for ( unsigned short x_add = 0; x_add < x_add_max; ++x_add )
	  {
		for ( unsigned short y_add = 0; y_add < y_add_max; ++y_add )
		{
		  unsigned short x = x_base + x_add;
		  unsigned short y = y_base + y_add;

		  StaticList statics;

		  // read the map, and treat it like a static.
		  short z;
		  USTRUCT_MAPINFO mi;

		  safe_getmapinfo( x, y, &z, &mi );

          if ( mi.landtile > 0x3FFF )
            INFO_PRINT.Format( "Tile 0x{:X} at ({},{},{}) is an invalid ID!\n" ) << mi.landtile << x << y << z;

		  // for water, don't average with surrounding tiles.
		  if ( landtile_uoflags( mi.landtile ) & USTRUCT_TILE::FLAG_LIQUID )
			z = mi.z;
		  short low_z = get_lowestadjacentz( x, y, z );

		  short lt_height = z - low_z;
		  z = low_z;

          if ( mi.landtile > 0x3FFF )
            INFO_PRINT.Format( "Tile 0x{:X} at ({},{},{}) is an invalid ID!\n" ) << mi.landtile << x << y << z;

		  unsigned int lt_flags = landtile_uoflags( mi.landtile );
		  if ( ~lt_flags & USTRUCT_TILE::FLAG_BLOCKING )
		  { // this seems to be the default.
			lt_flags |= USTRUCT_TILE::FLAG_PLATFORM;
		  }
		  lt_flags |= USTRUCT_TILE::FLAG_NO_SHOOT;    // added to make sure people using noshoot will have shapes
		  // generated by this tile in future block LOS, shouldn't
		  // affect people using old LOS method one way or another.
		  lt_flags |= USTRUCT_TILE::FLAG_FLOOR;
		  lt_flags |= USTRUCT_TILE::FLAG_HALF_HEIGHT; // the entire map is this way

		  if ( lt_flags & USTRUCT_TILE::FLAG_WALL )
			lt_height = 20;

		  readstatics( statics, x, y,
					   USTRUCT_TILE::FLAG_BLOCKING |
					   USTRUCT_TILE::FLAG_PLATFORM |
					   USTRUCT_TILE::FLAG_HALF_HEIGHT |
					   USTRUCT_TILE::FLAG_LIQUID |
					   USTRUCT_TILE::FLAG_HOVEROVER
					   //USTRUCT_TILE::FLAG__WALK
					   );

		  for ( unsigned i = 0; i < statics.size(); ++i )
		  {
			StaticRec srec = statics[i];

			unsigned int polflags = polflags_from_tileflags( srec.graphic, srec.flags, cfg_use_no_shoot, cfg_LOS_through_windows );

			if ( ( ~polflags & FLAG::MOVELAND ) &&
				 ( ~polflags & FLAG::MOVESEA ) &&
				 ( ~polflags & FLAG::BLOCKSIGHT ) &&
				 ( ~polflags & FLAG::BLOCKING ) &&
				 ( ~polflags & FLAG::OVERFLIGHT ) )
			{
			  // remove it.  we'll re-sort later.
			  statics.erase( statics.begin() + i );
			  --i; // do-over
			}
			if ( ( ~srec.flags & USTRUCT_TILE::FLAG_BLOCKING ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_PLATFORM ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_HALF_HEIGHT ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_LIQUID ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_HOVEROVER ) )
				 /*(~srec.flags & USTRUCT_TILE::FLAG__WALK)*/
			{
			  // remove it.  we'll re-sort later.
			  statics.erase( statics.begin() + i );
			  --i; // do-over
			}
		  }

		  bool addMap = true;

		  for ( const auto &srec : statics )
		  {
			// Look for water tiles.  If there are any, discard the map (which is usually at -15 anyway)
			if ( z + lt_height <= srec.z && ( ( srec.z - ( z + lt_height ) ) <= 10 ) && // only where the map is below or same Z as the static
				 srec.graphic >= 0x1796 && srec.graphic <= 0x17B2 ) // FIXME hardcoded
			{
			  // arr, there be water here
			  addMap = false;
			}

			// if there's a static on top of one of these "wall" landtiles, make it override.
			if ( ( lt_flags & USTRUCT_TILE::FLAG_WALL ) && // wall?
				 z <= srec.z &&
				 srec.z - z <= lt_height )
			{

			  lt_height = srec.z - z;
			}
		  }
		  // shadows above caves
		  if ( is_cave_shadow( mi ) && !statics.empty() )
		  {
			addMap = false;
		  }



		  // If the map is a NODRAW tile, and there are statics, discard the map tile
		  if ( mi.landtile == 2 && !statics.empty() )
			addMap = false;

		  if ( addMap )
			statics.push_back( StaticRec( 0, static_cast<signed char>( z ), lt_flags, static_cast<char>( lt_height ) ) );

		  sort( statics.begin(), statics.end(), StaticsByZ() );
		  reverse( statics.begin(), statics.end() );

          std::vector<MapShape> shapes;

		  // try to consolidate like shapes, and discard ones we don't care about.
		  while ( !statics.empty() )
		  {
			StaticRec srec = statics.back();
			statics.pop_back();

			unsigned int polflags = polflags_from_tileflags( srec.graphic, srec.flags, cfg_use_no_shoot, cfg_LOS_through_windows );
			if ( ( ~polflags & FLAG::MOVELAND ) &&
				 ( ~polflags & FLAG::MOVESEA ) &&
				 ( ~polflags & FLAG::BLOCKSIGHT ) &&
				 ( ~polflags & FLAG::BLOCKING ) &&
				 ( ~polflags & FLAG::OVERFLIGHT ) )
			{
			  passert_always( 0 );
			  continue;
			}
			if ( ( ~srec.flags & USTRUCT_TILE::FLAG_BLOCKING ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_PLATFORM ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_HALF_HEIGHT ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_LIQUID ) &&
				 ( ~srec.flags & USTRUCT_TILE::FLAG_HOVEROVER ) )
				 /*(~srec.flags & USTRUCT_TILE::FLAG__WALK)*/
			{
			  passert_always( 0 );
			  continue;
			}

			if ( shapes.empty() )
			{
			  // this, whatever it is, is the map base.
			  //TODO: look for water statics and use THOSE as the map.
			  MapShape shape;
			  shape.z = srec.z;      //these will be converted below to
			  shape.height = 0;      //make the map "solid"
			  shape.flags = static_cast<unsigned char>( polflags );
			  // no matter what, the lowest level is gradual
			  shape.flags |= FLAG::GRADUAL;
			  shapes.push_back( shape );

			  //for wall flag - map tile always height 0, at bottom. if map tile has height, add it as a static
			  if ( srec.height != 0 )
			  {
				MapShape _shape;
				_shape.z = srec.z;
				_shape.height = srec.height;
				_shape.flags = polflags;
				shapes.push_back( _shape );

			  }
			  continue;
			}

			MapShape& prev = shapes.back();
			// we're adding it.
			MapShape shape;
			shape.z = srec.z;
			shape.height = srec.height;
			shape.flags = polflags;

			//always add the map shape seperately
			if ( shapes.size() == 1 )
			{
			  shapes.push_back( shape );
			  continue;
			}

			if ( shape.z < prev.z + prev.height )
			{
			  // things can't exist in the same place.
			  // shrink the bottom part of this shape.
			  // if that would give it negative height, then skip it.
			  short height_remove = prev.z + prev.height - shape.z;
			  if ( height_remove <= shape.height )
			  {
				shape.z += height_remove;
				shape.height -= height_remove;
			  }
			  else
			  { // example: 5530, 14
				continue;
			  }
			}

			// sometimes water has "sand" a couple z-coords above it.
			// We'll try to detect this (really, anything that is up to 4 dist from water)
			// and extend the thing above downward.
			if ( ( prev.flags & FLAG::MOVESEA ) &&
				 ( shape.z > prev.z + prev.height ) &&
				 ( shape.z <= prev.z + prev.height + 4 ) )
			{
			  short height_add = shape.z - prev.z - prev.height;
			  shape.z -= height_add;
			  shape.height += height_add;
			}
			if ( ( prev.flags & FLAG::MOVESEA ) &&
				 ( prev.z + prev.height == -5 ) &&
				 ( shape.flags & FLAG::MOVESEA ) &&
				 ( shape.z == 25 ) )
			{
			  // oddly, there are some water tiles at z=25 in some places...I don't get it
			  continue;
			}

			//string prevflags_s = flagstr(prev.flags);
			//const char* prevflags = prevflags_s.c_str();
			//string shapeflags_s = flagstr(shape.flags);
			//const char* shapeflags = shapeflags_s.c_str();

			if ( shape.z > prev.z + prev.height )
			{
			  //
			  // elevated above what's below, must include separately
			  //

			  shapes.push_back( shape );
			  continue;
			}

			passert_always( shape.z == prev.z + prev.height );

			if ( shape.z == prev.z + prev.height )
			{
			  //
			  // sitting right on top of the previous solid
			  //

			  // standable atop non-standable: standable
			  // nonstandable atop standable: nonstandable
			  // etc
			  bool can_combine = flags_match( prev.flags, shape.flags, FLAG::BLOCKSIGHT | FLAG::BLOCKING );
			  if ( prev.flags & FLAG::MOVELAND &&
				   ~shape.flags & FLAG::BLOCKING &&
				   ~shape.flags & FLAG::MOVELAND )
			  {
				can_combine = false;
			  }

			  if ( can_combine )
			  {
				prev.flags = shape.flags;
				prev.height += shape.height;
			  }
			  else // if one blocks LOS, but not the other, they can't be combined this way.
			  {
				shapes.push_back( shape );
				continue;
			  }
			}
		  }

		  // the first StaticShape is the map base.
		  MapShape base = shapes[0];
		  shapes.erase( shapes.begin() );
		  MAPCELL cell;
		  passert_always( base.height == 0 );
		  cell.z = static_cast<signed char>( base.z ); //assume now map has height=1. a static was already added if it was >0
		  cell.flags = static_cast<u8>( base.flags );
		  if ( !shapes.empty() )
			cell.flags |= FLAG::MORE_SOLIDS;

		  mapwriter.SetMapCell( x, y, cell );

		  if ( !shapes.empty() )
		  {
			++with_more_solids;
			total_statics += static_cast<unsigned int>( shapes.size() );
			if ( idx2_offset == 0 )
			  idx2_offset = mapwriter.NextSolidx2Offset();

			unsigned int addindex = mapwriter.NextSolidIndex() - idx2_elem.baseindex;
			if ( addindex > std::numeric_limits<unsigned short>::max() )
                throw std::runtime_error("addoffset overflow");
			idx2_elem.addindex[x_add][y_add] = static_cast<unsigned short>( addindex );
			int count = static_cast<int>( shapes.size() );
			for ( int j = 0; j < count; ++j )
			{
			  MapShape shape = shapes[j];
			  char _z, height, flags;
			  _z = static_cast<char>( shapes[j].z );
			  height = static_cast<char>( shape.height );
			  flags = static_cast<u8>( shape.flags );
			  if ( !height )//make 0 height solid
			  {
				--_z;
				++height;
			  }

			  if ( j != count - 1 )
				flags |= FLAG::MORE_SOLIDS;
			  SOLIDS_ELEM solid;
			  solid.z = _z;
			  solid.height = height;
			  solid.flags = flags;
			  mapwriter.AppendSolid( solid );
			}
		  }
		}
	  }
	  if ( idx2_offset )
	  {
		++nonempty;
		mapwriter.AppendSolidx2Elem( idx2_elem );
	  }
	  else
	  {
		++empty;
	  }
	  mapwriter.SetSolidx2Offset( x_base, y_base, idx2_offset );
	}