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; }
/* 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; } }
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 ); }