Return-Path: Delivered-To: apmail-geronimo-dev-archive@www.apache.org Received: (qmail 87293 invoked from network); 31 Oct 2008 16:20:58 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 31 Oct 2008 16:20:58 -0000 Received: (qmail 67606 invoked by uid 500); 31 Oct 2008 16:21:01 -0000 Delivered-To: apmail-geronimo-dev-archive@geronimo.apache.org Received: (qmail 67562 invoked by uid 500); 31 Oct 2008 16:21:01 -0000 Mailing-List: contact dev-help@geronimo.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@geronimo.apache.org List-Id: Delivered-To: mailing list dev@geronimo.apache.org Delivered-To: moderator for dev@geronimo.apache.org Received: (qmail 23244 invoked by uid 99); 31 Oct 2008 07:44:23 -0000 X-ASF-Spam-Status: No, hits=1.2 required=10.0 tests=SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (athena.apache.org: local policy) Message-ID: <490AB702.9060508@webtide.com> Date: Fri, 31 Oct 2008 18:42:58 +1100 From: Jan Bartel Reply-To: janb@webtide.com Organization: Webtide User-Agent: Thunderbird 2.0.0.16 (X11/20080724) MIME-Version: 1.0 To: dev@jetty.codehaus.org, David Jencks CC: dev@geronimo.apache.org Subject: Re: [jetty-dev] Jetty Security refactoring for JASPI References: <48F837C4.50400@webtide.com> <49091DF7.3060300@webtide.com> <11DB9A16-A66A-4660-B884-194583D8C51F@yahoo.com> <490A9D83.6090503@webtide.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Hi David, No, I'm referring to this code: ConstraintSecurityHandler.checkUserDataPermissions line 235 and 259. It is doing a redirect there to get the request to come in again on the right connector (either the confidential or integral port as appropriate). cheers Jan David Jencks wrote: > > On Oct 30, 2008, at 10:54 PM, Jan Bartel wrote: > >> Hi David, >> >> I'll reply to your reply in a later posting. For now, I just noticed >> something odd in the ConstraintSecurityHandler. If >> checkUserDataPermissions() >> notices the request was received on the wrong connector (ie on http >> instead of >> https) and does a redirect, the AbstractSecurityHandler.handle() >> method goes >> ahead and subjects the request to JASPI authentication. It seems to me >> that >> at that point we want to stop processing the request altogether. It will >> be the redirected request that we're interested in processing further >> (either doing the auth or doing a redirect to a login form). > > I think you are referring to this code? > > if (!checkUserDataPermissions(pathInContext, > base_request, base_response, constraintInfo)) > { > if (!base_request.isHandled()) > { > response.sendError(Response.SC_FORBIDDEN); > base_request.setHandled(true); > } > return; > } > > I think there's something odd here, but IIUC something other than what > you see. > This is not proposing a redirect, it is plainly denying the request. > I've been worrying about this because it prevents redirecting http > requests to the equivalent https requests. Until recently I didn't > think it was possible to do this redirect using jacc permissions but I > think there is a solution.... > > If the actual request is denied and is http we could create a new > request with the url converted to https and checkUserDataPermissions on > it.... if that check succeeds we can redirect to the more secure url. > This is somewhat analogous to the way we determine if authentication is > mandatory, namely by doing a web resource permission check with the > unauthenticated user. > > I might also have missed what you are looking at... > > thanks > david jencks >> >> >> cheers >> Jan >> >> David Jencks wrote: >>> Hi Jan, >>> >>> On Oct 29, 2008, at 7:37 PM, Jan Bartel wrote: >>> >>>> Hi David, >>>> >>>> I'm still snatching time to tiptoe further around the jaspi branch. >>>> >>>> A couple of thoughts to run by you: >>>> >>>> 1. UserIdentity and LoginService classnames. These are quasi analogous >>>> to UserPrincipal and UserRealm (although the behaviour has been >>>> refactored). >>>> I'm wondering whether it might not be a good idea to retain the old >>>> classnames, just so it might be easier for jetty users/developers >>>> to ease into understanding the new security structures? >>>> >>> >>> I'm not sure that keeping the old names would help anyone understand the >>> new code, I rather think it would be confusing. I'd really rather not >>> call UserIdentity a Principal since it isn't a Principal and depending >>> on the security handler implementation can contain rather different >>> things. The main point of introducing it was that in jetty integrations >>> (Geronimo and from distant memory JBoss) the UserPrincipal was >>> ridiculously overloaded to contain incredible amounts of non-principal >>> information associated with the user's identity. I think that instead >>> it makes sense to have an object that supplies the UserPrincipal, plus >>> whatever else the security system needs. I don't have strong objection >>> to calling the LoginService UserRealm but I think its going to be >>> confusing and less informative since it doesn't have the >>> non-login-service methods any more. >>> >>>> 1a. Actually thinking about this, it will probably be quite >>>> important for >>>> Jetty users to be able to make a smooth transition over to a >>>> jaspi-based >>>> implementation. Do you think we can retain a UserRealm and a >>>> UserPrincipal >>>> with all their methods intact, but just "blend in" the jaspi-ness with >>>> some extra methods and some changed implementations of the existing >>>> apis? >>>> >>> >>> Maybe. I think the new interfaces are a lot clearer and more >>> descriptive for embedding jetty that the old ones. I could look into >>> writing adapters from UserIdentity to UserPrincipal and LoginService to >>> UserRealm but I'm not entirely sure it will work. In particular I'm not >>> at all sure the non login-service methods on UserRealm could plausibly >>> be called. >>> >>>> 2. We allow a UserRealm to be explicitly set on a WebAppContext (well, >>>> strictly speaking its >>>> WebAppContext.getSecurityHandler().setUserRealm(UserRealm)). >>>> I couldn't see specific support for that, only getting a list of >>>> LoginServices from the Server instance. Should be easy enough to >>>> put in though? >>> >>> I'm not sure how my code is different, except the LoginService is final >>> and set in the constructor of ServletCallbackHandler, around line 1042 >>> of WebXmlConfiguration. I don't recall changing this code much... >>> >>>> >>>> >>>> 3. With the JAAS stuff, which has its own set of callbacks it >>>> uses to obtain info, we used a DefaultCallbackHandler to plug in >>>> the right info, such as credentials, passwords, usernames and >>>> also extra request parameters from the login. I notice you're using >>>> an anonymous CallbackHandler instead to pass into the JAAS >>>> LoginContext. >>>> Is it possible to use the DefaultCallbackHandler instead? It supports >>>> a couple more callback types that some LoginModule implementations may >>>> depend on. >>> >>> I could misunderstand the DefaultCallbackHandler but I think that the >>> extensions to a user-password callback handler all involve extracting >>> credentials from the request. In the jaspi architecture this is the >>> function of the auth module, not the password validation service. A >>> login module that fishes directly in the request ought to be refactored >>> into a plain login module that just validates the credentials and an >>> auth module that extracts the credentials from the message. Despite all >>> the weirdness in jaspi I think this is a good idea and worth enforcing. >>> >>> I guess someone who really really wanted to preserve their login module >>> could write a subclass of LoginCallback that dealt with request >>> parameters, and a JAASLoginService subclass. This would be made easier >>> by factoring out the CallbackHandler creation in JAASLoginService into a >>> protected method. Looks like I left out some exception handling there >>> too :-( I'd rather not encourage this however. >>> >>>> >>>> >>>> 4. Minor thing - is there a lot of value in the RunAsToken marker >>>> interface >>>> as opposed to just having a String? The roles and role mappings are >>>> themselves just Strings, so I was wondering what the utility is? >>> >>> This is an embedding thing also. It's pretty unclear what run-as is >>> actually supposed to mean and how things like supplying the identity for >>> a web service client or other remote call is supposed to work. (If the >>> web service is supposed to be called as the user, rather than the >>> server's identity, and you are in a run-as role, what credentials does >>> this run-as-role identity supply????) In Geronimo we represent the >>> run-as role by a Subject obtained by logging into a security realm. So, >>> the geronimo run-as token has this Subject in it. We might want to >>> store a UserIdentity there instead..... anyway I don't think >>> constraining the representation of the run-as identity is wise. >>> >>> BTW remember that the current auth modules implementing >>> BASIC/DIGEST/FORM auth are more or less temporary until we more or less >>> agree on the main interfaces, at which time I plan to rewrite them in >>> more jetty-friendly form (also after apachecon :-) >>> >>> Many thanks! >>> david jencks >>> >>>> >>>> >>>> best regards >>>> Jan >>>> >>>> David Jencks wrote: >>>>> >>>>> On Oct 16, 2008, at 11:59 PM, Jan Bartel wrote: >>>>> >>>>>> Hi David, >>>>>> >>>>>> Firstly, let me genuflect in recognition of your extraordinary >>>>>> efforts >>>>>> for a) reading the spec b) being able to make heads or tails of it c) >>>>>> coming up with an implementation based on it! >>>>> >>>>> :-D >>>>>> >>>>>> >>>>>> I'm surpressing the urge to have a bit of rant at yet another jcp >>>>>> spec >>>>>> that is at the same time heavy on the verbiage and light on >>>>>> comprehensibility. Your email was way more informative >>>>>> than what 29 people managed to produce in the spec. >>>>>> >>>>>> Anyway, looking at the code in the jetty-7-jaspi branch, and I admit >>>>>> that so far I've only just had a cursory nosey around, where would >>>>>> we integrate the JAAS side of things? Implement a JAASLoginService? >>>>> >>>>> see org.mortbay.jetty.plus.jaas in modules/plus/jetty-plus >>>>> Not sure if it is ideal, it's pretty much a simple modification of >>>>> the >>>>> former JAASUserRealm >>>>> >>>>>> >>>>>> >>>>>> I'll have a deeper look at the code and get back to you with more >>>>>> informed comments. This mail is to re-assure you that your post >>>>>> hasn't fallen into the void and that we are looking forward to >>>>>> integrating this into jetty-7 trunk! >>>>> >>>>> The main thing to remember might be that the current >>>>> implementations of >>>>> built-in security (FORM, BASIC, DIGEST etc) are in jaspi "modules" >>>>> only >>>>> until we agree on the jetty api at which point I was thinking to >>>>> convert >>>>> them back into more jetty specific code. Of course if you decide you >>>>> really like jaspi.... :-) >>>>>> >>>>>> >>>>>> Jan >>>>>> PS I love this code-comment in ServletCallbackHandler: >>>>>> >>>>>> * Idiot class required by jaspi stupidity @#*($)#@&^)$@#&*$@ >>>>> >>>>> Several parts of the jaspi spec look to me as if they are sort of >>>>> stuck >>>>> on at the end when someone realized it was incomplete, and the >>>>> heavy use >>>>> of CallbackHandler for two way communication between the jaspi modules >>>>> and the container strikes me as one such point. >>>>> >>>>> thanks >>>>> david jencks >>>>> >>>>>> >>>>>> >>>>>> :) >>>>>> >>>>>> David Jencks wrote: >>>>>>> Greg and Jan were kind enough to create a branch for me to play >>>>>>> around >>>>>>> with a JASPI (Java Authentication Service Provider Interface) >>>>>>> integration with jetty and its getting to a point where I'm >>>>>>> willing to >>>>>>> talk about it. >>>>>>> >>>>>>> Code is at >>>>>>> https://svn.codehaus.org/jetty/jetty/branches/jetty-7-jaspi >>>>>>> >>>>>>> JASPI attempts to provide a uniform framework for messaging systems, >>>>>>> both client and server side, to plug in message authentication. On >>>>>>> the >>>>>>> client you can add auth info to a request and validate auth info >>>>>>> on a >>>>>>> response. On the server you can validate auth info on a request >>>>>>> and add >>>>>>> auth info to a response. The auth code can conduct arbitrary >>>>>>> message >>>>>>> exchanges to negotiate what info is needed and transmit the info. >>>>>>> I've >>>>>>> been working on the server side auth for jetty. >>>>>>> >>>>>>> The actual spec jaspi interfaces are not 100% ideal for http and >>>>>>> don't >>>>>>> allow stuff like lazy authentication for unsecured resources so I've >>>>>>> come up with interfaces similar in spirit to the jaspi ones. >>>>>>> >>>>>>> I've also tried to rework the implementation so it is more >>>>>>> friendly to >>>>>>> integration with other app servers with their own ideas about >>>>>>> security >>>>>>> frameworks such as geronimo and in particular make jacc >>>>>>> implementations >>>>>>> easier. I expect these changes will also simplify integration with >>>>>>> e.g. >>>>>>> jboss and glassfish but I haven't seriously tried to verify this. >>>>>>> >>>>>>> Currently all the authentication code (replacing the *Authenticator >>>>>>> classes) is implemented in terms of jaspi but I plan to change this >>>>>>> soon >>>>>>> to use the jetty specific interfaces directly. >>>>>>> >>>>>>> So.... lets follow a HttpServletRequest/Response pair on its voyage >>>>>>> through the security system... >>>>>>> >>>>>>> >>>>>>> ... it arrives at AbstractSecurityHandler.handle. This is a >>>>>>> template >>>>>>> method that runs through the following structure calling out to >>>>>>> subclasses and the authentication system: >>>>>>> 1. calls checkUserDataPermissions(pathInContext, base_request, >>>>>>> base_response, constraintInfo). This checks the user data >>>>>>> constraints, >>>>>>> basically that the request arrived over the right kind of connection >>>>>>> (http/https). Two obvious implementations of this are the existing >>>>>>> jetty constraint based implementation or one based on JACC. >>>>>>> >>>>>>> 2. calls isAuthMandatory(base_request, base_response, >>>>>>> constraintInfo) to >>>>>>> determine if the request actually needs authentication. If it does >>>>>>> not >>>>>>> we can often delay authentication until a method relying on auth >>>>>>> results >>>>>>> is called (such as getUserPrincipal or isUserInRole). Again this >>>>>>> can be >>>>>>> implemented using constraints or JACC. >>>>>>> >>>>>>> 3. packs the request, response, and authManditory into a >>>>>>> JettyMessageInfo holder object which can also pass various auth >>>>>>> info in >>>>>>> a map. >>>>>>> >>>>>>> 4. delegates the authentication to the jaspi-like ServerAuthResult >>>>>>> authResult = serverAuthentication.validateRequest(messageInfo); >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>> assuming we are not doing lazy auth, this will extract the >>>>>>> credentials >>>>>>> from the request (possibly conducing a multi-message exchange >>>>>>> with the >>>>>>> client to request the credentials) and validate them. >>>>>>> Validation can use a LoginService possibly provided to the >>>>>>> ServerAuthentication which could be JAAS, Hash, JDBC, etc etc. >>>>>>> Lazy auth results in returning a lazy result that only attempts >>>>>>> authentication when info is actually needed. In this case no >>>>>>> message >>>>>>> exchange with the client is possible. >>>>>>> <<<<<<<<<<<<<<<<<<<< >>>>>>> 5. Assuming that authentication succeeded (this includes the lazy >>>>>>> case >>>>>>> where the request would be allowed even without authentication), we >>>>>>> wrap >>>>>>> up the result in an identity delegate: >>>>>>> UserIdentity userIdentity = newUserIdentity(authResult); >>>>>>> base_request.setUserIdentity(userIdentity); >>>>>>> The UserIdentity is the delegate for run-as role implementation and >>>>>>> actually answering auth questions from the application program. >>>>>>> This >>>>>>> allows app servers to handle run-as roles however they want. >>>>>>> >>>>>>> 6. Assuming authentication is mandatory, now that we know the >>>>>>> user, we >>>>>>> can find out if they are in the appropriate roles: >>>>>>> checkWebResourcePermissions(pathInContext, base_request, >>>>>>> base_response, >>>>>>> constraintInfo, userIdentity) >>>>>>> >>>>>>> 7. On success, we can actually handle the request: >>>>>>> getHandler().handle(pathInContext, messageInfo.getRequestMessage(), >>>>>>> messageInfo.getResponseMessage(), dispatch); >>>>>>> >>>>>>> 8. Assuming no exceptions were thrown, we can now secure the >>>>>>> response >>>>>>> (normally a no-op for http): >>>>>>> serverAuthentication.secureResponse(messageInfo, authResult); >>>>>>> >>>>>>> ------------------------------------------- >>>>>>> >>>>>>> JASPI implementations >>>>>>> >>>>>>> I wrote a fairly complete jaspi framework implementation for >>>>>>> geronimo >>>>>>> (rather than the bits actually needed for http which I wrote for >>>>>>> jetty) >>>>>>> and have a nearly-untested openid implementation. This >>>>>>> (theoretically) >>>>>>> lets you openid-enable your app by supplying an appropriate login >>>>>>> page >>>>>>> and useing the openid auth module. >>>>>>> >>>>>>> Theres also a glassfish implementation that I haven't looked at and >>>>>>> someone wrote a SPNEGO auth module that works with it. >>>>>>> http://spnego.ocean.net.au/ >>>>>>> >>>>>>> -------------------------------------------- >>>>>>> >>>>>>> How does this differ from what's there now? >>>>>>> >>>>>>> SecurityHandler: AbstractSecurityHandler now just has the basic >>>>>>> workflow described about and delegates all actual work to either >>>>>>> subclasses (for authorization decisions and object creation) or the >>>>>>> authentication delegate. This makes it easy to plug in alternate >>>>>>> implementations such as a JACC implementation for an EE server. >>>>>>> >>>>>>> Authentication results and run-as roles: Formerly these were either >>>>>>> directly set in the request (possibly using lazy evaluation, with >>>>>>> code >>>>>>> again in Request) or stuffed into a Principal implementation via the >>>>>>> UserRealm. This really overloaded the idea of a Principal for no >>>>>>> apparent reason and made integration into app servers slightly >>>>>>> convoluted. This is replaced with a UserIdentity interface >>>>>>> providing >>>>>>> separate access to the auth results (user principal) and role >>>>>>> handling >>>>>>> (isUserInRole, and run-as handling). Subclasses of >>>>>>> AbstractSecurityHandler can provide their own implementations of >>>>>>> this >>>>>>> interface. These typically delegate to implementations of >>>>>>> ServerAuthResult, which can handle lazy authentication if necessary. >>>>>>> >>>>>>> UserRealm IMO glues together a lot of unrelated functions, >>>>>>> primarily the >>>>>>> role handling code now in UserIdentity and the credential >>>>>>> validation now >>>>>>> in LoginService. Credential validation may not even be needed by >>>>>>> the >>>>>>> server (e.g. openid). If needed it's called from something that >>>>>>> extracts credentials from the request. Implementations are going >>>>>>> to do >>>>>>> something like look up the user in a file or table or delegate to >>>>>>> JAAS. >>>>>>> On the other hand the role handling is called by jetty or by the >>>>>>> application and the implementation is done by the app server >>>>>>> (jetty or >>>>>>> e.g. geronimo). Aside from being related somehow to security, >>>>>>> these are >>>>>>> totally unrelated concerns. >>>>>>> >>>>>>> -------------------------------------------------- >>>>>>> >>>>>>> How does ServerAuthentication and LoginService relate to JASPI? >>>>>>> >>>>>>> The JASPI interface similar to ServerAuthentication is >>>>>>> ServerAuthContext: >>>>>>> >>>>>>> void cleanSubject(MessageInfo messageInfo, Subject subject) throws >>>>>>> AuthException; >>>>>>> >>>>>>> AuthStatus secureResponse(MessageInfo messageInfo, Subject >>>>>>> serviceSubject) throws AuthException; >>>>>>> >>>>>>> AuthStatus validateRequest(MessageInfo messageInfo, Subject >>>>>>> clientSubject, Subject serviceSubject) throws AuthException; >>>>>>> >>>>>>> The main difference is that ServerAuthentication packages all the >>>>>>> results into a ServerAuthResult object rather than modifying the >>>>>>> clientSubject directly and hiding user principal and group info in >>>>>>> some >>>>>>> callback handers. This lets ServerAuthentication support lazy auth. >>>>>>> >>>>>>> As far as configuration goes. you get a ServerAuthContext by >>>>>>> calling a >>>>>>> whole lotta methods on some other stuff. or.... you can just >>>>>>> create one >>>>>>> and stuff it into an adapter, JaspiServerAuthentication. >>>>>>> Probably we >>>>>>> want to implement the built in auth methods as direct >>>>>>> ServerAuthentication implementations rather than the current >>>>>>> ServerAuthModule implementations (a ServerAuthContext is supposed to >>>>>>> delegate to one or more ServerAuthModules, which have the same >>>>>>> interface). >>>>>>> >>>>>>> LoginService is a pretty straightforward way of asking for password >>>>>>> validation and getting some info back. JASPI has a peculiar IMO >>>>>>> system >>>>>>> based on Callbacks. The container (jetty) supplies the auth context >>>>>>> with a CallbackHandler that enables bi-directional communication. >>>>>>> Callbacks providing services to the auth module: >>>>>>> >>>>>>> PasswordValidationCallback: this lets the auth module ask for >>>>>>> password >>>>>>> validation: this is the closest to LoginService. >>>>>>> CertStoreCallback, PrivateKeyCallback, SecretKeyCallback, and >>>>>>> TrustStoreCallback all let the auth module ask for certificate >>>>>>> services. AFAICT these are mostly for securing response messages, >>>>>>> which >>>>>>> is typically not done for http. >>>>>>> >>>>>>> Callbacks letting the auth module pass info to the server: >>>>>>> CallerPrincipalCallback: supplies the caller principal so >>>>>>> getCallerPrincipal can return something. >>>>>>> GroupPrincipalCallback supplies "groups" the user may be in. The >>>>>>> meaning here is rather undefined but can be mapped to roles in some >>>>>>> way, >>>>>>> such as by assuming the groups and roles are the same. >>>>>>> >>>>>>> The use of callbacks here still seems rather weird to me but may >>>>>>> make >>>>>>> more sense in the context of other messaging systems: jaspi is >>>>>>> supposed >>>>>>> to be applicable to all sorts of messaging, including ejb calls, >>>>>>> jms, >>>>>>> web services, etc etc. >>>>>>> >>>>>>> I've put the caller principal and groups into the ServerAuthResult >>>>>>> object where they can be accessed directly (although possibly >>>>>>> determined >>>>>>> lazily). >>>>>>> >>>>>>> >>>>>>> -------------------------------------------------------------- >>>>>>> >>>>>>> Comments... >>>>>>> >>>>>>> Right now it looks to me as if form auth needs to be non-lazy since >>>>>>> part >>>>>>> of the message exchange involves a request to j_security_check >>>>>>> which is >>>>>>> normally not a secured response. Trying to evaluate auth for this >>>>>>> lazily doesn't work... you never get back to the original request. >>>>>>> >>>>>>> I don't see how this implementation could be significantly >>>>>>> simplified or >>>>>>> sped up.... I'm certainly willing to look at problems. >>>>>>> >>>>>>> I've been discussing JACC with Greg for a long time now. The only >>>>>>> thing >>>>>>> I can see that is possible with constraint implementations that >>>>>>> is not >>>>>>> possible with jacc is redirecting an http request to the >>>>>>> "equivalent" >>>>>>> https request if a user data constraint is violated. I'm curious >>>>>>> about >>>>>>> whether this is something people want to do or usually set up. >>>>>>> >>>>>>> Many thanks, >>>>>>> david jencks >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> --------------------------------------------------------------------- >>>>>>> >>>>>>> To unsubscribe from this list, please visit: >>>>>>> >>>>>>> http://xircles.codehaus.org/manage_email >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Jan Bartel, Webtide LLC | janb@webtide.com | http://www.webtide.com >>>>>> >>>>>> --------------------------------------------------------------------- >>>>>> To unsubscribe from this list, please visit: >>>>>> >>>>>> http://xircles.codehaus.org/manage_email >>>>>> >>>>>> >>>>> >>>>> >>>>> --------------------------------------------------------------------- >>>>> To unsubscribe from this list, please visit: >>>>> >>>>> http://xircles.codehaus.org/manage_email >>>>> >>>>> >>>>> >>>> >>>> >>>> -- >>>> Jan Bartel, Webtide LLC | janb@webtide.com | http://www.webtide.com >>> >>> >>> --------------------------------------------------------------------- >>> To unsubscribe from this list, please visit: >>> >>> http://xircles.codehaus.org/manage_email >>> >>> >>> >> >> >> -- >> Jan Bartel, Webtide LLC | janb@webtide.com | http://www.webtide.com > > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > -- Jan Bartel, Webtide LLC | janb@webtide.com | http://www.webtide.com