"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/service_inspectors/dce_rpc/dce_co.cc" between
snort3-3.1.29.0.tar.gz and snort3-3.1.30.0.tar.gz

About: Snort 3 is a network intrusion prevention and detection system (IDS/IPS) combining the benefits of signature, protocol and anomaly-based inspection.

dce_co.cc  (snort3-3.1.29.0):dce_co.cc  (snort3-3.1.30.0)
skipping to change at line 337 skipping to change at line 337
{ {
DceRpcCoHdr* co_hdr = (DceRpcCoHdr*)co_ptr; DceRpcCoHdr* co_hdr = (DceRpcCoHdr*)co_ptr;
/* If we've set the fragment tracker context id or opnum, use them. */ /* If we've set the fragment tracker context id or opnum, use them. */
uint16_t ctx_id = uint16_t ctx_id =
(cot->frag_tracker.ctx_id != DCE2_SENTINEL) ? (cot->frag_tracker.ctx_id != DCE2_SENTINEL) ?
(uint16_t)cot->frag_tracker.ctx_id : (uint16_t)cot->ctx_id; (uint16_t)cot->frag_tracker.ctx_id : (uint16_t)cot->ctx_id;
uint16_t opnum = uint16_t opnum =
(cot->frag_tracker.opnum != DCE2_SENTINEL) ? (cot->frag_tracker.opnum != DCE2_SENTINEL) ?
(uint16_t)cot->frag_tracker.opnum : (uint16_t)cot->opnum; (uint16_t)cot->frag_tracker.opnum : (uint16_t)cot->opnum;
if ( DetectionEngine::get_current_packet()->is_from_client() ) Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return;
if ( p->is_from_client() )
{ {
DceRpcCoRequest* co_req = (DceRpcCoRequest*)((uint8_t*)co_hdr + sizeof(D ceRpcCoHdr)); DceRpcCoRequest* co_req = (DceRpcCoRequest*)((uint8_t*)co_hdr + sizeof(D ceRpcCoHdr));
/* Doesn't really matter if this wraps ... it is basically just for pres entation */ /* Doesn't really matter if this wraps ... it is basically just for pres entation */
uint16_t flen = sizeof(DceRpcCoHdr) + sizeof(DceRpcCoRequest) + stub_len ; uint16_t flen = sizeof(DceRpcCoHdr) + sizeof(DceRpcCoRequest) + stub_len ;
co_hdr->frag_length = DceRpcHtons(&flen, DCERPC_BO_FLAG__LITTLE_ENDIAN); co_hdr->frag_length = DceRpcHtons(&flen, DCERPC_BO_FLAG__LITTLE_ENDIAN);
co_req->context_id = DceRpcHtons(&ctx_id, DCERPC_BO_FLAG__LITTLE_ENDIAN) ; co_req->context_id = DceRpcHtons(&ctx_id, DCERPC_BO_FLAG__LITTLE_ENDIAN) ;
co_req->opnum = DceRpcHtons(&opnum, DCERPC_BO_FLAG__LITTLE_ENDIAN); co_req->opnum = DceRpcHtons(&opnum, DCERPC_BO_FLAG__LITTLE_ENDIAN);
} }
else else
skipping to change at line 383 skipping to change at line 387
co_hdr->packed_drep[0] = DCE2_LITTLE_ENDIAN; /* Little endian */ co_hdr->packed_drep[0] = DCE2_LITTLE_ENDIAN; /* Little endian */
if (dir == PKT_FROM_CLIENT) if (dir == PKT_FROM_CLIENT)
co_hdr->ptype = DCERPC_PDU_TYPE__REQUEST; co_hdr->ptype = DCERPC_PDU_TYPE__REQUEST;
else else
co_hdr->ptype = DCERPC_PDU_TYPE__RESPONSE; co_hdr->ptype = DCERPC_PDU_TYPE__RESPONSE;
} }
static inline DCE2_CoSeg* DCE2_CoGetSegPtr(DCE2_CoTracker* cot) static inline DCE2_CoSeg* DCE2_CoGetSegPtr(DCE2_CoTracker* cot)
{ {
if ( DetectionEngine::get_current_packet()->is_from_server() ) Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return nullptr;
if ( p->is_from_server() )
return &cot->srv_seg; return &cot->srv_seg;
return &cot->cli_seg; return &cot->cli_seg;
} }
/******************************************************************** /********************************************************************
* Function: DCE2_CoSetIface() * Function: DCE2_CoSetIface()
* *
* Sets the interface UUID for the rules options. Looks in the * Sets the interface UUID for the rules options. Looks in the
* context id list. If nothing found there, it looks in the pending * context id list. If nothing found there, it looks in the pending
skipping to change at line 559 skipping to change at line 566
if (pdu_type >= DCERPC_PDU_TYPE__MAX) if (pdu_type >= DCERPC_PDU_TYPE__MAX)
{ {
if (sd->trans != DCE2_TRANS_TYPE__SMB) if (sd->trans != DCE2_TRANS_TYPE__SMB)
{ {
dce_alert(GID_DCE2, DCE2_CO_BAD_PDU_TYPE,dce_common_stats, *sd); dce_alert(GID_DCE2, DCE2_CO_BAD_PDU_TYPE,dce_common_stats, *sd);
} }
return DCE2_RET__ERROR; return DCE2_RET__ERROR;
} }
if (DetectionEngine::get_current_packet()->is_from_client() && (cot->max_xmi Packet* p = DetectionEngine::get_current_packet();
t_frag != DCE2_SENTINEL)) if (p == nullptr)
return DCE2_RET__ERROR;
if (p->is_from_client() && (cot->max_xmit_frag != DCE2_SENTINEL))
{ {
if (frag_len > cot->max_xmit_frag) if (frag_len > cot->max_xmit_frag)
{ {
dce_alert(GID_DCE2, DCE2_CO_FRAG_GT_MAX_XMIT_FRAG,dce_common_stats, *sd); dce_alert(GID_DCE2, DCE2_CO_FRAG_GT_MAX_XMIT_FRAG,dce_common_stats, *sd);
} }
else if (!DceRpcCoLastFrag(co_hdr) && (pdu_type == DCERPC_PDU_TYPE__REQU EST) else if (!DceRpcCoLastFrag(co_hdr) && (pdu_type == DCERPC_PDU_TYPE__REQU EST)
&& ((((int)cot->max_xmit_frag - DCE2_MAX_XMIT_SIZE_FUZZ) < 0) && ((((int)cot->max_xmit_frag - DCE2_MAX_XMIT_SIZE_FUZZ) < 0)
|| ((int)frag_len < ((int)cot->max_xmit_frag - DCE2_MAX_XMIT_SIZE_FU ZZ)))) || ((int)frag_len < ((int)cot->max_xmit_frag - DCE2_MAX_XMIT_SIZE_FU ZZ))))
{ {
/* If client needs to fragment the DCE/RPC request, it shouldn't be less than the /* If client needs to fragment the DCE/RPC request, it shouldn't be less than the
skipping to change at line 1170 skipping to change at line 1181
{ {
dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd) ; dce_alert(GID_DCE2, DCE2_CO_REM_FRAG_LEN_LT_SIZE, dce_common_stats, *sd) ;
return -1; return -1;
} }
return (int)auth_len; return (int)auth_len;
} }
static DCE2_Buffer* DCE2_CoGetFragBuf(DCE2_CoFragTracker* ft) static DCE2_Buffer* DCE2_CoGetFragBuf(DCE2_CoFragTracker* ft)
{ {
if ( DetectionEngine::get_current_packet()->is_from_server() ) Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return nullptr;
if ( p->is_from_server() )
return ft->srv_stub_buf; return ft->srv_stub_buf;
return ft->cli_stub_buf; return ft->cli_stub_buf;
} }
/******************************************************************** /********************************************************************
* Function: DCE2_CoGetRpktType() * Function: DCE2_CoGetRpktType()
* *
* Determines the type of reassembly packet we need to use * Determines the type of reassembly packet we need to use
* based on the transport and buffer type. * based on the transport and buffer type.
skipping to change at line 1248 skipping to change at line 1263
********************************************************************/ ********************************************************************/
static Packet* DCE2_CoGetRpkt(DCE2_SsnData* sd, DCE2_CoTracker* cot, static Packet* DCE2_CoGetRpkt(DCE2_SsnData* sd, DCE2_CoTracker* cot,
DCE2_CoRpktType co_rtype, DCE2_RpktType* rtype) DCE2_CoRpktType co_rtype, DCE2_RpktType* rtype)
{ {
DCE2_CoSeg* seg_buf = DCE2_CoGetSegPtr(cot); DCE2_CoSeg* seg_buf = DCE2_CoGetSegPtr(cot);
DCE2_Buffer* frag_buf = DCE2_CoGetFragBuf(&cot->frag_tracker); DCE2_Buffer* frag_buf = DCE2_CoGetFragBuf(&cot->frag_tracker);
const uint8_t* frag_data = nullptr, * seg_data = nullptr; const uint8_t* frag_data = nullptr, * seg_data = nullptr;
uint32_t frag_len = 0, seg_len = 0; uint32_t frag_len = 0, seg_len = 0;
Packet* rpkt = nullptr; Packet* rpkt = nullptr;
if (seg_buf == nullptr)
return nullptr;
*rtype = DCE2_RPKT_TYPE__NULL; *rtype = DCE2_RPKT_TYPE__NULL;
switch (co_rtype) switch (co_rtype)
{ {
case DCE2_CO_RPKT_TYPE__ALL: case DCE2_CO_RPKT_TYPE__ALL:
if (!DCE2_BufferIsEmpty(frag_buf)) if (!DCE2_BufferIsEmpty(frag_buf))
{ {
frag_data = DCE2_BufferData(frag_buf); frag_data = DCE2_BufferData(frag_buf);
frag_len = DCE2_BufferLength(frag_buf); frag_len = DCE2_BufferLength(frag_buf);
} }
skipping to change at line 1345 skipping to change at line 1363
rpkt = DCE2_GetRpkt(DetectionEngine::get_current_packet(), *rtype, seg_d ata, seg_len); rpkt = DCE2_GetRpkt(DetectionEngine::get_current_packet(), *rtype, seg_d ata, seg_len);
} }
return rpkt; return rpkt;
} }
static Packet* dce_co_reassemble(DCE2_SsnData* sd, DCE2_CoTracker* cot, static Packet* dce_co_reassemble(DCE2_SsnData* sd, DCE2_CoTracker* cot,
DCE2_CoRpktType co_rtype, const DceRpcCoHdr** co_hdr) DCE2_CoRpktType co_rtype, const DceRpcCoHdr** co_hdr)
{ {
dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd); dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd);
bool from_client = DetectionEngine::get_current_packet()->is_from_client(); Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return nullptr;
bool from_client = p->is_from_client();
int co_hdr_len = from_client ? DCE2_MOCK_HDR_LEN__CO_CLI : DCE2_MOCK_HDR_LEN __CO_SRV; int co_hdr_len = from_client ? DCE2_MOCK_HDR_LEN__CO_CLI : DCE2_MOCK_HDR_LEN __CO_SRV;
int smb_hdr_len = from_client ? DCE2_MOCK_HDR_LEN__SMB_CLI : DCE2_MOCK_HDR_L EN__SMB_SRV; int smb_hdr_len = from_client ? DCE2_MOCK_HDR_LEN__SMB_CLI : DCE2_MOCK_HDR_L EN__SMB_SRV;
DCE2_RpktType rpkt_type; DCE2_RpktType rpkt_type;
Packet* rpkt = DCE2_CoGetRpkt(sd, cot, co_rtype, &rpkt_type); Packet* rpkt = DCE2_CoGetRpkt(sd, cot, co_rtype, &rpkt_type);
if (rpkt == nullptr) if (rpkt == nullptr)
{ {
return nullptr; return nullptr;
} }
skipping to change at line 1453 skipping to change at line 1474
static DCE2_Ret dce_co_handle_frag(DCE2_SsnData* sd, DCE2_CoTracker* cot, static DCE2_Ret dce_co_handle_frag(DCE2_SsnData* sd, DCE2_CoTracker* cot,
const DceRpcCoHdr* co_hdr, const uint8_t* frag_ptr, const DceRpcCoHdr* co_hdr, const uint8_t* frag_ptr,
uint16_t frag_len, DCE2_Buffer* frag_buf, uint16_t frag_len, DCE2_Buffer* frag_buf,
uint16_t max_frag_data) uint16_t max_frag_data)
{ {
uint32_t size = (frag_len < DCE2_CO__MIN_ALLOC_SIZE) ? DCE2_CO__MIN_ALLOC_SI ZE : frag_len; uint32_t size = (frag_len < DCE2_CO__MIN_ALLOC_SIZE) ? DCE2_CO__MIN_ALLOC_SI ZE : frag_len;
DCE2_BufferMinAddFlag mflag = DCE2_BUFFER_MIN_ADD_FLAG__USE; DCE2_BufferMinAddFlag mflag = DCE2_BUFFER_MIN_ADD_FLAG__USE;
DCE2_Ret status; DCE2_Ret status;
dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd); dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd);
Packet* p = DetectionEngine::get_current_packet(); Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return DCE2_RET__ERROR;
if ( p->is_from_client() ) if ( p->is_from_client() )
{ {
if (frag_len > dce_common_stats->co_cli_max_frag_size) if (frag_len > dce_common_stats->co_cli_max_frag_size)
dce_common_stats->co_cli_max_frag_size = frag_len; dce_common_stats->co_cli_max_frag_size = frag_len;
if (dce_common_stats->co_cli_min_frag_size == 0 || frag_len < if (dce_common_stats->co_cli_min_frag_size == 0 || frag_len <
dce_common_stats->co_cli_min_frag_size) dce_common_stats->co_cli_min_frag_size)
dce_common_stats->co_cli_min_frag_size = frag_len; dce_common_stats->co_cli_min_frag_size = frag_len;
} }
skipping to change at line 1855 skipping to change at line 1878
DCE2_BufferEmpty(cot->frag_tracker.srv_stub_buf); DCE2_BufferEmpty(cot->frag_tracker.srv_stub_buf);
DCE2_CoResetFragTracker(&cot->frag_tracker); DCE2_CoResetFragTracker(&cot->frag_tracker);
} }
cot->stub_data = frag_ptr; cot->stub_data = frag_ptr;
/* Opnum not in response header - have to use previous client's */ /* Opnum not in response header - have to use previous client's */
cot->ctx_id = ctx_id; cot->ctx_id = ctx_id;
cot->call_id = DceRpcCoCallId(co_hdr); cot->call_id = DceRpcCoCallId(co_hdr);
Packet* p = DetectionEngine::get_current_packet(); Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return;
if (DceRpcCoFirstFrag(co_hdr) && DceRpcCoLastFrag(co_hdr)) if (DceRpcCoFirstFrag(co_hdr) && DceRpcCoLastFrag(co_hdr))
{ {
int auth_len = DCE2_CoGetAuthLen(sd, co_hdr, frag_ptr, frag_len); int auth_len = DCE2_CoGetAuthLen(sd, co_hdr, frag_ptr, frag_len);
if (auth_len == -1) if (auth_len == -1)
return; return;
DCE2_CoSetRopts(sd, cot, co_hdr, p); DCE2_CoSetRopts(sd, cot, co_hdr, p);
} }
else else
skipping to change at line 1931 skipping to change at line 1956
* and request. * and request.
* *
********************************************************************/ ********************************************************************/
static void DCE2_CoDecode(DCE2_SsnData* sd, DCE2_CoTracker* cot, static void DCE2_CoDecode(DCE2_SsnData* sd, DCE2_CoTracker* cot,
const uint8_t* frag_ptr, uint16_t frag_len) const uint8_t* frag_ptr, uint16_t frag_len)
{ {
/* Already checked that we have enough data for header */ /* Already checked that we have enough data for header */
const DceRpcCoHdr* co_hdr = (const DceRpcCoHdr*)frag_ptr; const DceRpcCoHdr* co_hdr = (const DceRpcCoHdr*)frag_ptr;
int pdu_type = DceRpcCoPduType(co_hdr); int pdu_type = DceRpcCoPduType(co_hdr);
dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd); dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd);
Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return;
/* We've got the main header. Move past it to the /* We've got the main header. Move past it to the
* start of the pdu */ * start of the pdu */
dce2_move(frag_ptr, frag_len, sizeof(DceRpcCoHdr)); dce2_move(frag_ptr, frag_len, sizeof(DceRpcCoHdr));
/* Client specific pdu types - some overlap with server */ /* Client specific pdu types - some overlap with server */
if ( DetectionEngine::get_current_packet()->is_from_client() ) if ( p->is_from_client() )
{ {
switch (pdu_type) switch (pdu_type)
{ {
case DCERPC_PDU_TYPE__BIND: case DCERPC_PDU_TYPE__BIND:
dce_common_stats->co_bind++; dce_common_stats->co_bind++;
/* Make sure context id list and queue are initialized */ /* Make sure context id list and queue are initialized */
if (DCE2_CoInitCtxStorage(cot) != DCE2_RET__SUCCESS) if (DCE2_CoInitCtxStorage(cot) != DCE2_RET__SUCCESS)
return; return;
skipping to change at line 2140 skipping to change at line 2168
* to the detection engine. Whether we do or not is based on * to the detection engine. Whether we do or not is based on
* whether or not we are configured to do so. The number of bytes * whether or not we are configured to do so. The number of bytes
* in the fragmentation and segmentation buffers are calculated * in the fragmentation and segmentation buffers are calculated
* and if they exceed the amount we are configured for, we * and if they exceed the amount we are configured for, we
* reassemble. * reassemble.
* *
********************************************************************/ ********************************************************************/
static void DCE2_CoEarlyReassemble(DCE2_SsnData* sd, DCE2_CoTracker* cot) static void DCE2_CoEarlyReassemble(DCE2_SsnData* sd, DCE2_CoTracker* cot)
{ {
DCE2_Buffer* frag_buf = DCE2_CoGetFragBuf(&cot->frag_tracker); DCE2_Buffer* frag_buf = DCE2_CoGetFragBuf(&cot->frag_tracker);
Packet* p = DetectionEngine::get_current_packet();
if ( DetectionEngine::get_current_packet()->is_from_server() ) if ( (p == nullptr) || p->is_from_server() )
return; return;
if (!DCE2_BufferIsEmpty(frag_buf)) if (!DCE2_BufferIsEmpty(frag_buf))
{ {
uint32_t bytes = DCE2_BufferLength(frag_buf); uint32_t bytes = DCE2_BufferLength(frag_buf);
uint32_t seg_bytes = 0; uint32_t seg_bytes = 0;
if (!DCE2_BufferIsEmpty(cot->cli_seg.buf)) if (!DCE2_BufferIsEmpty(cot->cli_seg.buf))
{ {
uint16_t hdr_size = sizeof(DceRpcCoHdr) + sizeof(DceRpcCoRequest); uint16_t hdr_size = sizeof(DceRpcCoHdr) + sizeof(DceRpcCoRequest);
skipping to change at line 2209 skipping to change at line 2238
* Function: DCE2_CoGetSegRpkt() * Function: DCE2_CoGetSegRpkt()
* *
* Gets and returns a reassembly packet based on a segmentation * Gets and returns a reassembly packet based on a segmentation
* buffer. * buffer.
* *
********************************************************************/ ********************************************************************/
static Packet* DCE2_CoGetSegRpkt(DCE2_SsnData* sd, static Packet* DCE2_CoGetSegRpkt(DCE2_SsnData* sd,
const uint8_t* data_ptr, uint32_t data_len) const uint8_t* data_ptr, uint32_t data_len)
{ {
Packet* p = DetectionEngine::get_current_packet(); Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return nullptr;
Packet* rpkt = nullptr; Packet* rpkt = nullptr;
int smb_hdr_len = p->is_from_client() ? DCE2_MOCK_HDR_LEN__SMB_CLI : DCE2_MO int smb_hdr_len = p->is_from_client() ? DCE2_MOCK_HDR_LEN__SMB_CLI :
CK_HDR_LEN__SMB_SRV; DCE2_MOCK_HDR_LEN__SMB_SRV;
switch (sd->trans) switch (sd->trans)
{ {
case DCE2_TRANS_TYPE__SMB: case DCE2_TRANS_TYPE__SMB:
rpkt = DCE2_GetRpkt(p, DCE2_RPKT_TYPE__SMB_CO_SEG, data_ptr, data_len); rpkt = DCE2_GetRpkt(p, DCE2_RPKT_TYPE__SMB_CO_SEG, data_ptr, data_len);
if ( !rpkt ) if ( !rpkt )
return nullptr; return nullptr;
set_smb_reassembled_data(const_cast<uint8_t*>(rpkt->data), set_smb_reassembled_data(const_cast<uint8_t*>(rpkt->data),
skipping to change at line 2252 skipping to change at line 2284
* detection engine has yet to see this data. * detection engine has yet to see this data.
* *
********************************************************************/ ********************************************************************/
static void DCE2_CoSegDecode(DCE2_SsnData* sd, DCE2_CoTracker* cot, DCE2_CoSeg* seg) static void DCE2_CoSegDecode(DCE2_SsnData* sd, DCE2_CoTracker* cot, DCE2_CoSeg* seg)
{ {
const uint8_t* frag_ptr = nullptr; const uint8_t* frag_ptr = nullptr;
uint16_t frag_len = 0; uint16_t frag_len = 0;
dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd); dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd);
int smb_hdr_len; int smb_hdr_len;
if ( DetectionEngine::get_current_packet()->is_from_client() ) Packet* p = DetectionEngine::get_current_packet();
if (p == nullptr)
return;
if ( p->is_from_client() )
{ {
smb_hdr_len = DCE2_MOCK_HDR_LEN__SMB_CLI; smb_hdr_len = DCE2_MOCK_HDR_LEN__SMB_CLI;
dce_common_stats->co_cli_seg_reassembled++; dce_common_stats->co_cli_seg_reassembled++;
} }
else else
{ {
smb_hdr_len = DCE2_MOCK_HDR_LEN__SMB_SRV; smb_hdr_len = DCE2_MOCK_HDR_LEN__SMB_SRV;
dce_common_stats->co_srv_seg_reassembled++; dce_common_stats->co_srv_seg_reassembled++;
} }
skipping to change at line 2396 skipping to change at line 2432
* *
* *
********************************************************************/ ********************************************************************/
void DCE2_CoProcess(DCE2_SsnData* sd, DCE2_CoTracker* cot, void DCE2_CoProcess(DCE2_SsnData* sd, DCE2_CoTracker* cot,
const uint8_t* data_ptr, uint16_t data_len) const uint8_t* data_ptr, uint16_t data_len)
{ {
DCE2_CoSeg* seg = DCE2_CoGetSegPtr(cot); DCE2_CoSeg* seg = DCE2_CoGetSegPtr(cot);
dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd); dce2CommonStats* dce_common_stats = dce_get_proto_stats_ptr(sd);
uint32_t num_frags = 0; uint32_t num_frags = 0;
if (seg == nullptr)
return;
dce_common_stats->co_pdus++; dce_common_stats->co_pdus++;
co_reassembled = 0; co_reassembled = 0;
while (data_len > 0) while (data_len > 0)
{ {
num_frags++; num_frags++;
/* Fast track full fragments */ /* Fast track full fragments */
if (DCE2_BufferIsEmpty(seg->buf)) if (DCE2_BufferIsEmpty(seg->buf))
{ {
 End of changes. 16 change blocks. 
11 lines changed or deleted 48 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)