1: 
  37: 
  38: 
  39: package ;
  40: 
  41: import ;
  42: 
  43: import ;
  44: import ;
  45: import ;
  46: import ;
  47: import ;
  48: import ;
  49: import ;
  50: import ;
  51: import ;
  52: import ;
  53: 
  54: 
  58: public abstract class EnvelopeEntry
  59:     extends Entry
  60: {
  61:   private static final Logger log = Configuration.DEBUG ?
  62:                 Logger.getLogger(EnvelopeEntry.class.getName()) : null;
  63:   
  64:   protected EnvelopeEntry containingEnvelope;
  65:   
  66:   protected List entries;
  67: 
  68:   public EnvelopeEntry(int type, Properties properties)
  69:   {
  70:     super(type, properties);
  71:     entries = new LinkedList();
  72:     if (this.properties.get("alias-list") != null)
  73:       this.properties.remove("alias-list");
  74:   }
  75: 
  76:   protected EnvelopeEntry(int type)
  77:   {
  78:     super(type);
  79:     entries = new LinkedList();
  80:   }
  81: 
  82:   
  87:   public void add(Entry entry)
  88:   {
  89:     if (Configuration.DEBUG)
  90:       log.entering(this.getClass().getName(), "add", entry);
  91:     if (! containsEntry(entry))
  92:       {
  93:         if (entry instanceof EnvelopeEntry)
  94:           ((EnvelopeEntry) entry).setContainingEnvelope(this);
  95:         entries.add(entry);
  96:         if (Configuration.DEBUG)
  97:           log.fine("Payload is " + (payload == null ? "" : "not ") + "null");
  98:         makeAliasList();
  99:       }
 100:     if (Configuration.DEBUG)
 101:       log.exiting(this.getClass().getName(), "add");
 102:   }
 103: 
 104:   
 111:   public boolean containsAlias(String alias)
 112:   {
 113:     if (Configuration.DEBUG)
 114:       log.entering(this.getClass().getName(), "containsAlias", alias);
 115:     String aliases = getAliasList();
 116:     if (Configuration.DEBUG)
 117:       log.fine("aliases = [" + aliases + "]");
 118:     boolean result = false;
 119:     if (aliases != null)
 120:       {
 121:         StringTokenizer tok = new StringTokenizer(aliases, ";");
 122:         while (tok.hasMoreTokens())
 123:           if (tok.nextToken().equals(alias))
 124:             {
 125:               result = true;
 126:               break;
 127:             }
 128:       }
 129:     if (Configuration.DEBUG)
 130:       log.exiting(this.getClass().getName(), "containsAlias",
 131:                   Boolean.valueOf(result));
 132:     return result;
 133:   }
 134: 
 135:   
 141:   public boolean containsEntry(Entry entry)
 142:   {
 143:     if (entry instanceof EnvelopeEntry)
 144:       return entries.contains(entry);
 145:     if (entry instanceof PrimitiveEntry)
 146:       for (Iterator it = entries.iterator(); it.hasNext();)
 147:         {
 148:           Entry e = (Entry) it.next();
 149:           if (e.equals(entry))
 150:             return true;
 151:           if ((e instanceof EnvelopeEntry)
 152:               && ((EnvelopeEntry) e).containsEntry(entry))
 153:             return true;
 154:         }
 155:     return false;
 156:   }
 157: 
 158:   
 163:   public List getEntries()
 164:   {
 165:     return new ArrayList(entries);
 166:   }
 167: 
 168:   
 175:   public List get(String alias)
 176:   {
 177:     if (Configuration.DEBUG)
 178:       log.entering(this.getClass().getName(), "get", alias);
 179:     List result = new LinkedList();
 180:     for (Iterator it = entries.iterator(); it.hasNext();)
 181:       {
 182:         Entry e = (Entry) it.next();
 183:         if (e instanceof EnvelopeEntry)
 184:           {
 185:             EnvelopeEntry ee = (EnvelopeEntry) e;
 186:             if (! ee.containsAlias(alias))
 187:               continue;
 188:             if (ee instanceof MaskableEnvelopeEntry)
 189:               {
 190:                 MaskableEnvelopeEntry mee = (MaskableEnvelopeEntry) ee;
 191:                 if (mee.isMasked())
 192:                   {
 193:                     if (Configuration.DEBUG)
 194:                       log.fine("Processing masked entry: " + mee);
 195:                     result.add(mee);
 196:                     continue;
 197:                   }
 198:               }
 199:             if (Configuration.DEBUG)
 200:               log.fine("Processing unmasked entry: " + ee);
 201:             result.addAll(ee.get(alias));
 202:           }
 203:         else if (e instanceof PrimitiveEntry)
 204:           {
 205:             PrimitiveEntry pe = (PrimitiveEntry) e;
 206:             if (pe.getAlias().equals(alias))
 207:               result.add(e);
 208:           }
 209:       }
 210:     if (Configuration.DEBUG)
 211:       log.exiting(this.getClass().getName(), "get", result);
 212:     return result;
 213:   }
 214: 
 215:   
 221:   public String getAliasList()
 222:   {
 223:     String list = properties.get("alias-list");
 224:     if (list == null)
 225:       return "";
 226:     else
 227:       return list;
 228:   }
 229: 
 230:   
 236:   public boolean remove(Entry entry)
 237:   {
 238:     if (Configuration.DEBUG)
 239:       log.entering(this.getClass().getName(), "remove", entry);
 240:     boolean ret = false;
 241:     for (Iterator it = entries.iterator(); it.hasNext();)
 242:       {
 243:         Entry e = (Entry) it.next();
 244:         if (e instanceof EnvelopeEntry)
 245:           {
 246:             if (e == entry)
 247:               {
 248:                 it.remove();
 249:                 ret = true;
 250:                 break;
 251:               }
 252:             if (((EnvelopeEntry) e).remove(entry))
 253:               {
 254:                 ret = true;
 255:                 break;
 256:               }
 257:           }
 258:         else if (e instanceof PrimitiveEntry)
 259:           {
 260:             if (((PrimitiveEntry) e).equals(entry))
 261:               {
 262:                 it.remove();
 263:                 ret = true;
 264:                 break;
 265:               }
 266:           }
 267:       }
 268:     if (ret)
 269:       {
 270:         if (Configuration.DEBUG)
 271:           log.fine("State before: " + this);
 272:         payload = null;
 273:         makeAliasList();
 274:         if (Configuration.DEBUG)
 275:           log.fine("State after: " + this);
 276:       }
 277:     if (Configuration.DEBUG)
 278:       log.exiting(this.getClass().getName(), "remove", Boolean.valueOf(ret));
 279:     return ret;
 280:   }
 281: 
 282:   
 291:   public boolean remove(String alias)
 292:   {
 293:     if (Configuration.DEBUG)
 294:       log.entering(this.getClass().getName(), "remove", alias);
 295:     boolean result = false;
 296:     for (Iterator it = entries.iterator(); it.hasNext();)
 297:       {
 298:         Entry e = (Entry) it.next();
 299:         if (e instanceof EnvelopeEntry)
 300:           {
 301:             EnvelopeEntry ee = (EnvelopeEntry) e;
 302:             result = ee.remove(alias) || result;
 303:           }
 304:         else if (e instanceof PrimitiveEntry)
 305:           {
 306:             PrimitiveEntry pe = (PrimitiveEntry) e;
 307:             if (pe.getAlias().equals(alias))
 308:               {
 309:                 it.remove();
 310:                 result = true;
 311:               }
 312:           }
 313:       }
 314:     if (result)
 315:       {
 316:         if (Configuration.DEBUG)
 317:           log.fine("State before: " + this);
 318:         payload = null;
 319:         makeAliasList();
 320:         if (Configuration.DEBUG)
 321:           log.fine("State after: " + this);
 322:       }
 323:     if (Configuration.DEBUG)
 324:       log.exiting(this.getClass().getName(), "remove", Boolean.valueOf(result));
 325:     return result;
 326:   }
 327: 
 328:   public String toString()
 329:   {
 330:     return new StringBuilder("Envelope{")
 331:         .append(super.toString())
 332:         .append(", entries=").append(entries)
 333:         .append("}")
 334:         .toString();
 335:   }
 336: 
 337:   
 338:   
 339: 
 340:   protected void encodePayload() throws IOException
 341:   {
 342:     ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
 343:     DataOutputStream out = new DataOutputStream(bout);
 344:     for (Iterator it = entries.iterator(); it.hasNext();)
 345:       ((Entry) it.next()).encode(out);
 346:   }
 347: 
 348:   protected void setContainingEnvelope(EnvelopeEntry e)
 349:   {
 350:     if (containingEnvelope != null)
 351:       throw new IllegalArgumentException("envelopes may not be shared");
 352:     containingEnvelope = e;
 353:   }
 354: 
 355:   protected void decodeEnvelope(DataInputStream in) throws IOException
 356:   {
 357:     this.entries.clear();
 358:     while (true)
 359:       {
 360:         int type = in.read();
 361:         switch (type)
 362:           {
 363:           case EncryptedEntry.TYPE:
 364:             add(EncryptedEntry.decode(in));
 365:             break;
 366:           case PasswordEncryptedEntry.TYPE:
 367:             add(PasswordEncryptedEntry.decode(in));
 368:             break;
 369:           case PasswordAuthenticatedEntry.TYPE:
 370:             add(PasswordAuthenticatedEntry.decode(in));
 371:             break;
 372:           case AuthenticatedEntry.TYPE:
 373:             add(AuthenticatedEntry.decode(in));
 374:             break;
 375:           case CompressedEntry.TYPE:
 376:             add(CompressedEntry.decode(in));
 377:             break;
 378:           case CertificateEntry.TYPE:
 379:             add(CertificateEntry.decode(in));
 380:             break;
 381:           case PublicKeyEntry.TYPE:
 382:             add(PublicKeyEntry.decode(in));
 383:             break;
 384:           case PrivateKeyEntry.TYPE:
 385:             add(PrivateKeyEntry.decode(in));
 386:             break;
 387:           case CertPathEntry.TYPE:
 388:             add(CertPathEntry.decode(in));
 389:             break;
 390:           case BinaryDataEntry.TYPE:
 391:             add(BinaryDataEntry.decode(in));
 392:             break;
 393:           case -1:
 394:             return;
 395:           default:
 396:             throw new MalformedKeyringException("unknown type " + type);
 397:           }
 398:       }
 399:   }
 400: 
 401:   private void makeAliasList()
 402:   {
 403:     if (Configuration.DEBUG)
 404:       log.entering(this.getClass().getName(), "makeAliasList");
 405:     if (! entries.isEmpty())
 406:       {
 407:         StringBuilder buf = new StringBuilder();
 408:         String aliasOrList;
 409:         for (Iterator it = entries.iterator(); it.hasNext();)
 410:           {
 411:             Entry entry = (Entry) it.next();
 412:             aliasOrList = null;
 413:             if (entry instanceof EnvelopeEntry)
 414:               aliasOrList = ((EnvelopeEntry) entry).getAliasList();
 415:             else if (entry instanceof PrimitiveEntry)
 416:               aliasOrList = ((PrimitiveEntry) entry).getAlias();
 417:             else if (Configuration.DEBUG)
 418:               log.fine("Entry with no Alias. Ignored: " + entry);
 419:             if (aliasOrList != null)
 420:               {
 421:                 aliasOrList = aliasOrList.trim();
 422:                 if (aliasOrList.trim().length() > 0)
 423:                   {
 424:                     buf.append(aliasOrList);
 425:                     if (it.hasNext())
 426:                       buf.append(';');
 427:                   }
 428:               }
 429:           }
 430:         String aliasList = buf.toString();
 431:         properties.put("alias-list", aliasList);
 432:         if (Configuration.DEBUG)
 433:           log.fine("alias-list=[" + aliasList + "]");
 434:         if (containingEnvelope != null)
 435:           containingEnvelope.makeAliasList();
 436:       }
 437:     if (Configuration.DEBUG)
 438:       log.exiting(this.getClass().getName(), "makeAliasList");
 439:   }
 440: }