Source for file rfc3412.php

Documentation is available at rfc3412.php

  1. <?php
  2. /**
  3. * phpsnmp - a PHP SNMP library
  4. *
  5. * Copyright (C) 2004 David Eder <david@eder,us>
  6. *
  7. * Based on snmp - a Python SNMP library
  8. * Copyright (C) 2003 Unicity Pty Ltd <libsnmp@unicity.com.au>
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation; either
  13. * version 2.1 of the License, or (at your option) any later version.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. *
  24. * @author David Eder <david@eder.us>
  25. * @copyright 2004 David Eder
  26. * @package phpSNMP
  27. * @subpackage rfc1155
  28. * @version .7
  29. */
  30.  
  31. /**
  32. */
  33.  
  34. require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'rfc1155.php');
  35. require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'rfc1905.php');
  36. require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'rfc3411.php');
  37.  
  38. define('SNMP_NOAUTH_NOPRIV', 0);
  39. define('SNMP_AUTH_NOPRIV', 1);
  40. define('SNMP_AUTH_PRIV', 3);
  41. define('SNMP_REPORTABLE', 4);
  42.  
  43. define('SNMP_SECURITY_ANY', 0);
  44. define('SNMP_SECURITY_V1', 1);
  45. define('SNMP_SECURITY_V2C', 2);
  46. define('SNMP_SECURITY_USM', 3);
  47.  
  48. /**
  49. * SNMP v3 Message
  50. *
  51. * @package phpSNMP
  52. * @subpackage rfc3412
  53. */
  54. class rfc3412_Message extends rfc1155_Sequence
  55. {
  56. /**
  57. * Constructor
  58. *
  59. * @param integer $version
  60. * @param rfc3412_Header $header
  61. * @param rfc3414_USM $security
  62. * @param rfc3412_ScopedPDU $scopedpdu
  63. */
  64. function rfc3412_Message($version=SNMP_VERSION_3, $header=NULL, $usm_security=NULL, $scopedpdu=NULL)
  65. {
  66. parent::rfc1155_Sequence();
  67.  
  68. if(is_null($header)) $header = new rfc3412_Header();
  69. if(is_null($usm_security)) $usm_security = new rfc3414_USM();
  70. if(is_null($scopedpdu)) $scopedpdu = new rfc3412_ScopedPDU();
  71.  
  72. $this->value = array(new rfc1155_Integer($version), $header, $usm_security, $scopedpdu);
  73. }
  74.  
  75. /**
  76. * Get/Set Version
  77. *
  78. * @param integer $value
  79. * @return integer
  80. */
  81. function version($value=NULL)
  82. {
  83. if(!is_null($value)) $this->value[0] = new rfc1155_Integer($value);
  84. return $this->value[0]->value;
  85. }
  86.  
  87. /**
  88. * Get/Set Header
  89. *
  90. * @param rfc3412_Header $value
  91. * @return rfc3412_Header
  92. */
  93. function header($value=NULL)
  94. {
  95. if(!is_null($value)) $this->value[1] = $value;
  96. return $this->value[1];
  97. }
  98.  
  99. /**
  100. * Get/Set USM Security
  101. *
  102. * @param rfc3414_USM $value
  103. * @return rfc3414_USM
  104. */
  105. function usm_security($value=NULL)
  106. {
  107. if(!is_null($value)) $this->value[2] = $value;
  108. return $this->value[2];
  109. }
  110.  
  111. /**
  112. * Get/Set Scoped PDU
  113. *
  114. * @param rfc3412_ScopedPDU $value
  115. * @return rfc3412_ScopedPDU
  116. */
  117. function scopedPDU($value=NULL)
  118. {
  119. if(!is_null($value)) $this->value[3] = $value;
  120. return $this->value[3];
  121. }
  122.  
  123. /**
  124. * Get/Set PDU
  125. *
  126. * @param rfc1905_PDU $value
  127. * @return rfc1905_PDU
  128. */
  129. function pdu($value=NULL)
  130. {
  131. if(!is_null($value))
  132. $this->value[3]->pdu($value);
  133. return $this->value[3]->pdu();
  134. }
  135.  
  136. /**
  137. * Decode Stream
  138. *
  139. * decode() an octet stream into a sequence of Asn1Objects
  140. *
  141. * @param string $stream
  142. * @return rfc3412_Message
  143. */
  144. function decode($stream)
  145. {
  146. $usm = $this->usm_security();
  147.  
  148. $this->value = parent::decode($stream);
  149.  
  150. if(count($this->value) != 1)
  151. trigger_error('Malformed Message: More than one object decoded.', E_USER_WARNING);
  152. $this->value = $this->value[0]->value;
  153. if(count($this->value) != 4)
  154. trigger_error('Malformed Message: Incorrect sequence length ' . count($this->value), E_USER_WARNING);
  155.  
  156. $header = $this->header();
  157.  
  158. $header = $this->header(new rfc3412_Header($header->value[0]->value, $header->value[1]->value,
  159. ord($header->value[2]->value), $header->value[3]->value));
  160.  
  161. $usm->decode($this->value[2]->value);
  162. $this->usm_security($usm);
  163.  
  164. if($header->auth_flag())
  165. {
  166. // authenticate
  167. $usm = $this->usm_security();
  168. $auth = $usm->auth();
  169. $usm->auth(str_repeat(chr(0), USM_AUTH_KEY_LEN));
  170. $usms = new rfc1155_OctetString($usm->encode());
  171. $contents = $this->value[0]->encode() . $header->encode() . $usms->encode() . $this->value[3]->encode();
  172. $packet = $this->encodeIdentifier() . $this->encodeLength(strlen($contents)) . $contents;
  173. $hmac = substr(HMAC($packet, $usm->generate_key('auth'), $usm->hash_function), 0, USM_AUTH_KEY_LEN);
  174. if($hmac != $auth)
  175. {
  176. trigger_error('Message is not authentic!', E_USER_WARNING);
  177. $this->value[3] = new rfc3412_ScopedPDU();
  178. return $this;
  179. }
  180.  
  181. if($header->priv_flag())
  182. {
  183. $clear = $usm->decrypt($this->value[3]->value);
  184. $spdu = new rfc3412_ScopedPDU();
  185. list($len, $c) = $spdu->decodeLength(substr($clear, 1));
  186. $len += strlen($clear) - strlen($c);
  187. $clear = substr($clear, 0, $len);
  188. $this->value[3] = $spdu->decode($clear);
  189. }
  190. else
  191. $this->value[3] = new rfc3412_ScopedPDU($this->value[3]->value[0]->value, $this->value[3]->value[1]->value, $this->value[3]->value[2]);
  192. }
  193. else
  194. $this->value[3] = new rfc3412_ScopedPDU($this->value[3]->value[0]->value, $this->value[3]->value[1]->value, $this->value[3]->value[2]);
  195.  
  196. return $this;
  197. }
  198.  
  199. /**
  200. * Encode Contents
  201. *
  202. * @return string
  203. */
  204. function encodeContents()
  205. {
  206. $version = $this->value[0];
  207. $header = $this->header();
  208. $usm = $this->usm_security();
  209. $spdu = $this->scopedPDU();
  210.  
  211. if($usm->engineID() == '')
  212. {
  213. $header->flags(SNMP_REPORTABLE);
  214. $usm = new rfc3414_USM();
  215. $pdu = $spdu->pdu();
  216. $pdu->varBindList(array());
  217. $spdu = new rfc3412_ScopedPDU('', '', $pdu);
  218. }
  219.  
  220. $spdu = $spdu->encode();
  221.  
  222. if($header->auth_flag())
  223. {
  224. if($header->priv_flag())
  225. {
  226. $spdu = new rfc1155_OctetString($usm->encrypt($spdu));
  227. $spdu = $spdu->encode();
  228. }
  229.  
  230. $usm->auth(str_repeat(chr(0), USM_AUTH_KEY_LEN));
  231. $usms = new rfc1155_OctetString($usm->encode());
  232. $contents = $version->encode() . $header->encode() . $usms->encode() . $spdu;
  233. $packet = $this->encodeIdentifier() . $this->encodeLength(strlen($contents)) . $contents;
  234. $hmac = HMAC($packet, $usm->generate_key('auth'), $usm->hash_function);
  235. $usm->auth($hmac);
  236. }
  237.  
  238. $usms = new rfc1155_OctetString($usm->encode());
  239. return $version->encode() . $header->encode() . $usms->encode() . $spdu;
  240. }
  241. }
  242.  
  243. /**
  244. * SNMP v3 Message Header
  245. *
  246. * @package phpSNMP
  247. * @subpackage rfc3412
  248. */
  249. class rfc3412_Header extends rfc1155_Sequence
  250. {
  251. /**
  252. * Constructor
  253. *
  254. * @param integer $msgid
  255. * @param string $flags noAuthNoPriv(0), authNoPriv(1), authPriv(3)
  256. * @param string $security any(0), v1(1), v2c(2), usm(3)
  257. */
  258. function rfc3412_Header($msgid=0, $max_size=65507, $flags=SNMP_NOAUTH_NOPRIV, $security=SNMP_SECURITY_USM)
  259. {
  260. parent::rfc1155_Sequence();
  261. $this->value = array(new rfc1155_Integer($msgid), new rfc1155_Integer($max_size),
  262. new rfc1155_OctetString(chr($flags)), new rfc1155_Integer($security));
  263. }
  264.  
  265. /**
  266. * to String
  267. *
  268. * @return string
  269. */
  270. function toString()
  271. {
  272. $flags = array();
  273. $f = ord($this->value[2]->value);
  274. if($f & 1) $flags[] = 'AUTH';
  275. if($f & 2) $flags[] = 'PRIV';
  276. if($f & 4) $flags[] = 'REPORTABLE';
  277. $flags = join('|', $flags) . "($f)";
  278.  
  279. switch($this->value[3]->value)
  280. {
  281. case SNMP_SECURITY_ANY: $security = 'ANY'; break;
  282. case SNMP_SECURITY_V1: $security = 'V1'; break;
  283. case SNMP_SECURITY_V2C: $security = 'V2C'; break;
  284. case SNMP_SECURITY_USM: $security = 'USM'; break;
  285. default: $this->value[3]->value;
  286. }
  287.  
  288. return get_class($this) . "(MsgID:{$this->value[0]->value},max_size:{$this->value[1]->value},flags:$flags,security:$security)";
  289. }
  290.  
  291. /**
  292. * Get/Set Message ID
  293. *
  294. * @param integer $value
  295. * @return integer
  296. */
  297. function msgid($value=NULL)
  298. {
  299. if(!is_null($value)) $this->value[0]->value = $value;
  300. return $this->value[0]->value;
  301. }
  302.  
  303. /**
  304. * Get/Set Max Message Size
  305. *
  306. * @param integer $value
  307. * @return integer
  308. */
  309. function maxsize($value=NULL)
  310. {
  311. if(!is_null($value)) $this->value[1]->value = $value;
  312. return $this->value[1]->value;
  313. }
  314.  
  315. /**
  316. * Get/Set Message Flags
  317. *
  318. * @param integer $value
  319. * @return integer
  320. */
  321. function flags($value=NULL)
  322. {
  323. if(!is_null($value)) $this->value[2]->value = chr($value);
  324. return ord($this->value[2]->value);
  325. }
  326.  
  327. /**
  328. * Get/Set Auth Flag
  329. *
  330. * @param boolean $value
  331. * @return boolean
  332. */
  333. function auth_flag($value=NULL)
  334. {
  335. if(!is_null($value))
  336. {
  337. if($value)
  338. $this->value[2]->value |= chr(1); // set SNMP_AUTH;
  339. else
  340. $this->value[2]->value &= chr(254); // unset SNMP_AUTH
  341. }
  342. return (($this->value[2]->value & chr(1)) == chr(1)) ? true : false;
  343. }
  344.  
  345. /**
  346. * Get/Set Priv Flag
  347. *
  348. * @param boolean $value
  349. * @return boolean
  350. */
  351. function priv_flag($value=NULL)
  352. {
  353. if(!is_null($value))
  354. {
  355. if($value)
  356. $this->value[2]->value |= chr(3); // set SNMP_AUTH_PRIV;
  357. else
  358. $this->value[2]->value &= chr(253); // unset PRIV
  359. }
  360. return (($this->value[2]->value & chr(2)) == chr(2)) ? true : false;
  361. }
  362.  
  363. /**
  364. * Get/Set Reportable Flag
  365. *
  366. * @param boolean $value
  367. * @return boolean
  368. */
  369. function reportable_flag($value=NULL)
  370. {
  371. if(!is_null($value))
  372. {
  373. if($value)
  374. $this->value[2]->value |= chr(4); // set SNMP_REPORTABLE;
  375. else
  376. $this->value[2]->value &= chr(251); // unset SNMP_REPORTABLE
  377. }
  378. return ($this->value[2]->value & chr(4) == chr(4)) ? true : false;
  379. }
  380.  
  381. /**
  382. * Get/Set Security Mode
  383. *
  384. * @param integer $value SNMP_SECURITY_ANY, SNMP_SECURITY_V1, SNMP_SECURITY_V2C, or SNMP_SECURITY_USM
  385. * @return integer
  386. */
  387. function security($value=NULL)
  388. {
  389. if(!is_null($value)) $this->value[3]->value = $value;
  390. return $this->value[3]->value;
  391. }
  392.  
  393. /**
  394. * Decode Stream
  395. *
  396. * decode() an octet stream into a sequence of Asn1Objects
  397. *
  398. * @param string $stream
  399. * @return rfc3412_Header
  400. */
  401. function decode($stream)
  402. {
  403. parent::decode($stream);
  404. if(count($this->value) != 1)
  405. trigger_error('Malformed Message: More than one object decoded.', E_USER_WARNING);
  406. if(count($this->value[0]->value) != 4)
  407. trigger_error('Malformed Message: Incorrect sequence length ' . count($this->value[0]->value), E_USER_WARNING);
  408. return $this;
  409. }
  410. }
  411.  
  412. /**
  413. * SNMP v3 Scoped PDU
  414. *
  415. * @package phpSNMP
  416. * @subpackage rfc3412
  417. */
  418. class rfc3412_ScopedPDU extends rfc1155_Sequence
  419. {
  420. /**
  421. * Constructor
  422. *
  423. * @param string $engineid
  424. * @param string $name
  425. * @param rfc1905_PDU $pdu
  426. */
  427. function rfc3412_ScopedPDU($engineid='', $name='', $pdu=NULL)
  428. {
  429. parent::rfc1155_Sequence();
  430. if(is_null($pdu)) $pdu = new rfc1905_PDU();
  431. $this->value = array(new rfc3411_EngineID($engineid), new rfc1155_OctetString($name), $pdu);
  432. }
  433.  
  434. /**
  435. * Get/Set Context Engine ID
  436. *
  437. * @param string $value
  438. * @return string
  439. */
  440. function engineID($value=NULL)
  441. {
  442. if(!is_null($value)) $this->value[0]->value = $value;
  443. return $this->value[0]->value;
  444. }
  445.  
  446. /**
  447. * Get/Set Context Name
  448. *
  449. * @param string $value
  450. * @return string
  451. */
  452. function name($value=NULL)
  453. {
  454. if(!is_null($value)) $this->value[1]->value = $value;
  455. return $this->value[1]->value;
  456. }
  457.  
  458. /**
  459. * Get/Set PDU
  460. *
  461. * @param rfc1905_PDU $value
  462. * @return rfc1905_PDU
  463. */
  464. function pdu($value=NULL)
  465. {
  466. if(!is_null($value)) $this->value[2] = $value;
  467. return $this->value[2];
  468. }
  469.  
  470. /**
  471. * To String
  472. *
  473. * @return string
  474. */
  475. function toString()
  476. {
  477. $eid = $this->value[0]->toString();
  478. $name = $this->value[1]->toString();
  479. $pdu = $this->pdu();
  480. $pdu = $pdu->toString();
  481. return get_class($this) . "(engineID:$eid,Name:$name,pdu:$pdu)";
  482. }
  483.  
  484. /**
  485. * Decode Stream
  486. *
  487. * decode() an octet stream into a sequence of Asn1Objects
  488. *
  489. * @param string $stream
  490. * @return rfc3412_ScopedPDU
  491. */
  492. function decode($stream)
  493. {
  494. $this->value = parent::decode($stream);
  495. if(count($this->value) != 1)
  496. trigger_error('Malformed Message: More than one object decoded.', E_USER_WARNING);
  497. $this->value = $this->value[0]->value;
  498. if(count($this->value) != 3)
  499. trigger_error('Malformed Message: Incorrect sequence length ' . count($this->value), E_USER_WARNING);
  500.  
  501. $this->value[0] = new rfc3411_EngineID($this->value[0]->value);
  502.  
  503. return $this;
  504. }
  505. }
  506. ?>

Documentation generated on Mon, 14 Nov 2005 17:55:41 -0700 by phpDocumentor 1.3.0RC3