1. /*
  2. * @(#)file SnmpAcl.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 4.32
  5. * @(#)date 04/09/15
  6. *
  7. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  8. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  9. *
  10. */
  11. package com.sun.jmx.snmp.IPAcl;
  12. // java import
  13. //
  14. import java.io.Serializable;
  15. import java.io.File;
  16. import java.io.FileInputStream;
  17. import java.io.FileNotFoundException;
  18. import java.net.InetAddress;
  19. import java.net.UnknownHostException;
  20. import java.util.Hashtable;
  21. import java.util.Vector;
  22. import java.util.Enumeration;
  23. import java.util.HashSet;
  24. import java.security.acl.AclEntry;
  25. import java.security.acl.NotOwnerException;
  26. // SNMP Runtime import
  27. //
  28. import com.sun.jmx.snmp.InetAddressAcl;
  29. import com.sun.jmx.trace.Trace;
  30. /**
  31. * Defines an implementation of the {@link com.sun.jmx.snmp.InetAddressAcl InetAddressAcl} interface.
  32. * <p>
  33. * In this implementation the ACL information is stored on a flat file and
  34. * its default location is "$JRE/lib/snmp.acl" - See
  35. * {@link #getDefaultAclFileName()}
  36. * <p>
  37. * <OL>
  38. *
  39. * <p><b>This API is a Sun Microsystems internal API and is subject
  40. * to change without notice.</b></p>
  41. * @version 4.32 12/19/03
  42. * @author Sun Microsystems, Inc
  43. */
  44. public class SnmpAcl implements InetAddressAcl, Serializable {
  45. static final PermissionImpl READ = new PermissionImpl("READ");
  46. static final PermissionImpl WRITE = new PermissionImpl("WRITE");
  47. /**
  48. * Constructs the Java Dynamic Management(TM) Access Control List
  49. * based on IP addresses. The ACL will take the given owner name.
  50. * The current IP address will be the owner of the ACL.
  51. *
  52. * @param Owner The name of the ACL Owner.
  53. *
  54. * @exception UnknownHostException If the local host is unknown.
  55. * @exception IllegalArgumentException If the ACL file doesn't exist.
  56. */
  57. public SnmpAcl(String Owner)
  58. throws UnknownHostException, IllegalArgumentException {
  59. this(Owner,null);
  60. }
  61. /**
  62. * Constructs the Java Dynamic Management(TM) Access Control List
  63. * based on IP addresses. The ACL will take the given owner name.
  64. * The current IP address will be the owner of the ACL.
  65. *
  66. * @param Owner The name of the ACL Owner.
  67. * @param aclFileName The name of the ACL File.
  68. *
  69. * @exception UnknownHostException If the local host is unknown.
  70. * @exception IllegalArgumentException If the ACL file doesn't exist.
  71. */
  72. public SnmpAcl(String Owner, String aclFileName)
  73. throws UnknownHostException, IllegalArgumentException {
  74. trapDestList= new Hashtable();
  75. informDestList= new Hashtable();
  76. // PrincipalImpl() take the current host as entry
  77. owner = new PrincipalImpl();
  78. try {
  79. acl = new AclImpl(owner,Owner);
  80. AclEntry ownEntry = new AclEntryImpl(owner);
  81. ownEntry.addPermission(READ);
  82. ownEntry.addPermission(WRITE);
  83. acl.addEntry(owner,ownEntry);
  84. } catch (NotOwnerException ex) {
  85. if (isDebugOn()) {
  86. debug("constructor",
  87. "Should never get NotOwnerException as the owner"+
  88. " is built in this constructor");
  89. }
  90. }
  91. if (aclFileName == null) setDefaultFileName();
  92. else setAuthorizedListFile(aclFileName);
  93. readAuthorizedListFile();
  94. }
  95. /**
  96. * Returns an enumeration of the entries in this ACL. Each element in the
  97. * enumeration is of type <CODE>java.security.acl.AclEntry</CODE>.
  98. *
  99. * @return An enumeration of the entries in this ACL.
  100. */
  101. public Enumeration entries() {
  102. return acl.entries();
  103. }
  104. /**
  105. * Returns ann enumeration of community strings. Community strings are returned as String.
  106. * @return The enumeration of community strings.
  107. */
  108. public Enumeration communities() {
  109. HashSet set = new HashSet();
  110. Vector res = new Vector();
  111. for (Enumeration e = acl.entries() ; e.hasMoreElements() ;) {
  112. AclEntryImpl entry = (AclEntryImpl) e.nextElement();
  113. for (Enumeration cs = entry.communities();
  114. cs.hasMoreElements() ;) {
  115. set.add((String) cs.nextElement());
  116. }
  117. }
  118. Object[] objs = set.toArray();
  119. for(int i = 0; i < objs.length; i++)
  120. res.addElement(objs[i]);
  121. return res.elements();
  122. }
  123. /**
  124. * Returns the name of the ACL.
  125. *
  126. * @return The name of the ACL.
  127. */
  128. public String getName() {
  129. return acl.getName();
  130. }
  131. /**
  132. * Returns the read permission instance used.
  133. *
  134. * @return The read permission instance.
  135. */
  136. static public PermissionImpl getREAD() {
  137. return READ;
  138. }
  139. /**
  140. * Returns the write permission instance used.
  141. *
  142. * @return The write permission instance.
  143. */
  144. static public PermissionImpl getWRITE() {
  145. return WRITE;
  146. }
  147. /**
  148. * Get the default name for the ACL file.
  149. * In this implementation this is "$JRE/lib/snmp.acl"
  150. * @return The default name for the ACL file.
  151. **/
  152. public static String getDefaultAclFileName() {
  153. final String fileSeparator =
  154. System.getProperty("file.separator");
  155. final StringBuffer defaultAclName =
  156. new StringBuffer(System.getProperty("java.home")).
  157. append(fileSeparator).append("lib").append(fileSeparator).
  158. append("snmp.acl");
  159. return defaultAclName.toString();
  160. }
  161. /**
  162. * Sets the full path of the file containing the ACL information.
  163. *
  164. * @param filename The full path of the file containing the ACL information.
  165. * @throws IllegalArgumentException If the passed ACL file doesn't exist.
  166. */
  167. public void setAuthorizedListFile(String filename)
  168. throws IllegalArgumentException {
  169. File file = new File(filename);
  170. if (!file.isFile() ) {
  171. if (isDebugOn()) {
  172. debug("setAuthorizedListFile",
  173. "ACL file not found: " + filename);
  174. }
  175. throw new
  176. IllegalArgumentException("The specified file ["+file+"] "+
  177. "doesn't exist or is not a file, "+
  178. "no configuration loaded");
  179. }
  180. if (isTraceOn()) {
  181. trace("setAuthorizedListFile", "Default file set to " + filename);
  182. }
  183. authorizedListFile = filename;
  184. }
  185. /**
  186. * Resets this ACL to the values contained in the configuration file.
  187. *
  188. * @exception NotOwnerException If the principal attempting the reset is not an owner of this ACL.
  189. * @exception UnknownHostException If IP addresses for hosts contained in the ACL file couldn't be found.
  190. */
  191. public void rereadTheFile() throws NotOwnerException, UnknownHostException {
  192. alwaysAuthorized = false;
  193. acl.removeAll(owner);
  194. trapDestList.clear();
  195. informDestList.clear();
  196. AclEntry ownEntry = new AclEntryImpl(owner);
  197. ownEntry.addPermission(READ);
  198. ownEntry.addPermission(WRITE);
  199. acl.addEntry(owner,ownEntry);
  200. readAuthorizedListFile();
  201. }
  202. /**
  203. * Returns the full path of the file used to get ACL information.
  204. *
  205. * @return The full path of the file used to get ACL information.
  206. */
  207. public String getAuthorizedListFile() {
  208. return authorizedListFile;
  209. }
  210. /**
  211. * Checks whether or not the specified host has <CODE>READ</CODE> access.
  212. *
  213. * @param address The host address to check.
  214. *
  215. * @return <CODE>true</CODE> if the host has read permission, <CODE>false</CODE> otherwise.
  216. */
  217. public boolean checkReadPermission(InetAddress address) {
  218. if (alwaysAuthorized) return ( true );
  219. PrincipalImpl p = new PrincipalImpl(address);
  220. return acl.checkPermission(p, READ);
  221. }
  222. /**
  223. * Checks whether or not the specified host and community have <CODE>READ</CODE> access.
  224. *
  225. * @param address The host address to check.
  226. * @param community The community associated with the host.
  227. *
  228. * @return <CODE>true</CODE> if the pair (host, community) has read permission, <CODE>false</CODE> otherwise.
  229. */
  230. public boolean checkReadPermission(InetAddress address, String community) {
  231. if (alwaysAuthorized) return ( true );
  232. PrincipalImpl p = new PrincipalImpl(address);
  233. return acl.checkPermission(p, community, READ);
  234. }
  235. /**
  236. * Checks whether or not a community string is defined.
  237. *
  238. * @param community The community to check.
  239. *
  240. * @return <CODE>true</CODE> if the community is known, <CODE>false</CODE> otherwise.
  241. */
  242. public boolean checkCommunity(String community) {
  243. return acl.checkCommunity(community);
  244. }
  245. /**
  246. * Checks whether or not the specified host has <CODE>WRITE</CODE> access.
  247. *
  248. * @param address The host address to check.
  249. *
  250. * @return <CODE>true</CODE> if the host has write permission, <CODE>false</CODE> otherwise.
  251. */
  252. public boolean checkWritePermission(InetAddress address) {
  253. if (alwaysAuthorized) return ( true );
  254. PrincipalImpl p = new PrincipalImpl(address);
  255. return acl.checkPermission(p, WRITE);
  256. }
  257. /**
  258. * Checks whether or not the specified host and community have <CODE>WRITE</CODE> access.
  259. *
  260. * @param address The host address to check.
  261. * @param community The community associated with the host.
  262. *
  263. * @return <CODE>true</CODE> if the pair (host, community) has write permission, <CODE>false</CODE> otherwise.
  264. */
  265. public boolean checkWritePermission(InetAddress address, String community) {
  266. if (alwaysAuthorized) return ( true );
  267. PrincipalImpl p = new PrincipalImpl(address);
  268. return acl.checkPermission(p, community, WRITE);
  269. }
  270. /**
  271. * Returns an enumeration of trap destinations.
  272. *
  273. * @return An enumeration of the trap destinations (enumeration of <CODE>InetAddress<CODE>).
  274. */
  275. public Enumeration getTrapDestinations() {
  276. return trapDestList.keys();
  277. }
  278. /**
  279. * Returns an enumeration of trap communities for a given host.
  280. *
  281. * @param i The address of the host.
  282. *
  283. * @return An enumeration of trap communities for a given host (enumeration of <CODE>String<CODE>).
  284. */
  285. public Enumeration getTrapCommunities(InetAddress i) {
  286. Vector list = null;
  287. if ((list = (Vector)trapDestList.get(i)) != null ) {
  288. if (isTraceOn()) {
  289. trace("getTrapCommunities", "["+i.toString()+"] is in list");
  290. }
  291. return list.elements();
  292. } else {
  293. list = new Vector();
  294. if (isTraceOn()) {
  295. trace("getTrapCommunities", "["+i.toString()+"] is not in list");
  296. }
  297. return list.elements();
  298. }
  299. }
  300. /**
  301. * Returns an enumeration of inform destinations.
  302. *
  303. * @return An enumeration of the inform destinations (enumeration of <CODE>InetAddress<CODE>).
  304. */
  305. public Enumeration getInformDestinations() {
  306. return informDestList.keys();
  307. }
  308. /**
  309. * Returns an enumeration of inform communities for a given host.
  310. *
  311. * @param i The address of the host.
  312. *
  313. * @return An enumeration of inform communities for a given host (enumeration of <CODE>String<CODE>).
  314. */
  315. public Enumeration getInformCommunities(InetAddress i) {
  316. Vector list = null;
  317. if ((list = (Vector)informDestList.get(i)) != null ) {
  318. if (isTraceOn()) {
  319. trace("getInformCommunities", "["+i.toString()+"] is in list");
  320. }
  321. return list.elements();
  322. } else {
  323. list = new Vector();
  324. if (isTraceOn()) {
  325. trace("getInformCommunities", "["+i.toString()+"] is not in list");
  326. }
  327. return list.elements();
  328. }
  329. }
  330. /**
  331. * Converts the input configuration file into ACL.
  332. */
  333. private void readAuthorizedListFile() {
  334. alwaysAuthorized = false;
  335. if (authorizedListFile == null) {
  336. if (isTraceOn()) {
  337. trace("readAuthorizedListFile", "alwaysAuthorized set to true");
  338. }
  339. alwaysAuthorized = true ;
  340. } else {
  341. // Read the file content
  342. Parser parser = null;
  343. try {
  344. parser= new Parser(new FileInputStream(getAuthorizedListFile()));
  345. } catch (FileNotFoundException e) {
  346. if (isDebugOn()) {
  347. debug("readAuthorizedListFile", "The specified file was not found, authorize everybody");
  348. }
  349. alwaysAuthorized = true ;
  350. return;
  351. }
  352. try {
  353. JDMSecurityDefs n = parser.SecurityDefs();
  354. n.buildAclEntries(owner, acl);
  355. n.buildTrapEntries(trapDestList);
  356. n.buildInformEntries(informDestList);
  357. } catch (ParseException e) {
  358. if (isDebugOn()) {
  359. debug("readAuthorizedListFile", "Parsing exception " + e);
  360. }
  361. throw new IllegalArgumentException(e.getMessage());
  362. } catch (Error err) {
  363. if (isDebugOn()) {
  364. debug("readAuthorizedListFile", "Error exception");
  365. }
  366. throw new IllegalArgumentException(err.getMessage());
  367. }
  368. for(Enumeration e = acl.entries(); e.hasMoreElements();) {
  369. AclEntryImpl aa = (AclEntryImpl) e.nextElement();
  370. if (isTraceOn()) {
  371. trace("readAuthorizedListFile", "===> " + aa.getPrincipal().toString());
  372. }
  373. for (Enumeration eee = aa.permissions();eee.hasMoreElements();) {
  374. java.security.acl.Permission perm = (java.security.acl.Permission)eee.nextElement();
  375. if (isTraceOn()) {
  376. trace("readAuthorizedListFile", "perm = " + perm);
  377. }
  378. }
  379. }
  380. }
  381. }
  382. /**
  383. * Set the default full path for "snmp.acl" input file.
  384. * Do not complain if the file does not exists.
  385. */
  386. private void setDefaultFileName() {
  387. try {
  388. setAuthorizedListFile(getDefaultAclFileName());
  389. } catch (IllegalArgumentException x) {
  390. // OK...
  391. }
  392. }
  393. // TRACES & DEBUG
  394. //---------------
  395. boolean isTraceOn() {
  396. return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_SNMP);
  397. }
  398. void trace(String clz, String func, String info) {
  399. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_SNMP, clz, func, info);
  400. }
  401. void trace(String func, String info) {
  402. trace(dbgTag, func, info);
  403. }
  404. boolean isDebugOn() {
  405. return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_SNMP);
  406. }
  407. void debug(String clz, String func, String info) {
  408. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_SNMP, clz, func, info);
  409. }
  410. void debug(String func, String info) {
  411. debug(dbgTag, func, info);
  412. }
  413. String dbgTag = "SnmpAcl";
  414. // PRIVATE VARIABLES
  415. //------------------
  416. /**
  417. * Represents the Access Control List.
  418. */
  419. private AclImpl acl = null;
  420. /**
  421. * Flag indicating whether the access is always authorized.
  422. * <BR>This is the case if there is no flat file defined.
  423. */
  424. private boolean alwaysAuthorized = false;
  425. /**
  426. * Represents the Access Control List flat file.
  427. */
  428. private String authorizedListFile = null;
  429. /**
  430. * Contains the hosts list for trap destination.
  431. */
  432. private Hashtable trapDestList = null;
  433. /**
  434. * Contains the hosts list for inform destination.
  435. */
  436. private Hashtable informDestList = null;
  437. private PrincipalImpl owner = null;
  438. }