Oracle WebLogic Tuxedo Connector Programmer's Guide
How to Create a Custom AppKey Plug-in
The following sections provide information about how to create custom AppKey generator plug-ins:
How to Create a Custom Plug-In
You cannot customize Oracle Tuxedo AAA tokens.
- Create your custom Java plug-in using the AppKey and UserRec interfaces. You can provide any required initialization parameters or a property file using the param parameter of the init method.
- Compile your plug-in. Example:
javac exampleAppKey.java
- Update your CLASSPATH to include the path to your compiled plug-in. Example:
export CLASSPATH=$CLASSPATH:/home/mywork
- Start your server.
- Configure your WTC Service to use the Custom Plug-in. For more information, see the Custom Plug-in.
Example Custom Plug-in
The exampleAppKey.java file is an example of a custom plug-in. It utilizes a tpusrfile file as the database to store the AppKey. Listing 9-1 exampleAppKey.Java Custom Plug-In
import java.io.*;import java.lang.*;import java.util.*;import java.security.Principal;import weblogic.wtc.jatmi.AppKey;import weblogic.wtc.jatmi.UserRec;import weblogic.wtc.jatmi.DefaultUserRec;import weblogic.wtc.jatmi.TPException;import weblogic.security.acl.internal.AuthenticatedSubject;import weblogic.security.WLSPrincipals;/*** @author Copyright (c) 2002 by BEA Systems, Inc. All Rights Reserved.*//*** @exclude* Sample AppKey plug-in using TPUSRFILE as the database for APPKEY.* It is installed through "Custom" option.* The syntax for option custom plug parameter input contains the full* pathname to the <tpusrfile>** @author BEA Systems, Inc.*/public class exampleAppKey implements AppKey {private String anon_user = null;private String tpusrfile = null;private File myfile;private HashMap userMap;private long l_time;private int dfltAppkey;private boolean allowAnon;private final static int USRIDX = 0;private final static int PWDIDX = 1;private final static int UIDIDX = 2;private final static int GIDIDX = 3;private final static int CLTIDX = 4;private final static byte[] tpsysadm_string = {(byte)'t', (byte)'p', (byte)'s', (byte)'y', (byte)'s',(byte)'a', (byte)'d', (byte)'m' };private final static byte[] tpsysop_string = {(byte)'t', (byte)'p', (byte)'s', (byte)'y', (byte)'s', (byte)'o',(byte)'p' };public void init(String param, boolean anonAllowed, int dfltAppKey)throws TPException {if (param == null) {System.out.println("Error: tpusrAppKey.init@param == null");throw new TPException(TPException.TPESYSTEM,"Invalid input parameter");}// get the tpusrfile nameparseParam(param);myfile = new File(tpusrfile);if (myfile.exists() != true) {System.out.println("Error: exampleAppKey.init@file \"" + param+ "\" does not exist");throw new TPException(TPException.TPESYSTEM,"Failed to find TPUSR file");}if (myfile.isFile() != true) {System.out.println("Error: exampleAppKey.init@the specified name \"" +param + "\" is not a file");throw new TPException(TPException.TPESYSTEM,"Invalid TPUSR file");}if (myfile.canRead() != true) {System.out.println("Error: exampleAppKey.init@file \"" + param +"\" is not readable");throw new TPException(TPException.TPESYSTEM,"Bad TPUSR file permission");}userMap = new HashMap();// create the cacheif (createCache(tpusrfile) == -1) {System.out.println("Error: exampleAppkey.init@fail to create user cache");throw new TPException(TPException.TPESYSTEM,"fail to create user cache");}l_time = myfile.lastModified();anon_user = weblogic.security.WLSPrincipals.getAnonymousUsername();allowAnon = anonAllowed;dfltAppkey = dfltAppKey;System.out.println("exampleAppKey installed!");return;}public void uninit() throws TPException {if (userMap != null) {userMap.clear();}return;}public UserRec getTuxedoUserRecord(AuthenticatedSubject subj) {Object[] obj = subj.getPrincipals().toArray();if (obj == null || obj.length == 0) {// a subject without principals is an anonymous userif (allowAnon) {return new DefaultUserRec(anon_user, dfltAppkey);}System.out.println("Error: exampleAppKey.getTuxedoUserRecord@return " +"anonymous user not allowed");return null;}// looping through all Principal names if necessary to get first user// name defined in tpuser filePrincipal user;String username;int key;UserRec rec;for (int i = 0; i < obj.length; i++) {user = (Principal)obj[i];username = user.getName();if (username.equals(anon_user)) {return new DefaultUserRec(anon_user, dfltAppkey);}if ((rec = (UserRec)userMap.get(username)) != null) {return rec;}}System.out.println("WARN: exampleAppKey.getTuxedoUserRecord@return " +"null UserRec");return null;}private int createCache(String fname) {FileInputStream fin;byte[] line;try {fin = new FileInputStream(fname);while ((line = readOneLine(fin)) != null) {DefaultUserRec newUser = parseOneLine(line);if (newUser != null) {userMap.put(newUser.getRemoteUserName(), newUser);}}fin.close();}catch (FileNotFoundException fnfe) {System.out.println("Error: exampleAppKey.createCache@reason: " + fnfe);return -1;}catch (SecurityException se) {System.out.println("Error: exampleAppKey.createCache@reason: " + se);return -1;}catch (IOException ioe) {System.out.println("Error: exampleAppKey.createCache@reason: " + ioe);return -1;}catch (Exception e) {System.out.println("Error: exampleAppKey.createCache@reason: " + e);return -1;}return 0;}private byte[] readOneLine(FileInputStream fh) {int len = 80;byte[] line = new byte[len];int inp = -1;int idx = 0;try {while ((inp = fh.read()) != -1) {if (idx == 0 && (inp == '\n' || inp == '\0')) {continue;}if (inp == '\n') {break;}if (idx == (len - 1)) {byte[] tmp = new byte[len + 80];System.arraycopy(line, 0, tmp, 0, len);line = tmp;len += 80;}line[idx] = (byte)inp;idx++;}}catch (Exception e) {System.out.println("Error: exampleAppKey.readOneLine@reason: " + e);return null;}if (inp == -1 && idx == 0) {return null;}byte[] tmp = new byte[idx];System.arraycopy(line, 0, tmp, 0, idx);return tmp;}private DefaultUserRec parseOneLine(byte[] line) {String name;int key = 0;DefaultUserRec usr;int firstCharacter;int i;int sidx;int fldlen;int fn;byte[] buid = null;byte[] bgid = null;byte[] clt = null;byte[] uname = null;firstCharacter = (int)line[0];if (firstCharacter == '#' || firstCharacter == '\n' ||firstCharacter == '!' || firstCharacter == '\0' ||firstCharacter == '\r') {return null;}fldlen = 0;sidx = 0;for (i = 0, fn = 0; i < line.length && fn <= CLTIDX; i++) {if (line[i] == (byte)':') {switch (fn) {case USRIDX:uname = new byte[fldlen];System.arraycopy(line, sidx, uname, 0, fldlen);break;case UIDIDX:buid = new byte[fldlen];System.arraycopy(line, sidx, buid, 0, fldlen);break;case GIDIDX:bgid = new byte[fldlen];System.arraycopy(line, sidx, bgid, 0, fldlen);break;case CLTIDX:if (line[sidx ] == (byte)'T' &&line[sidx+1] == (byte)'P' &&line[sidx+2] == (byte)'C' &&line[sidx+3] == (byte)'L' &&line[sidx+4] == (byte)'T' &&line[sidx+5] == (byte)'N' &&line[sidx+6] == (byte)'M' &&line[sidx+7] == (byte)',') {sidx += 8;fldlen -= 8;}if (fldlen > 0) {clt = new byte[fldlen];System.arraycopy(line, sidx, clt, 0, fldlen);}break;default:break;} // end of switchfn++;fldlen = 0;sidx = i + 1;} // end of ifelse {fldlen++;}}// try to tolerate incomplete lineif (fn <= CLTIDX && fldlen > 0) {switch (fn) {case USRIDX:uname = new byte[fldlen];System.arraycopy(line, sidx, uname, 0, fldlen);break;case UIDIDX:buid = new byte[fldlen];System.arraycopy(line, sidx, buid, 0, fldlen);break;case GIDIDX:bgid = new byte[fldlen];System.arraycopy(line, sidx, bgid, 0, fldlen);break;case CLTIDX:if (line[sidx ] == (byte)'T' &&line[sidx+1] == (byte)'P' &&line[sidx+2] == (byte)'C' &&line[sidx+3] == (byte)'L' &&line[sidx+4] == (byte)'T' &&line[sidx+5] == (byte)'N' &&line[sidx+6] == (byte)'M' &&line[sidx+7] == (byte)',') {sidx += 8;fldlen -= 8;}clt = new byte[fldlen];System.arraycopy(line, sidx, clt, 0, fldlen);break;}}if (uname == null || buid == null || bgid == null) {return null;}name = new String(uname);if (clt != null) {if (Arrays.equals(tpsysadm_string, clt) == true) {key = TPSYSADM_KEY;}else if (Arrays.equals(tpsysop_string, clt) == true) {key = TPSYSOP_KEY;}}if (key == 0) {Integer u_val;Integer g_val;int uid = 0;int gid = 0;try {u_val = new Integer(new String(buid));g_val = new Integer(new String(bgid));uid = u_val.intValue();gid = g_val.intValue();uid &= UIDMASK;gid &= GIDMASK;key = uid | (gid << GIDSHIFT);}catch (NumberFormatException nfe) {System.out.println("Error: exampleAppKey.readOneLine@reason: " + nfe);return null;}}return new DefaultUserRec(name, key);}private void parseParam(String param) {String str;// trim the inputtpusrfile = param.trim();return;}}