Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

547 lines
16 KiB

/*++
Copyright (c) 1992-1996 Microsoft Corporation
Module Name:
trapapi.c
Abstract:
Provides SNMP message authentication functionality for Proxy Agent.
Environment:
User Mode - Win32
Revision History:
10-May-1996 DonRyan
Removed banner from Technology Dynamics, Inc.
--*/
//--------------------------- WINDOWS DEPENDENCIES --------------------------
//--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
#include <windows.h>
#include <winsock.h>
#include <wsipx.h>
#include <errno.h>
#include <stdio.h>
#include <process.h>
#include <string.h>
//--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
#include <snmp.h>
#include <snmputil.h>
#include "wellknow.h"
#include "..\authapi.\berapi.h"
#include "..\authapi.\pduapi.h"
#include "..\authapi.\auth1157.h"
#include "..\authapi.\authxxxx.h"
#include "..\authapi.\authapi.h"
#include "regconf.h"
//--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
//--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
extern DWORD g_platformId;
extern AsnObjectIdentifier * g_enterprise;
//--------------------------- PRIVATE CONSTANTS -----------------------------
#define SGTTimeout ((DWORD)3600000)
//--------------------------- PRIVATE STRUCTS -------------------------------
//--------------------------- PRIVATE VARIABLES -----------------------------
static RFC1157VarBindList noVarBinds = { NULL, 0 };
//--------------------------- PRIVATE PROTOTYPES ----------------------------
int gethostname(OUT char *,IN int );
void dp_ipx(int, char *, SOCKADDR_IPX *, char *);
//--------------------------- PRIVATE PROCEDURES ----------------------------
#define bzero(lp, size) (void)memset(lp, 0, size)
//--------------------------- PUBLIC PROCEDURES -----------------------------
SNMPAPI
SNMP_FUNC_TYPE
SnmpSvcGenerateTrap(
IN AsnObjectIdentifier * enterprise,
IN AsnInteger genericTrap,
IN AsnInteger specificTrap,
IN AsnTimeticks timeStamp,
IN RFC1157VarBindList * variableBindings)
{
static BOOL fFirstTime = TRUE;
static HANDLE hGenerateTrapMutex;
static char myname[128];
static struct sockaddr mysocket;
static SnmpMgmtCom request;
static SOCKET fd_inet, fd_ipx, fd;
static unsigned long nul_s_addr = 0L;
struct sockaddr dest;
BYTE *pBuf;
UINT length;
INT i, j;
if (fFirstTime)
{
struct sockaddr localAddress;
BOOL fSuccess;
fFirstTime = FALSE;
fSuccess = FALSE;
// initialize trap destinations
if (!tdConfig(&trapDests, &trapDestsLen))
{
SnmpUtilVarBindListFree(variableBindings);
return FALSE;
}
// setup 2 trap generation sockets, one for inet, one for ipx
// block...
{
struct sockaddr_in localAddress_in;
localAddress_in.sin_family = AF_INET;
localAddress_in.sin_port = htons(0);
localAddress_in.sin_addr.s_addr = ntohl(INADDR_ANY);
bcopy(&localAddress_in, &localAddress, sizeof(localAddress_in));
} // end block.
if ((fd_inet = socket(AF_INET, SOCK_DGRAM, 0)) == (SOCKET)-1)
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error %d creating udp trap generation socket.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
}
else if (bind(fd_inet, &localAddress, sizeof(localAddress)) != 0)
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d binding udp trap generation socket.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
}
else
{
fSuccess = TRUE;
}
{
struct sockaddr_ipx localAddress_ipx;
bzero(&localAddress_ipx,sizeof(localAddress_ipx));
localAddress_ipx.sa_family = AF_IPX;
bcopy(&localAddress_ipx, &localAddress, sizeof(localAddress_ipx));
}
if ((fd_ipx = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == (SOCKET)-1)
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error %d creating ipx trap generation socket.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
}
else if (bind(fd_ipx, &localAddress, sizeof(localAddress)) != 0)
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d binding ipx trap generation socket.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
}
else
{
fSuccess = TRUE;
}
if (!fSuccess)
return FALSE;
// create mutex...
if ((hGenerateTrapMutex = CreateMutex(NULL, FALSE, NULL)) == NULL)
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d creating trap generaion mutex.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
return FALSE;
}
// other one-time initialization...
request.pdu.pduType = ASN_RFC1157_TRAP;
if (fd_inet != (SOCKET)-1)
{
if (gethostname(myname, sizeof(myname)) == -1)
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error on gethostname %d.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
return FALSE;
}
if (!SnmpSvcAddrToSocket(myname, &mysocket) == -1)
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error on SnmpSvcAddrToSocket %d.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
return FALSE;
}
}
} // end if (fFirstTime)
// take mutex
if (WaitForSingleObject(hGenerateTrapMutex, SGTTimeout)
== 0xffffffff)
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d waiting for trap generation mutex.\n", GetLastError()));
SnmpUtilVarBindListFree(variableBindings);
return FALSE;
}
// build pdu
request.pdu.pduValue.trap.genericTrap = genericTrap;
request.pdu.pduValue.trap.specificTrap = specificTrap;
request.pdu.pduValue.trap.timeStamp = timeStamp;
request.pdu.pduValue.trap.varBinds.list = variableBindings->list;
request.pdu.pduValue.trap.varBinds.len = variableBindings->len;
// check if default enterprise oid has been overridden
if (enterprise && enterprise->idLength && enterprise->ids)
{
request.pdu.pduValue.trap.enterprise.idLength = enterprise->idLength;
request.pdu.pduValue.trap.enterprise.ids = enterprise->ids;
}
else
{
request.pdu.pduValue.trap.enterprise.idLength = g_enterprise->idLength;
request.pdu.pduValue.trap.enterprise.ids = g_enterprise->ids;
}
for (i=0; i<trapDestsLen; i++)
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: processing trap destinations for community %s.\n",
trapDests[i].communityName));
for (j=0; j<trapDests[i].addrLen; j++)
{
request.community.stream = trapDests[i].communityName;
request.community.length = strlen(trapDests[i].communityName);
request.community.dynamic = FALSE;
switch (trapDests[i].addrList[j].addrEncoding.sa_family)
{
case AF_INET:
{
struct sockaddr_in destAddress_in;
struct servent *serv;
if (fd_inet == (SOCKET)-1) // don't have an IP socket
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: cannot send udp trap because no socket available.\n"));
continue;
}
destAddress_in.sin_family = AF_INET;
if ((serv = getservbyname( "snmp-trap", "udp" )) == NULL) {
destAddress_in.sin_port = htons(162);
} else {
destAddress_in.sin_port = (SHORT)serv->s_port;
}
destAddress_in.sin_addr.s_addr = ((struct sockaddr_in *)(&trapDests[i].addrList[j].addrEncoding))->sin_addr.s_addr;
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: processing ip trap destination %u.%u.%u.%u.\n",
destAddress_in.sin_addr.S_un.S_un_b.s_b1,
destAddress_in.sin_addr.S_un.S_un_b.s_b2,
destAddress_in.sin_addr.S_un.S_un_b.s_b3,
destAddress_in.sin_addr.S_un.S_un_b.s_b4));
bcopy(&destAddress_in, &dest, sizeof(destAddress_in));
}
// include local agent addr in pdu (ip only)
request.pdu.pduValue.trap.agentAddr.stream =
(BYTE *)&((struct sockaddr_in *)(&mysocket))->sin_addr.s_addr;
request.pdu.pduValue.trap.agentAddr.length = 4;
fd = fd_inet;
break;
case AF_IPX:
{
SOCKADDR_IPX *pdest = (SOCKADDR_IPX *) &dest;
if (fd_ipx == (SOCKET)-1) // don't have an IPX socket
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: cannot send ipx trap because no socket available.\n"));
continue;
}
// sa_family, sa_netnum, and sa_nodenum are already set
bcopy(&trapDests[i].addrList[j].addrEncoding, &dest,
sizeof(SOCKADDR_IPX));
pdest->sa_socket = htons(WKSN_IPX_TRAP);
dp_ipx(SNMP_LOG_TRACE, "SNMP: TRAP: processing ipx trap destination ", pdest, ".\n");
}
// include empty agent addr in pdu (ipx only)
request.pdu.pduValue.trap.agentAddr.stream = (BYTE *)&nul_s_addr;
request.pdu.pduValue.trap.agentAddr.length = 4;
fd = fd_ipx;
break;
default:
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: cannot send trap because sa_family invalid.\n"));
continue;
}
}
pBuf = NULL;
length = 0;
if (!SnmpSvcEncodeMessage(ASN_SEQUENCE, &request, &pBuf, &length))
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error on SnmpSvcEncodeMessage %d.\n",
GetLastError()));
SnmpUtilMemFree(pBuf);
continue;
}
// transmit trap pdu
if ((length = sendto(fd, pBuf, length, 0, &dest, sizeof(dest)))
== -1)
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d sending trap.\n", GetLastError()));
//a serious error?
}
else
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: trap sent successfully.\n"));
}
SnmpUtilMemFree(pBuf);
} // end for ()
} // end for ()
SnmpUtilVarBindListFree(variableBindings);
// release mutex
if (!ReleaseMutex(hGenerateTrapMutex))
{
SNMPDBG((SNMP_LOG_ERROR, "SNMP: TRAP: error %d releasing trap generation mutex.\n", GetLastError()));
return FALSE;
}
return TRUE;
} // end SnmpSvcGenerateTrap()
SNMPAPI
SNMP_FUNC_TYPE
SnmpSvcGenerateColdStartTrap(
IN AsnInteger timeStamp)
{
if (!SnmpSvcGenerateTrap(
NULL, // use default oid
SNMP_GENERICTRAP_COLDSTART,
0,
timeStamp,
&noVarBinds))
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error on SnmpServiceGenerateTrap %d.\n", GetLastError()));
return FALSE;
}
return TRUE;
} // end SnmpSvcGenerateColdStartTrap()
SNMPAPI
SNMP_FUNC_TYPE
SnmpSvcGenerateWarmStartTrap(
IN AsnInteger timeStamp)
{
if (!SnmpSvcGenerateTrap(
NULL, // use default oid
SNMP_GENERICTRAP_WARMSTART,
0,
timeStamp,
&noVarBinds))
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error on SnmpServiceGenerateTrap %d.\n", GetLastError()));
return FALSE;
}
return TRUE;
} // end SnmpSvcGenerateWarmStartTrap()
SNMPAPI
SNMP_FUNC_TYPE
SnmpSvcGenerateLinkUpTrap(
IN AsnInteger timeStamp,
IN RFC1157VarBindList * variableBindings)
{
if (!SnmpSvcGenerateTrap(
NULL, // use default oid
SNMP_GENERICTRAP_LINKUP,
0,
timeStamp,
variableBindings))
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error on SnmpServiceGenerateTrap %d.\n", GetLastError()));
return FALSE;
}
return TRUE;
} // end SnmpSvcGenerateLinkUpTrap()
SNMPAPI
SNMP_FUNC_TYPE
SnmpSvcGenerateLinkDownTrap(
IN AsnInteger timeStamp,
IN RFC1157VarBindList * variableBindings)
{
if (!SnmpSvcGenerateTrap(
NULL, // use default oid
SNMP_GENERICTRAP_LINKDOWN,
0,
timeStamp,
variableBindings))
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error on SnmpServiceGenerateTrap %d.\n", GetLastError()));
return FALSE;
}
return TRUE;
} // end SnmpSvcGenerateLinkDownTrap()
SNMPAPI
SNMP_FUNC_TYPE
SnmpSvcGenerateAuthFailTrap(
AsnInteger timeStamp)
{
if (!SnmpSvcGenerateTrap(
NULL, // use default oid
SNMP_GENERICTRAP_AUTHFAILURE,
0,
timeStamp,
&noVarBinds))
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: TRAP: error on SnmpServiceGenerateTrap %d.\n", GetLastError()));
return FALSE;
}
return TRUE;
} // end SnmpSvcGenerateAuthFailTrap()
// authenticate community of rfc1157 message with valid communities in registry
BOOL commauth(RFC1157Message *message)
{
static BOOL fFirstTime = TRUE;
BOOL fFound = FALSE;
INT i;
if (fFirstTime)
{
fFirstTime = FALSE;
vcConfig(&validComms, &validCommsLen);
}
if (validCommsLen > 0)
{
for(i=0; i < validCommsLen; i++)
{
if ((strlen(validComms[i].communityName) == message->community.length) &&
!strncmp(message->community.stream, validComms[i].communityName, message->community.length))
{
fFound = TRUE;
break;
}
} // end for ()
}
else
{
fFound = TRUE; // no entries means all communities allowed
} // end if
if (!fFound)
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: PDU: invalid community filtered.\n"));
if (enableAuthTraps)
{
if (!SnmpSvcGenerateAuthFailTrap(SnmpSvcGetUptime()))
{
SNMPDBG((SNMP_LOG_TRACE, "SNMP: PDU: error on SnmpSvcGenerateAuthFailTrap %d.\n",
GetLastError()));
}
} // end if
} // end if
return fFound;
} // end commauth()
//-------------------------------- END --------------------------------------
// display IPX address in 00000001.123456789ABC form
void dp_ipx(int level, char *msg1, SOCKADDR_IPX* addr, char *msg2)
{
SNMPDBG((level, "%s%02X%02X%02X%02X.%02X%02X%02X%02X%02X%02X%s",
msg1,
(unsigned char)addr->sa_netnum[0],
(unsigned char)addr->sa_netnum[1],
(unsigned char)addr->sa_netnum[2],
(unsigned char)addr->sa_netnum[3],
(unsigned char)addr->sa_nodenum[0],
(unsigned char)addr->sa_nodenum[1],
(unsigned char)addr->sa_nodenum[2],
(unsigned char)addr->sa_nodenum[3],
(unsigned char)addr->sa_nodenum[4],
(unsigned char)addr->sa_nodenum[5],
msg2));
}