📄 snmpv3.c
字号:
/* READ: Authentication Pass Phrase */
if (!cp) {
config_perror("no authentication pass phrase");
usm_free_user(newuser);
return;
}
cp = copy_word(cp, buf);
/* And turn it into a localized key */
ret = generate_Ku(newuser->authProtocol, newuser->authProtocolLen,
(u_char *)buf, strlen(buf),
userKey, &userKeyLen );
if (ret != SNMPERR_SUCCESS) {
config_perror("Error generating auth key from pass phrase.");
usm_free_user(newuser);
return;
}
newuser->authKeyLen =
sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen);
newuser->authKey = (u_char *) malloc(newuser->authKeyLen);
ret = generate_kul(newuser->authProtocol, newuser->authProtocolLen,
newuser->engineID, newuser->engineIDLen,
userKey, userKeyLen,
newuser->authKey, &newuser->authKeyLen );
if (ret != SNMPERR_SUCCESS) {
config_perror("Error generating localized auth key (Kul) from Ku.");
usm_free_user(newuser);
return;
}
if (!cp)
goto add; /* no privacy type (which is legal) */
/* READ: Privacy Type */
if (strncmp(cp, "DES", 3) == 0) {
memcpy(newuser->privProtocol, usmDESPrivProtocol,
sizeof(usmDESPrivProtocol));
} else {
config_perror("Unknown privacy protocol");
usm_free_user(newuser);
return;
}
cp = skip_token(cp);
/* READ: Authentication Pass Phrase */
if (!cp) {
/* assume the same as the authentication key */
memdup(&newuser->privKey, newuser->authKey, newuser->authKeyLen);
} else {
cp = copy_word(cp, buf);
/* And turn it into a localized key */
ret = generate_Ku(newuser->authProtocol, newuser->authProtocolLen,
(u_char *)buf, strlen(buf),
userKey, &userKeyLen );
if (ret != SNMPERR_SUCCESS) {
config_perror("Error generating priv key from pass phrase.");
usm_free_user(newuser);
return;
}
ret = sc_get_properlength(newuser->authProtocol, newuser->authProtocolLen);
if (ret < 0) {
config_perror("Error getting proper key length for priv algorithm.");
usm_free_user(newuser);
return;
}
newuser->privKeyLen = ret;
newuser->privKey = (u_char *) malloc(newuser->privKeyLen);
ret = generate_kul(newuser->authProtocol, newuser->authProtocolLen,
newuser->engineID, newuser->engineIDLen,
userKey, userKeyLen,
newuser->privKey, &newuser->privKeyLen );
if (ret != SNMPERR_SUCCESS) {
config_perror("Error generating localized priv key (Kul) from Ku.");
usm_free_user(newuser);
return;
}
}
add:
usm_add_user(newuser);
DEBUGMSGTL(("usmUser","created a new user %s\n", newuser->secName));
}
/*******************************************************************-o-******
* engineBoots_conf
*
* Parameters:
* *word
* *cptr
*
* Line syntax:
* engineBoots <num_boots>
*/
void
engineBoots_conf(const char *word, char *cptr)
{
engineBoots = atoi(cptr)+1;
DEBUGMSGTL(("snmpv3","engineBoots: %d\n",engineBoots));
}
/*******************************************************************-o-******
* engineID_conf
*
* Parameters:
* *word
* *cptr
*
* This function reads a string from the configuration file and uses that
* string to initialize the engineID. It's assumed to be human readable.
*/
void
engineID_conf(const char *word, char *cptr)
{
setup_engineID(NULL, cptr);
DEBUGMSGTL(("snmpv3","initialized engineID with: %s\n",cptr));
}
void
version_conf(const char *word, char *cptr)
{
if (strcmp(cptr,"1") == 0) {
ds_set_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION, SNMP_VERSION_1);
} else if (strcasecmp(cptr,"2c") == 0) {
ds_set_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION, SNMP_VERSION_2c);
} else if (strcmp(cptr,"3") == 0) {
ds_set_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION, SNMP_VERSION_3);
} else {
config_perror("Unknown version specification");
return;
}
DEBUGMSGTL(("snmpv3","set default version to %d\n",
ds_get_int(DS_LIBRARY_ID, DS_LIB_SNMPVERSION)));
}
/* engineID_old_conf(const char *, char *):
Reads a octet string encoded engineID into the oldEngineID and
oldEngineIDLen pointers.
*/
void
oldengineID_conf(const char *word, char *cptr)
{
read_config_read_octet_string(cptr, &oldEngineID, &oldEngineIDLength);
}
/*******************************************************************-o-******
* init_snmpv3
*
* Parameters:
* *type Label for the config file "type" used by calling entity.
*
* Set time and engineID.
* Set parsing functions for config file tokens.
* Initialize SNMP Crypto API (SCAPI).
*/
void
init_snmpv3(const char *type) {
gettimeofday(&snmpv3starttime, NULL);
if (type == NULL)
type = "snmpapp";
if (type && !strcmp(type,"snmpapp")) {
setup_engineID(NULL,"__snmpapp__");
} else {
setup_engineID(NULL, NULL);
}
/* initialize submodules */
init_usm();
/* we need to be called back later */
snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG,
init_snmpv3_post_config, NULL);
/* we need to be called back later */
snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
snmpv3_store, (void *) type);
#if !defined(USE_INTERNAL_MD5)
/* doesn't belong here at all */
sc_init();
#endif /* !USE_INTERNAL_MD5 */
/* register all our configuration handlers (ack, there's a lot) */
/* handle engineID setup before everything else which may depend on it */
register_premib_handler(type,"engineID", engineID_conf, NULL, "string");
register_premib_handler(type,"oldEngineID", oldengineID_conf, NULL, NULL);
register_config_handler(type,"engineBoots", engineBoots_conf, NULL, NULL);
/* default store config entries */
ds_register_config(ASN_OCTET_STR, "snmp", "defSecurityName", DS_LIBRARY_ID,
DS_LIB_SECNAME);
ds_register_config(ASN_OCTET_STR, "snmp", "defContext", DS_LIBRARY_ID,
DS_LIB_CONTEXT);
ds_register_config(ASN_OCTET_STR, "snmp", "defPassphrase", DS_LIBRARY_ID,
DS_LIB_PASSPHRASE);
ds_register_config(ASN_OCTET_STR, "snmp", "defAuthPassphrase", DS_LIBRARY_ID,
DS_LIB_AUTHPASSPHRASE);
ds_register_config(ASN_OCTET_STR, "snmp", "defPrivPassphrase", DS_LIBRARY_ID,
DS_LIB_PRIVPASSPHRASE);
register_config_handler("snmp","defVersion", version_conf, NULL, "1|2c|3");
register_config_handler("snmp","defAuthType", snmpv3_authtype_conf, NULL,
"MD5|SHA");
register_config_handler("snmp","defPrivType", snmpv3_privtype_conf, NULL,
"DES (currently the only possible value)");
register_config_handler("snmp","defSecurityLevel", snmpv3_secLevel_conf,
NULL, "noAuthNoPriv|authNoPriv|authPriv");
register_config_handler(type,"userSetAuthPass", usm_set_password, NULL,
"secname engineIDLen engineID pass");
register_config_handler(type,"userSetPrivPass", usm_set_password, NULL,
"secname engineIDLen engineID pass");
register_config_handler(type,"userSetAuthKey", usm_set_password, NULL,
"secname engineIDLen engineID KuLen Ku");
register_config_handler(type,"userSetPrivKey", usm_set_password, NULL,
"secname engineIDLen engineID KuLen Ku");
register_config_handler(type,"userSetAuthLocalKey", usm_set_password, NULL,
"secname engineIDLen engineID KulLen Kul");
register_config_handler(type,"userSetPrivLocalKey", usm_set_password, NULL,
"secname engineIDLen engineID KulLen Kul");
}
/*
* initializations for SNMPv3 to be called after the configuration files
* have been read.
*/
int
init_snmpv3_post_config(int majorid, int minorid, void *serverarg,
void *clientarg) {
int engineIDLen;
u_char *c_engineID;
c_engineID = snmpv3_generate_engineID(&engineIDLen);
if ( engineIDLen < 0 ) {
/* Somethine went wrong - help! */
return SNMPERR_GENERR;
}
/* if our engineID has changed at all, the boots record must be set to 1 */
if (engineIDLen != (int)oldEngineIDLength ||
oldEngineID == NULL || c_engineID == NULL ||
memcmp(oldEngineID, c_engineID, engineIDLen) != 0) {
engineBoots = 1;
}
/* set our local engineTime in the LCD timing cache */
set_enginetime(c_engineID, engineIDLen,
snmpv3_local_snmpEngineBoots(),
snmpv3_local_snmpEngineTime(),
TRUE);
free(c_engineID);
return SNMPERR_SUCCESS;
}
/*******************************************************************-o-******
* store_snmpv3
*
* Parameters:
* *type
*/
int
snmpv3_store(int majorID, int minorID, void *serverarg, void *clientarg) {
char line[SNMP_MAXBUF_SMALL];
u_char c_engineID[SNMP_MAXBUF_SMALL];
int engineIDLen;
const char *type = (const char *) clientarg;
if (type == NULL) /* should never happen, since the arg is ours */
type = "unknown";
sprintf(line, "engineBoots %ld", engineBoots);
read_config_store(type, line);
engineIDLen = snmpv3_get_engineID(c_engineID, SNMP_MAXBUF_SMALL);
if (engineIDLen) {
/* store the engineID used for this run */
sprintf(line, "oldEngineID ");
read_config_save_octet_string(line+strlen(line), c_engineID,
engineIDLen);
read_config_store(type, line);
}
return SNMPERR_SUCCESS;
} /* snmpv3_store() */
u_long
snmpv3_local_snmpEngineBoots(void)
{
return engineBoots;
}
/*******************************************************************-o-******
* snmpv3_get_engineID
*
* Parameters:
* *buf
* buflen
*
* Returns:
* Length of engineID On Success
* SNMPERR_GENERR Otherwise.
*
*
* Store engineID in buf; return the length.
*
*/
int
snmpv3_get_engineID(u_char *buf, size_t buflen)
{
/*
* Sanity check.
*/
if ( !buf || (buflen < engineIDLength) ) {
return SNMPERR_GENERR;
}
memcpy(buf,engineID,engineIDLength);
return engineIDLength;
} /* end snmpv3_get_engineID() */
/*******************************************************************-o-******
* snmpv3_clone_engineID
*
* Parameters:
* **dest
* *dest_len
* src
* srclen
*
* Returns:
* Length of engineID On Success
* 0 Otherwise.
*
*
* Clones engineID, creates memory
*
*/
int
snmpv3_clone_engineID(u_char **dest, size_t* destlen, u_char*src, size_t srclen)
{
if ( !dest || !destlen ) return 0;
*dest = NULL; *destlen = 0;
if (srclen && src) {
*dest = (u_char*)malloc((unsigned)srclen * sizeof(u_char));
if (*dest == NULL) return 0;
memmove(*dest, src, srclen * sizeof(u_char));
*destlen = srclen;
}
return *destlen;
} /* end snmpv3_clone_engineID() */
/*******************************************************************-o-******
* snmpv3_generate_engineID
*
* Parameters:
* *length
*
* Returns:
* Pointer to copy of engineID On Success.
* NULL If malloc() or snmpv3_get_engineID()
* fail.
*
* Generates a malloced copy of our engineID.
*
* 'length' is set to the length of engineID -OR- < 0 on failure.
*/
u_char *
snmpv3_generate_engineID(int *length)
{
u_char *newID;
newID = (u_char *) malloc(engineIDLength);
if (newID) {
*length = snmpv3_get_engineID(newID, engineIDLength);
}
if (*length < 0) {
SNMP_FREE(newID);
newID = NULL;
}
return newID;
} /* end snmpv3_generate_engineID() */
/* snmpv3_local_snmpEngineTime(): return the number of seconds since the
snmpv3 engine last incremented engine_boots */
u_long
snmpv3_local_snmpEngineTime(void)
{
struct timeval now;
gettimeofday(&now, NULL);
return calculate_time_diff(&now, &snmpv3starttime)/100;
}
#ifdef SNMP_TESTING_CODE
/* snmpv3_set_engineBootsAndTime(): this function does not exist. Go away. */
/* It certainly should never be used, unless in a testing scenero,
which is why it was created */
void
snmpv3_set_engineBootsAndTime(int boots, int ttime) {
engineBoots = boots;
gettimeofday(&snmpv3starttime, NULL);
snmpv3starttime.tv_sec -= ttime;
}
#endif
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -