@@ -830,30 +830,69 @@ static bool php_snmp_parse_oid(
830830/* }}} */
831831
832832/* {{{ netsnmp_session_init
833- allocates memory for session and session->peername, caller should free it manually using netsnmp_session_free () and efree()
833+ allocates memory for session and session->peername, caller should free it manually using session_free () and efree()
834834*/
835- static bool netsnmp_session_init (php_snmp_session * * session_p , int version , zend_string * hostname , zend_string * community , int timeout , int retries )
835+ static bool netsnmp_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 )
836836{
837837 php_snmp_session * session ;
838838 char * pptr , * host_ptr ;
839839 bool force_ipv6 = false;
840840 int n ;
841841 struct sockaddr * * psal ;
842842 struct sockaddr * * res ;
843+
844+ * session_p = 0 ;
845+
846+ ZEND_ASSERT (hostname != NULL );
847+ ZEND_ASSERT (community != NULL );
848+
849+ if (zend_str_has_nul_byte (hostname )) {
850+ zend_argument_value_error (2 , "must not contain any null bytes" );
851+ return false;
852+ }
853+
854+ if (ZSTR_LEN (hostname ) >= MAX_NAME_LEN ) {
855+ zend_argument_value_error (2 , "length must be lower than %d" , MAX_NAME_LEN );
856+ return false;
857+ }
858+
859+ if (zend_str_has_nul_byte (community )) {
860+ zend_argument_value_error (3 , "must not contain any null bytes" );
861+ return false;
862+ }
863+
864+ if (ZSTR_LEN (community ) == 0 ) {
865+ zend_argument_value_error (3 , "cannot be empty" );
866+ return false;
867+ }
868+
869+ if (timeout_argument_offset != -1 ) {
870+ if (timeout < -1 || timeout > LONG_MAX ) {
871+ zend_argument_value_error (timeout_argument_offset , "must be between -1 and %ld" , LONG_MAX );
872+ return false;
873+ }
874+
875+ if (retries < -1 || retries > INT_MAX ) {
876+ zend_argument_value_error (timeout_argument_offset , "must be between -1 and %d" , INT_MAX );
877+ return false;
878+ }
879+ }
880+
843881 // TODO: Do not strip and re-add the port in peername?
844- unsigned remote_port = SNMP_PORT ;
882+ unsigned short remote_port = SNMP_PORT ;
883+ int tmp_port ;
845884
846885 * session_p = (php_snmp_session * )emalloc (sizeof (php_snmp_session ));
847886 session = * session_p ;
848887 memset (session , 0 , sizeof (php_snmp_session ));
849888
850889 snmp_sess_init (session );
851890
852- session -> version = version ;
891+ session -> version = ( long ) version ;
853892
854893 session -> peername = emalloc (MAX_NAME_LEN );
855894 /* we copy original hostname for further processing */
856- strlcpy (session -> peername , ZSTR_VAL (hostname ), MAX_NAME_LEN );
895+ memcpy (session -> peername , ZSTR_VAL (hostname ), ZSTR_LEN ( hostname ) + 1 );
857896 host_ptr = session -> peername ;
858897
859898 /* 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
862901 host_ptr ++ ;
863902 if ((pptr = strchr (host_ptr , ']' ))) {
864903 if (pptr [1 ] == ':' ) {
865- remote_port = atoi (pptr + 2 );
904+ char * pport = pptr + 2 ;
905+ tmp_port = atoi (pport );
906+ if (tmp_port < 0 || tmp_port > USHRT_MAX ) {
907+ zend_value_error ("remote port must be between 0 and %u" , USHRT_MAX );
908+ return false;
909+ }
910+ remote_port = (unsigned short )tmp_port ;
866911 }
867912 * pptr = '\0' ;
868913 } else {
@@ -871,7 +916,13 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend
871916 }
872917 } else { /* IPv4 address */
873918 if ((pptr = strchr (host_ptr , ':' ))) {
874- remote_port = atoi (pptr + 1 );
919+ char * pport = pptr + 1 ;
920+ tmp_port = atoi (pport );
921+ if (tmp_port < 0 || tmp_port > USHRT_MAX ) {
922+ zend_value_error ("remote port must be between 0 and %u" , USHRT_MAX );
923+ return false;
924+ }
925+ remote_port = (unsigned short )tmp_port ;
875926 * pptr = '\0' ;
876927 }
877928 }
@@ -920,7 +971,7 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend
920971 if (remote_port != SNMP_PORT ) {
921972 size_t peername_length = strlen (session -> peername );
922973 pptr = session -> peername + peername_length ;
923- snprintf (pptr , MAX_NAME_LEN - peername_length , ":%d " , remote_port );
974+ snprintf (pptr , MAX_NAME_LEN - peername_length , ":%u " , remote_port );
924975 }
925976
926977 php_network_freeaddresses (psal );
@@ -935,14 +986,14 @@ static bool netsnmp_session_init(php_snmp_session **session_p, int version, zend
935986 session -> community_len = ZSTR_LEN (community );
936987 }
937988
938- session -> retries = retries ;
939- session -> timeout = timeout ;
989+ session -> retries = ( int ) retries ;
990+ session -> timeout = ( long ) timeout ;
940991 return true;
941992}
942993/* }}} */
943994
944995/* {{{ Set the security level in the snmpv3 session */
945- static bool netsnmp_session_set_sec_level (struct snmp_session * s , zend_string * level )
996+ static bool snmp_session_set_sec_level (struct snmp_session * s , zend_string * level )
946997{
947998 if (zend_string_equals_literal_ci (level , "noAuthNoPriv" ) || zend_string_equals_literal_ci (level , "nanp" )) {
948999 s -> securityLevel = SNMP_SEC_LEVEL_NOAUTH ;
@@ -959,7 +1010,7 @@ static bool netsnmp_session_set_sec_level(struct snmp_session *s, zend_string *l
9591010/* }}} */
9601011
9611012/* {{{ Set the authentication protocol in the snmpv3 session */
962- static bool netsnmp_session_set_auth_protocol (struct snmp_session * s , zend_string * prot )
1013+ static bool snmp_session_set_auth_protocol (struct snmp_session * s , zend_string * prot )
9631014{
9641015#ifndef DISABLE_MD5
9651016 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
10111062/* }}} */
10121063
10131064/* {{{ Set the security protocol in the snmpv3 session */
1014- static bool netsnmp_session_set_sec_protocol (struct snmp_session * s , zend_string * prot )
1065+ static bool snmp_session_set_sec_protocol (struct snmp_session * s , zend_string * prot )
10151066{
10161067#ifndef NETSNMP_DISABLE_DES
10171068 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
10481099/* }}} */
10491100
10501101/* {{{ Make key from pass phrase in the snmpv3 session */
1051- static bool netsnmp_session_gen_auth_key (struct snmp_session * s , zend_string * pass )
1102+ static bool snmp_session_gen_auth_key (struct snmp_session * s , zend_string * pass )
10521103{
10531104 int snmp_errno ;
10541105 s -> securityAuthKeyLen = USM_AUTH_KU_LEN ;
@@ -1063,7 +1114,7 @@ static bool netsnmp_session_gen_auth_key(struct snmp_session *s, zend_string *pa
10631114/* }}} */
10641115
10651116/* {{{ Make key from pass phrase in the snmpv3 session */
1066- static bool netsnmp_session_gen_sec_key (struct snmp_session * s , zend_string * pass )
1117+ static bool snmp_session_gen_sec_key (struct snmp_session * s , zend_string * pass )
10671118{
10681119 int snmp_errno ;
10691120
@@ -1079,7 +1130,7 @@ static bool netsnmp_session_gen_sec_key(struct snmp_session *s, zend_string *pas
10791130/* }}} */
10801131
10811132/* {{{ Set context Engine Id in the snmpv3 session */
1082- static bool netsnmp_session_set_contextEngineID (struct snmp_session * s , zend_string * contextEngineID )
1133+ static bool snmp_session_set_contextEngineID (struct snmp_session * s , zend_string * contextEngineID )
10831134{
10841135 size_t ebuf_len = 32 , eout_len = 0 ;
10851136 uint8_t * ebuf = (uint8_t * ) emalloc (ebuf_len );
@@ -1102,40 +1153,40 @@ static bool netsnmp_session_set_contextEngineID(struct snmp_session *s, zend_str
11021153/* }}} */
11031154
11041155/* {{{ Set all snmpv3-related security options */
1105- static bool netsnmp_session_set_security (struct snmp_session * session , zend_string * sec_level ,
1156+ static bool snmp_session_set_security (struct snmp_session * session , zend_string * sec_level ,
11061157 zend_string * auth_protocol , zend_string * auth_passphrase , zend_string * priv_protocol ,
11071158 zend_string * priv_passphrase , zend_string * contextName , zend_string * contextEngineID )
11081159{
11091160
11101161 /* Setting the security level. */
1111- if (!netsnmp_session_set_sec_level (session , sec_level )) {
1162+ if (!snmp_session_set_sec_level (session , sec_level )) {
11121163 /* ValueError already generated, just bail out */
11131164 return false;
11141165 }
11151166
11161167 if (session -> securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || session -> securityLevel == SNMP_SEC_LEVEL_AUTHPRIV ) {
11171168
11181169 /* Setting the authentication protocol. */
1119- if (!netsnmp_session_set_auth_protocol (session , auth_protocol )) {
1170+ if (!snmp_session_set_auth_protocol (session , auth_protocol )) {
11201171 /* ValueError already generated, just bail out */
11211172 return false;
11221173 }
11231174
11241175 /* Setting the authentication passphrase. */
1125- if (!netsnmp_session_gen_auth_key (session , auth_passphrase )) {
1176+ if (!snmp_session_gen_auth_key (session , auth_passphrase )) {
11261177 /* Warning message sent already, just bail out */
11271178 return false;
11281179 }
11291180
11301181 if (session -> securityLevel == SNMP_SEC_LEVEL_AUTHPRIV ) {
11311182 /* Setting the security protocol. */
1132- if (!netsnmp_session_set_sec_protocol (session , priv_protocol )) {
1183+ if (!snmp_session_set_sec_protocol (session , priv_protocol )) {
11331184 /* ValueError already generated, just bail out */
11341185 return false;
11351186 }
11361187
11371188 /* Setting the security protocol passphrase. */
1138- if (!netsnmp_session_gen_sec_key (session , priv_passphrase )) {
1189+ if (!snmp_session_gen_sec_key (session , priv_passphrase )) {
11391190 /* Warning message sent already, just bail out */
11401191 return false;
11411192 }
@@ -1149,7 +1200,7 @@ static bool netsnmp_session_set_security(struct snmp_session *session, zend_stri
11491200 }
11501201
11511202 /* Setting contextEngineIS if specified */
1152- if (contextEngineID && ZSTR_LEN (contextEngineID ) && !netsnmp_session_set_contextEngineID (session , contextEngineID )) {
1203+ if (contextEngineID && ZSTR_LEN (contextEngineID ) && !snmp_session_set_contextEngineID (session , contextEngineID )) {
11531204 /* Warning message sent already, just bail out */
11541205 return false;
11551206 }
@@ -1176,6 +1227,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
11761227 struct objid_query objid_query ;
11771228 php_snmp_session * session ;
11781229 int session_less_mode = (getThis () == NULL );
1230+ int timeout_argument_offset = -1 ;
11791231 php_snmp_object * snmp_object ;
11801232 php_snmp_object glob_snmp_object ;
11811233
@@ -1202,6 +1254,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12021254 Z_PARAM_LONG (timeout )
12031255 Z_PARAM_LONG (retries )
12041256 ZEND_PARSE_PARAMETERS_END ();
1257+
1258+ timeout_argument_offset = 10 ;
12051259 } else {
12061260 /* SNMP_CMD_GET
12071261 * SNMP_CMD_GETNEXT
@@ -1220,6 +1274,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12201274 Z_PARAM_LONG (timeout )
12211275 Z_PARAM_LONG (retries )
12221276 ZEND_PARSE_PARAMETERS_END ();
1277+
1278+ timeout_argument_offset = 9 ;
12231279 }
12241280 } else {
12251281 if (st & SNMP_CMD_SET ) {
@@ -1233,6 +1289,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12331289 Z_PARAM_LONG (timeout )
12341290 Z_PARAM_LONG (retries )
12351291 ZEND_PARSE_PARAMETERS_END ();
1292+
1293+ timeout_argument_offset = 6 ;
12361294 } else {
12371295 /* SNMP_CMD_GET
12381296 * SNMP_CMD_GETNEXT
@@ -1246,6 +1304,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12461304 Z_PARAM_LONG (timeout )
12471305 Z_PARAM_LONG (retries )
12481306 ZEND_PARSE_PARAMETERS_END ();
1307+
1308+ timeout_argument_offset = 4 ;
12491309 }
12501310 }
12511311 } else {
@@ -1289,12 +1349,12 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12891349 }
12901350
12911351 if (session_less_mode ) {
1292- if (!netsnmp_session_init (& session , version , a1 , a2 , timeout , retries )) {
1352+ if (!netsnmp_session_init (& session , version , a1 , a2 , timeout , retries , timeout_argument_offset )) {
12931353 php_free_objid_query (& objid_query , oid_ht , value_ht , st );
12941354 netsnmp_session_free (& session );
12951355 RETURN_FALSE ;
12961356 }
1297- if (version == SNMP_VERSION_3 && !netsnmp_session_set_security (session , a3 , a4 , a5 , a6 , a7 , NULL , NULL )) {
1357+ if (version == SNMP_VERSION_3 && !snmp_session_set_security (session , a3 , a4 , a5 , a6 , a7 , NULL , NULL )) {
12981358 php_free_objid_query (& objid_query , oid_ht , value_ht , st );
12991359 netsnmp_session_free (& session );
13001360 /* Warning message sent already, just bail out */
@@ -1593,7 +1653,7 @@ PHP_METHOD(SNMP, __construct)
15931653 netsnmp_session_free (& (snmp_object -> session ));
15941654 }
15951655
1596- if (!netsnmp_session_init (& (snmp_object -> session ), version , a1 , a2 , timeout , retries )) {
1656+ if (!netsnmp_session_init (& (snmp_object -> session ), version , a1 , a2 , timeout , retries , 4 )) {
15971657 return ;
15981658 }
15991659 snmp_object -> max_oids = 0 ;
@@ -1669,7 +1729,7 @@ PHP_METHOD(SNMP, setSecurity)
16691729 RETURN_THROWS ();
16701730 }
16711731
1672- if (!netsnmp_session_set_security (snmp_object -> session , a1 , a2 , a3 , a4 , a5 , a6 , a7 )) {
1732+ if (!snmp_session_set_security (snmp_object -> session , a1 , a2 , a3 , a4 , a5 , a6 , a7 )) {
16731733 /* Warning message sent already, just bail out */
16741734 RETURN_FALSE ;
16751735 }
0 commit comments