1 17 18 package org.apache.james.smtpserver; 19 20 import org.apache.avalon.cornerstone.services.connection.ConnectionHandler; 21 import org.apache.avalon.excalibur.pool.DefaultPool; 22 import org.apache.avalon.excalibur.pool.HardResourceLimitingPool; 23 import org.apache.avalon.excalibur.pool.ObjectFactory; 24 import org.apache.avalon.excalibur.pool.Pool; 25 import org.apache.avalon.excalibur.pool.Poolable; 26 import org.apache.avalon.framework.activity.Disposable; 27 import org.apache.avalon.framework.activity.Initializable; 28 import org.apache.avalon.framework.component.ComponentException; 29 import org.apache.avalon.framework.component.ComponentManager; 30 import org.apache.avalon.framework.configuration.Configuration; 31 import org.apache.avalon.framework.configuration.ConfigurationException; 32 import org.apache.avalon.framework.component.Component; 33 import org.apache.avalon.framework.activity.Disposable; 34 import org.apache.avalon.framework.logger.LogEnabled; 35 import org.apache.james.Constants; 36 import org.apache.james.core.AbstractJamesService; 37 import org.apache.james.services.MailServer; 38 import org.apache.james.services.UsersRepository; 39 import org.apache.james.services.UsersStore; 40 import org.apache.james.util.NetMatcher; 41 import org.apache.james.util.watchdog.Watchdog; 42 import org.apache.james.util.watchdog.WatchdogFactory; 43 import org.apache.mailet.MailetContext; 44 45 52 56 public class SMTPServer extends AbstractJamesService implements Component, SMTPServerMBean { 57 58 61 MailetContext mailetcontext; 62 63 67 private UsersRepository users; 68 69 72 private MailServer mailServer; 73 74 78 private boolean authRequired = false; 79 80 86 private boolean verifyIdentity = false; 87 88 92 private NetMatcher authorizedNetworks = null; 93 94 98 private long maxMessageSize = 0; 99 100 105 private int lengthReset = 20 * 1024; 106 107 110 private Pool theHandlerPool = null; 111 112 115 private ObjectFactory theHandlerFactory = new SMTPHandlerFactory(); 116 117 120 private WatchdogFactory theWatchdogFactory; 121 122 125 private SMTPHandlerConfigurationData theConfigData 126 = new SMTPHandlerConfigurationDataImpl(); 127 128 131 public void compose(final ComponentManager componentManager) throws ComponentException { 132 super.compose(componentManager); 133 mailetcontext = (MailetContext) componentManager.lookup("org.apache.mailet.MailetContext"); 134 mailServer = (MailServer) componentManager.lookup("org.apache.james.services.MailServer"); 135 UsersStore usersStore = 136 (UsersStore) componentManager.lookup("org.apache.james.services.UsersStore"); 137 users = usersStore.getRepository("LocalUsers"); 138 if (users == null) { 139 throw new ComponentException("The user repository could not be found."); 140 } 141 } 142 143 146 public void configure(final Configuration configuration) throws ConfigurationException { 147 super.configure(configuration); 148 if (isEnabled()) { 149 mailetcontext.setAttribute(Constants.HELLO_NAME, helloName); 150 Configuration handlerConfiguration = configuration.getChild("handler"); 151 authRequired = handlerConfiguration.getChild("authRequired").getValueAsBoolean(false); 152 verifyIdentity = handlerConfiguration.getChild("verifyIdentity").getValueAsBoolean(false); 153 if (authRequired) { 154 if (verifyIdentity) { 155 getLogger().info("This SMTP server requires authentication and verifies that the authentication credentials match the sender address."); 156 } else { 157 getLogger().info("This SMTP server requires authentication, but doesn't verify that the authentication credentials match the sender address."); 158 } 159 } else { 160 getLogger().info("This SMTP server does not require authentication."); 161 } 162 163 String authorizedAddresses = handlerConfiguration.getChild("authorizedAddresses").getValue(null); 164 if (!authRequired && authorizedAddresses == null) { 165 179 authorizedAddresses = "0.0.0.0/0.0.0.0"; 180 } 181 182 if (authorizedAddresses != null) { 183 java.util.StringTokenizer st = new java.util.StringTokenizer (authorizedAddresses, ", ", false); 184 java.util.Collection networks = new java.util.ArrayList (); 185 while (st.hasMoreTokens()) { 186 String addr = st.nextToken(); 187 networks.add(addr); 188 } 189 authorizedNetworks = new NetMatcher(networks); 190 } 191 192 if (authorizedNetworks != null) { 193 getLogger().info("Authorized addresses: " + authorizedNetworks.toString()); 194 } 195 196 maxMessageSize = handlerConfiguration.getChild( "maxmessagesize" ).getValueAsLong( maxMessageSize ) * 1024; 199 if (maxMessageSize > 0) { 200 getLogger().info("The maximum allowed message size is " + maxMessageSize + " bytes."); 201 } else { 202 getLogger().info("No maximum message size is enforced for this server."); 203 } 204 lengthReset = configuration.getChild("lengthReset").getValueAsInteger(lengthReset); 206 if (lengthReset <= 0) { 207 throw new ConfigurationException("The configured value for the idle timeout reset, " + lengthReset + ", is not valid."); 208 } 209 if (getLogger().isInfoEnabled()) { 210 getLogger().info("The idle timeout will be reset every " + lengthReset + " bytes."); 211 } 212 } else { 213 mailetcontext.setAttribute(Constants.HELLO_NAME, "localhost"); 214 } 215 } 216 217 220 public void initialize() throws Exception { 221 super.initialize(); 222 if (!isEnabled()) { 223 return; 224 } 225 226 if (connectionLimit != null) { 227 theHandlerPool = new HardResourceLimitingPool(theHandlerFactory, 5, connectionLimit.intValue()); 228 if (getLogger().isDebugEnabled()) { 229 getLogger().debug("Using a bounded pool for SMTP handlers with upper limit " + connectionLimit.intValue()); 230 } 231 } else { 232 theHandlerPool = new DefaultPool(theHandlerFactory, null, 5, 30); 235 getLogger().debug("Using an unbounded pool for SMTP handlers."); 236 } 237 if (theHandlerPool instanceof LogEnabled) { 238 ((LogEnabled)theHandlerPool).enableLogging(getLogger()); 239 } 240 if (theHandlerPool instanceof Initializable) { 241 ((Initializable)theHandlerPool).initialize(); 242 } 243 244 theWatchdogFactory = getWatchdogFactory(); 245 } 246 247 250 protected int getDefaultPort() { 251 return 25; 252 } 253 254 257 public String getServiceType() { 258 return "SMTP Service"; 259 } 260 261 264 protected ConnectionHandler newHandler() 265 throws Exception { 266 SMTPHandler theHandler = (SMTPHandler)theHandlerPool.get(); 267 268 if (getLogger().isDebugEnabled()) { 269 getLogger().debug("Getting SMTPHandler from pool."); 270 } 271 Watchdog theWatchdog = theWatchdogFactory.getWatchdog(theHandler.getWatchdogTarget()); 272 273 theHandler.setConfigurationData(theConfigData); 274 275 theHandler.setWatchdog(theWatchdog); 276 return theHandler; 277 } 278 279 282 public void releaseConnectionHandler( ConnectionHandler connectionHandler ) { 283 if (!(connectionHandler instanceof SMTPHandler)) { 284 throw new IllegalArgumentException ("Attempted to return non-SMTPHandler to pool."); 285 } 286 if (getLogger().isDebugEnabled()) { 287 getLogger().debug("Returning SMTPHandler to pool."); 288 } 289 theHandlerPool.put((Poolable)connectionHandler); 290 } 291 292 295 private static class SMTPHandlerFactory 296 implements ObjectFactory { 297 298 301 public Object newInstance() throws Exception { 302 return new SMTPHandler(); 303 } 304 305 308 public Class getCreatedClass() { 309 return SMTPHandler.class; 310 } 311 312 315 public void decommission( Object object ) throws Exception { 316 return; 317 } 318 } 319 320 323 private class SMTPHandlerConfigurationDataImpl 324 implements SMTPHandlerConfigurationData { 325 326 329 public String getHelloName() { 330 return SMTPServer.this.helloName; 331 } 332 333 336 public int getResetLength() { 337 return SMTPServer.this.lengthReset; 338 } 339 340 343 public long getMaxMessageSize() { 344 return SMTPServer.this.maxMessageSize; 345 } 346 347 350 public boolean isRelayingAllowed(String remoteIP) { 351 boolean relayingAllowed = false; 352 if (authorizedNetworks != null) { 353 relayingAllowed = SMTPServer.this.authorizedNetworks.matchInetNetwork(remoteIP); 354 } 355 return relayingAllowed; 356 } 357 358 361 public boolean isAuthRequired(String remoteIP) { 362 boolean authRequired = SMTPServer.this.authRequired; 363 if (authorizedNetworks != null) { 364 authRequired = authRequired && !SMTPServer.this.authorizedNetworks.matchInetNetwork(remoteIP); 365 } 366 return authRequired; 367 } 368 369 372 public boolean isAuthRequired() { 373 return SMTPServer.this.authRequired; 374 } 375 376 379 public boolean isVerifyIdentity() { 380 return SMTPServer.this.verifyIdentity; 381 } 382 383 386 public MailServer getMailServer() { 387 return SMTPServer.this.mailServer; 388 } 389 390 393 public UsersRepository getUsersRepository() { 394 return SMTPServer.this.users; 395 } 396 } 397 } 398 | Popular Tags |