-
Notifications
You must be signed in to change notification settings - Fork 8k
ext/snmp: various internals rewrite. #17368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 8 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
d3d8859
ext/snmp: various internals rewrite.
devnexen 29d56a5
add test
devnexen dc963f3
to exception
devnexen 8dfc82d
further initialisation type check and segfault fix.
devnexen 305631d
revert renaming
devnexen 4d076cf
changes from review
devnexen 051a82a
renaming
devnexen b466f12
update comment
devnexen 0fead78
last remaining changes.
devnexen dc02a8f
fix test
devnexen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -153,7 +153,7 @@ static PHP_GINIT_FUNCTION(snmp) | |
} \ | ||
} | ||
|
||
static void netsnmp_session_free(php_snmp_session **session) /* {{{ */ | ||
static void snmp_session_free(php_snmp_session **session) /* {{{ */ | ||
{ | ||
if (*session) { | ||
PHP_SNMP_SESSION_FREE(peername); | ||
|
@@ -174,7 +174,7 @@ static void php_snmp_object_free_storage(zend_object *object) /* {{{ */ | |
return; | ||
} | ||
|
||
netsnmp_session_free(&(intern->session)); | ||
snmp_session_free(&(intern->session)); | ||
|
||
zend_object_std_dtor(&intern->zo); | ||
} | ||
|
@@ -829,31 +829,70 @@ static bool php_snmp_parse_oid( | |
} | ||
/* }}} */ | ||
|
||
/* {{{ netsnmp_session_init | ||
allocates memory for session and session->peername, caller should free it manually using netsnmp_session_free() and efree() | ||
/* {{{ snmp_session_init | ||
allocates memory for session and session->peername, caller should free it manually using snmp_session_free() and efree() | ||
*/ | ||
static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, int timeout, int retries) | ||
static bool snmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, zend_long timeout, zend_long retries, int timeout_argument_offset) | ||
{ | ||
php_snmp_session *session; | ||
char *pptr, *host_ptr; | ||
bool force_ipv6 = false; | ||
int n; | ||
struct sockaddr **psal; | ||
struct sockaddr **res; | ||
|
||
*session_p = 0; | ||
|
||
ZEND_ASSERT(hostname != NULL); | ||
ZEND_ASSERT(community != NULL); | ||
|
||
if (zend_str_has_nul_byte(hostname)) { | ||
zend_argument_value_error(2, "must not contain any null bytes"); | ||
return false; | ||
} | ||
|
||
if (ZSTR_LEN(hostname) >= MAX_NAME_LEN) { | ||
zend_argument_value_error(2, "length must be lower than %d", MAX_NAME_LEN); | ||
return false; | ||
} | ||
|
||
if (zend_str_has_nul_byte(community)) { | ||
zend_argument_value_error(3, "must not contain any null bytes"); | ||
return false; | ||
} | ||
|
||
if (ZSTR_LEN(community) == 0) { | ||
zend_argument_value_error(3, "cannot be empty"); | ||
return false; | ||
} | ||
|
||
if (timeout_argument_offset != -1) { | ||
if (timeout < -1 || timeout > LONG_MAX) { | ||
zend_argument_value_error(timeout_argument_offset, "must be between -1 and %ld", LONG_MAX); | ||
return false; | ||
} | ||
|
||
if (retries < -1 || retries > INT_MAX) { | ||
zend_argument_value_error(timeout_argument_offset + 1, "must be between -1 and %d", INT_MAX); | ||
return false; | ||
} | ||
} | ||
|
||
// TODO: Do not strip and re-add the port in peername? | ||
unsigned remote_port = SNMP_PORT; | ||
unsigned short remote_port = SNMP_PORT; | ||
int tmp_port; | ||
|
||
*session_p = (php_snmp_session *)emalloc(sizeof(php_snmp_session)); | ||
session = *session_p; | ||
memset(session, 0, sizeof(php_snmp_session)); | ||
|
||
snmp_sess_init(session); | ||
|
||
session->version = version; | ||
session->version = (long)version; | ||
|
||
session->peername = emalloc(MAX_NAME_LEN); | ||
/* we copy original hostname for further processing */ | ||
strlcpy(session->peername, ZSTR_VAL(hostname), MAX_NAME_LEN); | ||
memcpy(session->peername, ZSTR_VAL(hostname), ZSTR_LEN(hostname) + 1); | ||
host_ptr = session->peername; | ||
|
||
/* Reading the hostname and its optional non-default port number */ | ||
|
@@ -862,7 +901,13 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend | |
host_ptr++; | ||
if ((pptr = strchr(host_ptr, ']'))) { | ||
if (pptr[1] == ':') { | ||
remote_port = atoi(pptr + 2); | ||
char *pport = pptr + 2; | ||
tmp_port = atoi(pport); | ||
if (tmp_port < 0 || tmp_port > USHRT_MAX) { | ||
zend_value_error("remote port must be between 0 and %u", USHRT_MAX); | ||
|
||
return false; | ||
} | ||
remote_port = (unsigned short)tmp_port; | ||
} | ||
*pptr = '\0'; | ||
} else { | ||
|
@@ -871,7 +916,13 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend | |
} | ||
} else { /* IPv4 address */ | ||
if ((pptr = strchr(host_ptr, ':'))) { | ||
remote_port = atoi(pptr + 1); | ||
char *pport = pptr + 1; | ||
tmp_port = atoi(pport); | ||
if (tmp_port < 0 || tmp_port > USHRT_MAX) { | ||
zend_value_error("remote port must be between 0 and %u", USHRT_MAX); | ||
|
||
return false; | ||
} | ||
remote_port = (unsigned short)tmp_port; | ||
*pptr = '\0'; | ||
} | ||
} | ||
|
@@ -920,7 +971,7 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend | |
if (remote_port != SNMP_PORT) { | ||
size_t peername_length = strlen(session->peername); | ||
pptr = session->peername + peername_length; | ||
snprintf(pptr, MAX_NAME_LEN - peername_length, ":%d", remote_port); | ||
snprintf(pptr, MAX_NAME_LEN - peername_length, ":%u", remote_port); | ||
} | ||
|
||
php_network_freeaddresses(psal); | ||
|
@@ -935,14 +986,14 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend | |
session->community_len = ZSTR_LEN(community); | ||
} | ||
|
||
session->retries = retries; | ||
session->timeout = timeout; | ||
session->retries = (int)retries; | ||
session->timeout = (long)timeout; | ||
return true; | ||
} | ||
/* }}} */ | ||
|
||
/* {{{ Set the security level in the snmpv3 session */ | ||
static bool netsnmp_session_set_sec_level(struct snmp_session *s, zend_string *level) | ||
static bool snmp_session_set_sec_level(struct snmp_session *s, zend_string *level) | ||
{ | ||
if (zend_string_equals_literal_ci(level, "noAuthNoPriv") || zend_string_equals_literal_ci(level, "nanp")) { | ||
s->securityLevel = SNMP_SEC_LEVEL_NOAUTH; | ||
|
@@ -959,7 +1010,7 @@ static bool netsnmp_session_set_sec_level(struct snmp_session *s, zend_string *l | |
/* }}} */ | ||
|
||
/* {{{ Set the authentication protocol in the snmpv3 session */ | ||
static bool netsnmp_session_set_auth_protocol(struct snmp_session *s, zend_string *prot) | ||
static bool snmp_session_set_auth_protocol(struct snmp_session *s, zend_string *prot) | ||
{ | ||
#ifndef DISABLE_MD5 | ||
if (zend_string_equals_literal_ci(prot, "MD5")) { | ||
|
@@ -1011,7 +1062,7 @@ static bool netsnmp_session_set_auth_protocol(struct snmp_session *s, zend_strin | |
/* }}} */ | ||
|
||
/* {{{ Set the security protocol in the snmpv3 session */ | ||
static bool netsnmp_session_set_sec_protocol(struct snmp_session *s, zend_string *prot) | ||
static bool snmp_session_set_sec_protocol(struct snmp_session *s, zend_string *prot) | ||
{ | ||
#ifndef NETSNMP_DISABLE_DES | ||
if (zend_string_equals_literal_ci(prot, "DES")) { | ||
|
@@ -1048,7 +1099,7 @@ static bool netsnmp_session_set_sec_protocol(struct snmp_session *s, zend_string | |
/* }}} */ | ||
|
||
/* {{{ Make key from pass phrase in the snmpv3 session */ | ||
static bool netsnmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass) | ||
static bool snmp_session_gen_auth_key(struct snmp_session *s, zend_string *pass) | ||
{ | ||
int snmp_errno; | ||
s->securityAuthKeyLen = USM_AUTH_KU_LEN; | ||
|
@@ -1063,7 +1114,7 @@ static bool netsnmp_session_gen_auth_key(struct snmp_session *s, zend_string *pa | |
/* }}} */ | ||
|
||
/* {{{ Make key from pass phrase in the snmpv3 session */ | ||
static bool netsnmp_session_gen_sec_key(struct snmp_session *s, zend_string *pass) | ||
static bool snmp_session_gen_sec_key(struct snmp_session *s, zend_string *pass) | ||
{ | ||
int snmp_errno; | ||
|
||
|
@@ -1079,7 +1130,7 @@ static bool netsnmp_session_gen_sec_key(struct snmp_session *s, zend_string *pas | |
/* }}} */ | ||
|
||
/* {{{ Set context Engine Id in the snmpv3 session */ | ||
static bool netsnmp_session_set_contextEngineID(struct snmp_session *s, zend_string * contextEngineID) | ||
static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string * contextEngineID) | ||
{ | ||
size_t ebuf_len = 32, eout_len = 0; | ||
uint8_t *ebuf = (uint8_t *) emalloc(ebuf_len); | ||
|
@@ -1102,40 +1153,40 @@ static bool netsnmp_session_set_contextEngineID(struct snmp_session *s, zend_str | |
/* }}} */ | ||
|
||
/* {{{ Set all snmpv3-related security options */ | ||
static bool netsnmp_session_set_security(struct snmp_session *session, zend_string *sec_level, | ||
static bool snmp_session_set_security(struct snmp_session *session, zend_string *sec_level, | ||
zend_string *auth_protocol, zend_string *auth_passphrase, zend_string *priv_protocol, | ||
zend_string *priv_passphrase, zend_string *contextName, zend_string *contextEngineID) | ||
{ | ||
|
||
/* Setting the security level. */ | ||
if (!netsnmp_session_set_sec_level(session, sec_level)) { | ||
if (!snmp_session_set_sec_level(session, sec_level)) { | ||
/* ValueError already generated, just bail out */ | ||
return false; | ||
} | ||
|
||
if (session->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { | ||
|
||
/* Setting the authentication protocol. */ | ||
if (!netsnmp_session_set_auth_protocol(session, auth_protocol)) { | ||
if (!snmp_session_set_auth_protocol(session, auth_protocol)) { | ||
/* ValueError already generated, just bail out */ | ||
return false; | ||
} | ||
|
||
/* Setting the authentication passphrase. */ | ||
if (!netsnmp_session_gen_auth_key(session, auth_passphrase)) { | ||
if (!snmp_session_gen_auth_key(session, auth_passphrase)) { | ||
/* Warning message sent already, just bail out */ | ||
return false; | ||
} | ||
|
||
if (session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { | ||
/* Setting the security protocol. */ | ||
if (!netsnmp_session_set_sec_protocol(session, priv_protocol)) { | ||
if (!snmp_session_set_sec_protocol(session, priv_protocol)) { | ||
/* ValueError already generated, just bail out */ | ||
return false; | ||
} | ||
|
||
/* Setting the security protocol passphrase. */ | ||
if (!netsnmp_session_gen_sec_key(session, priv_passphrase)) { | ||
if (!snmp_session_gen_sec_key(session, priv_passphrase)) { | ||
/* Warning message sent already, just bail out */ | ||
return false; | ||
} | ||
|
@@ -1149,7 +1200,7 @@ static bool netsnmp_session_set_security(struct snmp_session *session, zend_stri | |
} | ||
|
||
/* Setting contextEngineIS if specified */ | ||
if (contextEngineID && ZSTR_LEN(contextEngineID) && !netsnmp_session_set_contextEngineID(session, contextEngineID)) { | ||
if (contextEngineID && ZSTR_LEN(contextEngineID) && !snmp_session_set_contextEngineID(session, contextEngineID)) { | ||
/* Warning message sent already, just bail out */ | ||
return false; | ||
} | ||
|
@@ -1176,6 +1227,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) | |
struct objid_query objid_query; | ||
php_snmp_session *session; | ||
int session_less_mode = (getThis() == NULL); | ||
int timeout_argument_offset = -1; | ||
php_snmp_object *snmp_object; | ||
php_snmp_object glob_snmp_object; | ||
|
||
|
@@ -1202,6 +1254,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) | |
Z_PARAM_LONG(timeout) | ||
Z_PARAM_LONG(retries) | ||
ZEND_PARSE_PARAMETERS_END(); | ||
|
||
timeout_argument_offset = 10; | ||
} else { | ||
/* SNMP_CMD_GET | ||
* SNMP_CMD_GETNEXT | ||
|
@@ -1220,6 +1274,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) | |
Z_PARAM_LONG(timeout) | ||
Z_PARAM_LONG(retries) | ||
ZEND_PARSE_PARAMETERS_END(); | ||
|
||
timeout_argument_offset = 9; | ||
} | ||
} else { | ||
if (st & SNMP_CMD_SET) { | ||
|
@@ -1233,6 +1289,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) | |
Z_PARAM_LONG(timeout) | ||
Z_PARAM_LONG(retries) | ||
ZEND_PARSE_PARAMETERS_END(); | ||
|
||
timeout_argument_offset = 6; | ||
} else { | ||
/* SNMP_CMD_GET | ||
* SNMP_CMD_GETNEXT | ||
|
@@ -1246,6 +1304,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) | |
Z_PARAM_LONG(timeout) | ||
Z_PARAM_LONG(retries) | ||
ZEND_PARSE_PARAMETERS_END(); | ||
|
||
timeout_argument_offset = 4; | ||
} | ||
} | ||
} else { | ||
|
@@ -1289,14 +1349,14 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) | |
} | ||
|
||
if (session_less_mode) { | ||
if (!netsnmp_session_init(&session, version, a1, a2, timeout, retries)) { | ||
if (!snmp_session_init(&session, version, a1, a2, timeout, retries, timeout_argument_offset)) { | ||
php_free_objid_query(&objid_query, oid_ht, value_ht, st); | ||
netsnmp_session_free(&session); | ||
snmp_session_free(&session); | ||
RETURN_FALSE; | ||
} | ||
if (version == SNMP_VERSION_3 && !netsnmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL)) { | ||
if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL)) { | ||
php_free_objid_query(&objid_query, oid_ht, value_ht, st); | ||
netsnmp_session_free(&session); | ||
snmp_session_free(&session); | ||
/* Warning message sent already, just bail out */ | ||
RETURN_FALSE; | ||
} | ||
|
@@ -1335,7 +1395,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) | |
php_free_objid_query(&objid_query, oid_ht, value_ht, st); | ||
|
||
if (session_less_mode) { | ||
netsnmp_session_free(&session); | ||
snmp_session_free(&session); | ||
} else { | ||
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM, glob_snmp_object.enum_print); | ||
netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, glob_snmp_object.quick_print); | ||
|
@@ -1590,10 +1650,10 @@ PHP_METHOD(SNMP, __construct) | |
|
||
/* handle re-open of snmp session */ | ||
if (snmp_object->session) { | ||
netsnmp_session_free(&(snmp_object->session)); | ||
snmp_session_free(&(snmp_object->session)); | ||
} | ||
|
||
if (!netsnmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries)) { | ||
if (!snmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries, 4)) { | ||
return; | ||
} | ||
snmp_object->max_oids = 0; | ||
|
@@ -1618,7 +1678,7 @@ PHP_METHOD(SNMP, close) | |
RETURN_THROWS(); | ||
} | ||
|
||
netsnmp_session_free(&(snmp_object->session)); | ||
snmp_session_free(&(snmp_object->session)); | ||
|
||
RETURN_TRUE; | ||
} | ||
|
@@ -1669,7 +1729,7 @@ PHP_METHOD(SNMP, setSecurity) | |
RETURN_THROWS(); | ||
} | ||
|
||
if (!netsnmp_session_set_security(snmp_object->session, a1, a2, a3, a4, a5, a6, a7)) { | ||
if (!snmp_session_set_security(snmp_object->session, a1, a2, a3, a4, a5, a6, a7)) { | ||
/* Warning message sent already, just bail out */ | ||
RETURN_FALSE; | ||
} | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the helper function for this to have a consistant error message.