[Building Sakai] Enc: SMTP outgoing mail problem Part II !

Matthew Buckett matthew.buckett at it.ox.ac.uk
Thu May 23 08:40:44 PDT 2013


I think you might have a trailing space on your username line of your
sakai.properties.


# UserName to connect to SMTP server (Optional)
smtpUser at org.sakaiproject.email.api.EmailService=XXX at qpainformatica.com.br




On Thu, May 23, 2013 at 4:35 PM, elcio abrahão
<elcio_abrahao at yahoo.com.br>wrote:

> Hi Folks !
>
> My name is Elcio and I m trying to send email thru SAKAI, version 2.9.1,
> but I m getting an javax.mail.AuthenticationFailedException: 535
> Incorrect authentication data error.
>
> I already read all related massages on this list, but no solution works
> for me. This is what I did:
>
> 1) Check and double check the user name and password from my SMTP server
> (no spaces chars on any of it...)
> 2) Check the name of the server and other email configurations like
> SSL/TLS = false and so one...
> 3) I wrote a test application named SendMail (servlet code below) that
> test the SMTP configurations and it works perfectly.
> 4) When trying to send a messagem from the SAKAI user interface I got that
> error...
>
> Could you help me understand why I got the error when I m using SAKAI and
> did not get it when I m using the test app ?? This will prove that the
> problem is on SAKAI (should I presume ?)
>
> What I could do to fix it ?!?   Turn off the SMTP authentication will
> solve the problem ?!?
>
> This is the only issue that prevent I use SAKAI as my AVA, please help me !
>
> Thanks so much !
>
> Elcio A.
> elcio_abrahao at yahoo.com.br
>
>
> ---------------------Here is my sakai.properties file (email config only):
> # ########################################################################
> # EMAIL
> # ########################################################################
>
> ## INCOMING EMAIL
> # flag to enable or disable James for incoming email (true | false)
> #Default=false.
> smtp.enabled=false
>
> # dns addresses used by James for incoming email.
> #smtp.dns.1=255.255.255.1
> #smtp.dns.2=255.255.255.2
>
> # SMTP port on which James runs.
> # Recommend running on 8025, and using a standard mailer on 25 to forward
> mail to Sakai.
> # Default=25.
> #smtp.port=25
>
> # Email support address used in incoming email rejection messages.
> mail.support=sac at qpainformatica.com.br
>
> # Control James email processing rules
> # Valid processors are: none (ghost), error, local-address-error,
> relay-denied, and bounces
> # none - no processing occurs, the message is essentially ignored
> # error - the error processor is triggered which usually emails the admin
> and logs the value
> # local-address-error - bounce back to origin and indicate the address is
> wrong
> # relay-denied - bounce back and indicate messages are not accepted from
> their email / domain
> # bounces - general bounce back to the origin
> # All processing is blocked by default to protect Sakai from becoming a
> spam relay (so all processors are set to "none")
> # To match pre-sakai-2.7 processing, uncomment the processors below
> #smtp.archive.disabled.processor=none
> #smtp.archive.address.invalid.processor=local-address-error
> #smtp.user.not.allowed.processor=bounces
>
> ## OUTGOING EMAIL
> # SMTP server for outgoing emails.
> smtp at org.sakaiproject.email.api.EmailService=localhost
>
> # SMTP port to connect to outgoing SMTP Server
> # Default: 25
> smtpPort at org.sakaiproject.email.api.EmailService=25
>
> # UserName to connect to SMTP server (Optional)
> smtpUser at org.sakaiproject.email.api.EmailService=XXX at qpainformatica.com.br
>
> # Password for connection to SMTP server (Optional)
> smtpPassword at org.sakaiproject.email.api.EmailService=XXXXXX
>
> # Use SSL/TLS to connect to the SMPT server
> # default: false
> smtpUseSSL at org.sakaiproject.email.api.EmailService=false
>
> # Run in test mode - email will be written to the log rather sent
> # default: false
> smtpDebug at org.sakaiproject.email.api.EmailService=true
>
> # Email address to send errors caught by the portal, and user bug reports
> in response.
> portal.error.email=elcio_abrahao at yahoo.com.br
>
> # Email address used as the "from" address for any email sent by Worksite
> Setup tool or Site Info tool.
> setup.request=android2013 at qpainformatica.com.br
>
> # Send an email to the user when the user is added.
> # Default: true
> #notifyNewUserEmail=true
>
> # Comma-separated list of domain names that are not allowed in guest
> accounts
> # This property is useful for preventing the accidental creation of guest
> accounts
> # for users (based on email address) that already have an external account
> (based on
> # username).  For instance, if this property is set to umich.edu, then a
> user
> # trying to add knoop at umich.edu to a site will receive an error, as there
> is an
> # expectation that a "knoop" user should already exist.
> # Example: umich.edu
> # Default: null (all domains are valid)
> #invalidEmailInIdAccountString=
>
> # Email notifications reply from preference
> # Set this to true to send notifications from the triggering user email
> addresses for announcements
> # instead of from a general server email address (no-reply at ...)
> # OLD (deprecated) config value:
> emailFromReplyable at org.sakaiproject.event.api.NotificationService
> # Default: false (use the no-reply at ... instead)
> #notify.email.from.replyable = true
>
> # Email notifications reply to preference
> # Set this to true to send notifications with the to field set to a user
> email instead of a general server email address
> # OLD (deprecated) config value:
> emailToReplyable at org.sakaiproject.event.api.NotificationService
> # Default: false (use the server address instead of the user)
> #notify.email.to.replyable = true
> -------------------------- end properties file
>
> -------------------------- Here is the error DUMP from the log file
> DEBUG: JavaMail version 1.4.4
> DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
> DEBUG: Tables of loaded providers
> DEBUG: Providers Listed By Class Name:
> {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun
> Microsystems, Inc],
> com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun
> Microsystems, Inc],
> com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun
> Microsystems, Inc],
> com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun
> Microsystems, Inc],
> com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun
> Microsystems, Inc],
> com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun
> Microsystems, Inc]}
> DEBUG: Providers Listed By Protocol:
> {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Sun
> Microsystems, Inc],
> imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun
> Microsystems, Inc],
> smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Sun
> Microsystems, Inc],
> pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun
> Microsystems, Inc],
> pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Sun
> Microsystems, Inc],
> smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun
> Microsystems, Inc]}
> DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
> DEBUG: getProvider() returning
> javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun
> Microsystems, Inc]
> DEBUG SMTP: useEhlo true, useAuth true
> DEBUG SMTP: trying to connect to host "localhost", port 25, isSSL false
> 220-vps.qpainformatica.com.br ESMTP Exim 4.80 #2 Thu, 23 May 2013
> 11:52:11 -0300
> 220-We do not authorize the use of this system to transport unsolicited,
> 220 and/or bulk e-mail.
> DEBUG SMTP: connected to host "localhost", port: 25
>
> EHLO vps.qpainformatica.com.br
> 250-vps.qpainformatica.com.br Hello localhost [127.0.0.1]
> 250-SIZE 52428800
> 250-8BITMIME
> 250-PIPELINING
> 250-AUTH PLAIN LOGIN
> 250-STARTTLS
> 250 HELP
> DEBUG SMTP: Found extension "SIZE", arg "52428800"
> DEBUG SMTP: Found extension "8BITMIME", arg ""
> DEBUG SMTP: Found extension "PIPELINING", arg ""
> DEBUG SMTP: Found extension "AUTH", arg "PLAIN LOGIN"
> DEBUG SMTP: Found extension "STARTTLS", arg ""
> DEBUG SMTP: Found extension "HELP", arg ""
> DEBUG SMTP: Attempt to authenticate
> DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
> AUTH LOGIN
> 334 VXNlcm5hbWU6
> YXZhQHFwYWluZm9ybWF0aWNhLmNvbS5iciA=
> 535 Incorrect authentication data
> 2013-05-23 11:52:13,265  WARN http-bio-127.0.0.1-4494-exec-10
> org.sakaiproject.email.impl.BasicEmailService - Email.sendMail: exception:
> 535 Incorrect authentication data
>
> javax.mail.AuthenticationFailedException: 535 Incorrect authentication data
>
>     at
> com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:809)
>     at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:752)
>     at
> com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:669)
>     at javax.mail.Service.connect(Service.java:295)
>     at javax.mail.Service.connect(Service.java:176)
>     at
> org.sakaiproject.email.impl.BasicEmailService.sendMessageAndLog(BasicEmailService.java:1290)
>     at
> org.sakaiproject.email.impl.BasicEmailService.sendMail(BasicEmailService.java:601)
>     at
> org.sakaiproject.email.impl.BasicEmailService.send(BasicEmailService.java:1012)
>     at
> org.sakaiproject.mailsender.logic.impl.ExternalLogicImpl.sendEmail(ExternalLogicImpl.java:412)
>     at
> org.sakaiproject.mailsender.tool.beans.EmailBean.sendEmail(EmailBean.java:221)
>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>     at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>     at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>     at java.lang.reflect.Method.invoke(Method.java:601)
>     at
> uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:23)
>     at
> uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:17)
>     at
> uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:77)
>     at
> uk.org.ponder.reflect.ReflectiveCache.invokeMethod(ReflectiveCache.java:141)
>     at
> uk.org.ponder.mapping.support.DARApplier.invokeBeanMethod(DARApplier.java:179)
>     at
> uk.org.ponder.rsf.state.support.RSVCApplier.invokeAction(RSVCApplier.java:218)
>     at
> uk.org.ponder.rsf.processor.support.RSFActionHandler$1.run(RSFActionHandler.java:189)
>     at
> uk.org.ponder.util.CollectingRunnableInvoker$1.run(CollectingRunnableInvoker.java:25)
>     at
> uk.org.ponder.rsf.flow.support.BasicScopedAlterationWrapper.invokeRunnable(BasicScopedAlterationWrapper.java:59)
>     at
> uk.org.ponder.rsf.flow.support.BasicScopedAlterationWrapper$$FastClassByCGLIB$$84f89202.invoke(<generated>)
>     at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
>     at
> org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:628)
>     at
> uk.org.ponder.rsf.flow.support.BasicScopedAlterationWrapper$$EnhancerByCGLIB$$100f0a2f.invokeRunnable(<generated>)
>     at
> uk.org.ponder.rsf.flow.support.BasicScopedAlterationWrapper$$FastClassByCGLIB$$84f89202.invoke(<generated>)
>     at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
>     at
> org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:628)
>     at
> uk.org.ponder.rsf.flow.support.BasicScopedAlterationWrapper$$EnhancerByCGLIB$$100f0a2f.invokeRunnable(<generated>)
>     at
> uk.org.ponder.util.CollectingRunnableInvoker$1.run(CollectingRunnableInvoker.java:29)
>     at
> uk.org.ponder.util.CollectingRunnableInvoker.invokeWrappers(CollectingRunnableInvoker.java:22)
>     at
> uk.org.ponder.util.CollectingRunnableInvoker.invokeRunnable(CollectingRunnableInvoker.java:14)
>     at
> uk.org.ponder.rsf.processor.support.RSFActionHandler.handle(RSFActionHandler.java:165)
>     at
> uk.org.ponder.rsf.processor.support.RSFActionHandler$$FastClassByCGLIB$$e3b6899d.invoke(<generated>)
>     at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
>     at
> org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:628)
>     at
> uk.org.ponder.rsf.processor.support.RSFActionHandler$$EnhancerByCGLIB$$a3edfaa8.handle(<generated>)
>     at
> uk.org.ponder.rsf.processor.support.RootHandlerBeanBase.handlePost(RootHandlerBeanBase.java:125)
>     at
> uk.org.ponder.rsf.processor.support.RootHandlerBeanBase.handle(RootHandlerBeanBase.java:82)
>     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>     at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>     at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>     at java.lang.reflect.Method.invoke(Method.java:601)
>     at
> uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:23)
>     at
> uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:17)
>     at
> uk.org.ponder.reflect.JDKReflectiveCache.invokeMethod(JDKReflectiveCache.java:77)
>     at
> uk.org.ponder.rsac.support.RSACBeanLocatorImpl.createBean(RSACBeanLocatorImpl.java:553)
>     at
> uk.org.ponder.rsac.support.RSACBeanLocatorImpl.access$000(RSACBeanLocatorImpl.java:75)
>     at
> uk.org.ponder.rsac.support.RSACBeanLocatorImpl$1.run(RSACBeanLocatorImpl.java:449)
>     at
> uk.org.ponder.rsac.RSACErrorBridge.invokeRunnable(RSACErrorBridge.java:38)
>     at
> uk.org.ponder.rsac.support.RSACBeanLocatorImpl.createBean(RSACBeanLocatorImpl.java:447)
>     at
> uk.org.ponder.rsac.support.RSACBeanLocatorImpl.getLocalBean(RSACBeanLocatorImpl.java:348)
>     at
> uk.org.ponder.rsac.support.RSACBeanLocatorImpl.getBean(RSACBeanLocatorImpl.java:379)
>     at
> uk.org.ponder.rsac.support.PerRequestInfo$1.locateBean(PerRequestInfo.java:49)
>     at
> uk.ac.cam.caret.sakai.rsf.servlet.ReasonableSakaiServlet.service(ReasonableSakaiServlet.java:65)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>     at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
>     at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>     at org.sakaiproject.util.RequestFilter.doFilter(RequestFilter.java:634)
>     at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
>     at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>     at
> org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
>     at
> org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
>     at
> org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:379)
>     at
> org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
>     at
> org.sakaiproject.tool.impl.ActiveToolComponent$MyActiveTool.forward(ActiveToolComponent.java:511)
>     at
> org.sakaiproject.portal.charon.SkinnableCharonPortal.forwardTool(SkinnableCharonPortal.java:1470)
>     at
> org.sakaiproject.portal.charon.handlers.ToolHandler.doTool(ToolHandler.java:213)
>     at
> org.sakaiproject.portal.charon.handlers.ToolHandler.doGet(ToolHandler.java:96)
>     at
> org.sakaiproject.portal.charon.handlers.ToolHandler.doPost(ToolHandler.java:73)
>     at
> org.sakaiproject.portal.charon.SkinnableCharonPortal.doPost(SkinnableCharonPortal.java:1260)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>     at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
>     at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>     at org.sakaiproject.util.RequestFilter.doFilter(RequestFilter.java:695)
>     at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
>     at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>     at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
>     at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
>     at
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
>     at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
>     at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
>     at
> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
>     at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>     at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
>     at
> org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
>     at
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
>     at
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
>     at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
>     at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
>     at java.lang.Thread.run(Thread.java:722)
> ------------------------------------ end of error log file
>
> ---------------------------SendMail test APP:
> /*
>  * To change this template, choose Tools | Templates
>  * and open the template in the editor.
>  */
> package br.com.qpainformatica.sendmail;
>
> import java.io.*;
> import java.net.*;
>
> import java.util.Properties;
> import javax.mail.AuthenticationFailedException;
> import javax.mail.Authenticator;
> import javax.mail.PasswordAuthentication;
> import javax.mail.Message;
> import javax.mail.MessagingException;
> import javax.mail.Session;
> import javax.mail.Transport;
> import javax.mail.internet.AddressException;
> import javax.mail.internet.InternetAddress;
> import javax.mail.internet.MimeMessage;
> import javax.servlet.*;
> import javax.servlet.http.*;
>
> public class EmailServlet extends HttpServlet {
>
>     protected void processRequest(HttpServletRequest request,
>                                   HttpServletResponse response)
>                    throws IOException, ServletException {
>
>         final String err = "/error.jsp";
>         final String succ = "/success.jsp";
>
>         String from = request.getParameter("from");
>         String to = request.getParameter("to");
>         String subject = request.getParameter("subject");
>         String message = request.getParameter("message");
>         String login = request.getParameter("login");
>         String password = request.getParameter("password");
>
>         try {
>             Properties props = new Properties();
>             props.setProperty("mail.host", "localhost");
>             props.setProperty("mail.smtp.port", "25");
>             props.setProperty("mail.smtp.auth", "true");
>             props.setProperty("mail.smtp.starttls.enable", "false");
>
>             Authenticator auth = new SMTPAuthenticator(login, password);
>
>             Session session = Session.getInstance(props, auth);
>
>             MimeMessage msg = new MimeMessage(session);
>             msg.setText(message);
>             msg.setSubject(subject);
>             msg.setFrom(new InternetAddress(from));
>             msg.addRecipient(Message.RecipientType.TO, new
> InternetAddress(to));
>             Transport.send(msg);
>
>         } catch (AuthenticationFailedException ex) {
>             request.setAttribute("ErrorMessage", "Authentication failed");
>
>             RequestDispatcher dispatcher =
> request.getRequestDispatcher(err);
>             dispatcher.forward(request, response);
>             return;
>
>         } catch (AddressException ex) {
>             request.setAttribute("ErrorMessage", "Wrong email address");
>
>             RequestDispatcher dispatcher =
> request.getRequestDispatcher(err);
>             dispatcher.forward(request, response);
>             return;
>
>         } catch (MessagingException ex) {
>             request.setAttribute("ErrorMessage", ex.getMessage());
>
>             RequestDispatcher dispatcher =
> request.getRequestDispatcher(err);
>             dispatcher.forward(request, response);
>             return;
>         }
>             RequestDispatcher dispatcher =
> request.getRequestDispatcher(succ);
>             dispatcher.forward(request, response);
>
>     }
>
>     private class SMTPAuthenticator extends Authenticator {
>
>         private PasswordAuthentication authentication;
>
>         public SMTPAuthenticator(String login, String password) {
>             authentication = new PasswordAuthentication(login, password);
>         }
>
>         protected PasswordAuthentication getPasswordAuthentication() {
>             return authentication;
>         }
>     }
>
>     protected void doGet(HttpServletRequest request,
>                          HttpServletResponse response)
>                    throws ServletException, IOException {
>         processRequest(request, response);
>     }
>
>     protected void doPost(HttpServletRequest request,
>                           HttpServletResponse response)
>                    throws ServletException, IOException {
>         processRequest(request, response);
>     }
> }
> -------------------- end
>
>
>
> _______________________________________________
> sakai-dev mailing list
> sakai-dev at collab.sakaiproject.org
> http://collab.sakaiproject.org/mailman/listinfo/sakai-dev
>
> TO UNSUBSCRIBE: send email to
> sakai-dev-unsubscribe at collab.sakaiproject.org with a subject of
> "unsubscribe"
>



-- 
  Matthew Buckett, VLE Developer, IT Services, University of Oxford
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://collab.sakaiproject.org/pipermail/sakai-dev/attachments/20130523/33ab5ea4/attachment.html 


More information about the sakai-dev mailing list