Klaus Demo nginx / 5fbe121
optimizations Igor Sysoev 14 years ago
6 changed file(s) with 230 addition(s) and 262 deletion(s). Raw diff Collapse all Expand all
312312
313313 #if (NGX_MAIL_SSL)
314314 void ngx_mail_starttls_handler(ngx_event_t *rev);
315 ngx_int_t ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c);
315316 #endif
316317
317318
329330 ngx_connection_t *c);
330331 ngx_int_t ngx_mail_auth_login_password(ngx_mail_session_t *s,
331332 ngx_connection_t *c);
333 ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s,
334 ngx_connection_t *c, char *prefix, size_t len);
332335 ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c);
333336
334337 void ngx_mail_send(ngx_event_t *wev);
350353 ngx_int_t ngx_mail_pop3_parse_command(ngx_mail_session_t *s);
351354 ngx_int_t ngx_mail_imap_parse_command(ngx_mail_session_t *s);
352355 ngx_int_t ngx_mail_smtp_parse_command(ngx_mail_session_t *s);
356 ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c);
353357
354358
355359 /* STUB */
284284 }
285285
286286
287 #if (NGX_MAIL_SSL)
288
289 ngx_int_t
290 ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c)
291 {
292 ngx_mail_ssl_conf_t *sslcf;
293
294 if (c->ssl) {
295 return 0;
296 }
297
298 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
299
300 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
301 return 1;
302 }
303
304 return 0;
305 }
306
307 #endif
308
309
287310 ngx_int_t
288311 ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
289312 {
400423 #endif
401424
402425 return NGX_DONE;
426 }
427
428
429 ngx_int_t
430 ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c,
431 char *prefix, size_t len)
432 {
433 u_char *p;
434 ngx_str_t salt;
435 ngx_uint_t n;
436
437 p = ngx_palloc(c->pool, len + ngx_base64_encoded_length(s->salt.len) + 2);
438 if (p == NULL) {
439 return NGX_ERROR;
440 }
441
442 salt.data = ngx_cpymem(p, prefix, len);
443 s->salt.len -= 2;
444
445 ngx_encode_base64(&salt, &s->salt);
446
447 s->salt.len += 2;
448 n = len + salt.len;
449 p[n++] = CR; p[n++] = LF;
450
451 s->out.len = n;
452 s->out.data = p;
453
454 return NGX_OK;
403455 }
404456
405457
176176
177177 case NGX_IMAP_AUTHENTICATE:
178178 rc = ngx_mail_imap_authenticate(s, c);
179
180 if (rc == NGX_OK) {
181 tag = 0;
182 }
183
179 tag = (rc != NGX_OK);
184180 break;
185181
186182 case NGX_IMAP_CAPABILITY:
306302 ngx_mail_imap_login(ngx_mail_session_t *s, ngx_connection_t *c)
307303 {
308304 ngx_str_t *arg;
305
309306 #if (NGX_MAIL_SSL)
310 ngx_mail_ssl_conf_t *sslcf;
311
312 if (c->ssl == NULL) {
313 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
314
315 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
316 return NGX_MAIL_PARSE_INVALID_COMMAND;
317 }
307 if (ngx_mail_starttls_only(s, c)) {
308 return NGX_MAIL_PARSE_INVALID_COMMAND;
318309 }
319310 #endif
320311
356347 static ngx_int_t
357348 ngx_mail_imap_authenticate(ngx_mail_session_t *s, ngx_connection_t *c)
358349 {
359 u_char *p;
360 ngx_str_t *arg, salt;
361 ngx_uint_t n;
350 ngx_int_t rc;
362351 ngx_mail_core_srv_conf_t *cscf;
352
363353 #if (NGX_MAIL_SSL)
364 ngx_mail_ssl_conf_t *sslcf;
365
366 if (c->ssl == NULL) {
367 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
368
369 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
370 return NGX_MAIL_PARSE_INVALID_COMMAND;
371 }
372 }
373 #endif
374
375 if (s->args.nelts != 1) {
354 if (ngx_mail_starttls_only(s, c)) {
376355 return NGX_MAIL_PARSE_INVALID_COMMAND;
377356 }
378
379 arg = s->args.elts;
380
381 if (arg[0].len == 5) {
382
383 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
384
385 s->out.len = sizeof(imap_username) - 1;
386 s->out.data = imap_username;
387 s->mail_state = ngx_imap_auth_login_username;
388
389 return NGX_OK;
390
391 } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
392
393 s->out.len = sizeof(imap_plain_next) - 1;
394 s->out.data = imap_plain_next;
395 s->mail_state = ngx_imap_auth_plain;
396
397 return NGX_OK;
398 }
399
400 } else if (arg[0].len == 8
401 && ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0)
402 {
403 if (s->args.nelts != 1) {
404 return NGX_MAIL_PARSE_INVALID_COMMAND;
405 }
357 #endif
358
359 rc = ngx_mail_auth_parse(s, c);
360
361 switch (rc) {
362
363 case NGX_MAIL_AUTH_LOGIN:
364
365 s->out.len = sizeof(imap_username) - 1;
366 s->out.data = imap_username;
367 s->mail_state = ngx_imap_auth_login_username;
368
369 return NGX_OK;
370
371 case NGX_MAIL_AUTH_PLAIN:
372
373 s->out.len = sizeof(imap_plain_next) - 1;
374 s->out.data = imap_plain_next;
375 s->mail_state = ngx_imap_auth_plain;
376
377 return NGX_OK;
378
379 case NGX_MAIL_AUTH_CRAM_MD5:
406380
407381 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
408382
410384 return NGX_MAIL_PARSE_INVALID_COMMAND;
411385 }
412386
413 p = ngx_palloc(c->pool,
414 sizeof("+ " CRLF) - 1
415 + ngx_base64_encoded_length(s->salt.len));
416 if (p == NULL) {
417 return NGX_ERROR;
418 }
419
420 p[0] = '+'; p[1]= ' ';
421 salt.data = &p[2];
422 s->salt.len -= 2;
423
424 ngx_encode_base64(&salt, &s->salt);
425
426 s->salt.len += 2;
427 n = 2 + salt.len;
428 p[n++] = CR; p[n++] = LF;
429
430 s->out.len = n;
431 s->out.data = p;
432 s->mail_state = ngx_imap_auth_cram_md5;
433
434 return NGX_OK;
435 }
436
437 return NGX_MAIL_PARSE_INVALID_COMMAND;
387 if (ngx_mail_auth_cram_md5_salt(s, c, "+ ", 2) == NGX_OK) {
388 s->mail_state = ngx_imap_auth_cram_md5;
389 return NGX_OK;
390 }
391
392 return NGX_ERROR;
393 }
394
395 return rc;
438396 }
439397
440398
824824
825825 return NGX_MAIL_PARSE_INVALID_COMMAND;
826826 }
827
828
829 ngx_int_t
830 ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c)
831 {
832 ngx_str_t *arg;
833
834 #if (NGX_MAIL_SSL)
835 if (ngx_mail_starttls_only(s, c)) {
836 return NGX_MAIL_PARSE_INVALID_COMMAND;
837 }
838 #endif
839
840 arg = s->args.elts;
841
842 if (arg[0].len == 5) {
843
844 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
845
846 if (s->args.nelts == 1) {
847 return NGX_MAIL_AUTH_LOGIN;
848 }
849
850 return NGX_MAIL_PARSE_INVALID_COMMAND;
851 }
852
853 if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
854
855 if (s->args.nelts == 1) {
856 return NGX_MAIL_AUTH_PLAIN;
857 }
858
859 if (s->args.nelts == 2) {
860 return ngx_mail_auth_plain(s, c, 1);
861 }
862 }
863
864 return NGX_MAIL_PARSE_INVALID_COMMAND;
865 }
866
867 if (arg[0].len == 8) {
868
869 if (s->args.nelts != 1) {
870 return NGX_MAIL_PARSE_INVALID_COMMAND;
871 }
872
873 if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) {
874 return NGX_MAIL_AUTH_CRAM_MD5;
875 }
876 }
877
878 return NGX_MAIL_PARSE_INVALID_COMMAND;
879 }
274274 ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c)
275275 {
276276 ngx_str_t *arg;
277 #if (NGX_MAIL_SSL)
278 ngx_mail_ssl_conf_t *sslcf;
279
280 if (c->ssl == NULL) {
281 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
282
283 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
284 return NGX_MAIL_PARSE_INVALID_COMMAND;
285 }
286 }
287
277
278 #if (NGX_MAIL_SSL)
279 if (ngx_mail_starttls_only(s, c)) {
280 return NGX_MAIL_PARSE_INVALID_COMMAND;
281 }
288282 #endif
289283
290284 if (s->args.nelts != 1) {
394388 {
395389 ngx_str_t *arg;
396390 ngx_mail_core_srv_conf_t *cscf;
397 #if (NGX_MAIL_SSL)
398 ngx_mail_ssl_conf_t *sslcf;
399
400 if (c->ssl == NULL) {
401 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
402
403 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
404 return NGX_MAIL_PARSE_INVALID_COMMAND;
405 }
406 }
407
391
392 #if (NGX_MAIL_SSL)
393 if (ngx_mail_starttls_only(s, c)) {
394 return NGX_MAIL_PARSE_INVALID_COMMAND;
395 }
408396 #endif
409397
410398 if (s->args.nelts != 2) {
447435 static ngx_int_t
448436 ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c)
449437 {
450 size_t n;
451 u_char *p;
452 ngx_str_t *arg, salt;
438 ngx_int_t rc;
453439 ngx_mail_core_srv_conf_t *cscf;
454 #if (NGX_MAIL_SSL)
455 ngx_mail_ssl_conf_t *sslcf;
456
457 if (c->ssl == NULL) {
458 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
459
460 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
461 return NGX_MAIL_PARSE_INVALID_COMMAND;
462 }
463 }
464
440
441 #if (NGX_MAIL_SSL)
442 if (ngx_mail_starttls_only(s, c)) {
443 return NGX_MAIL_PARSE_INVALID_COMMAND;
444 }
465445 #endif
466446
467447 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
473453 return NGX_OK;
474454 }
475455
476 arg = s->args.elts;
477
478 if (arg[0].len == 5) {
479
480 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
481
482 if (s->args.nelts != 1) {
483 return NGX_MAIL_PARSE_INVALID_COMMAND;
484 }
485
486 s->out.len = sizeof(pop3_username) - 1;
487 s->out.data = pop3_username;
488 s->mail_state = ngx_pop3_auth_login_username;
489
490 return NGX_OK;
491
492 } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
493
494 if (s->args.nelts == 1) {
495
496 s->out.len = sizeof(pop3_next) - 1;
497 s->out.data = pop3_next;
498 s->mail_state = ngx_pop3_auth_plain;
499
500 return NGX_OK;
501 }
502
503 if (s->args.nelts == 2) {
504
505 /*
506 * workaround for Eudora for Mac: it sends
507 * AUTH PLAIN [base64 encoded]
508 */
509
510 return ngx_mail_auth_plain(s, c, 1);
511 }
512
513 return NGX_MAIL_PARSE_INVALID_COMMAND;
514 }
515
516 } else if (arg[0].len == 8
517 && ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0)
518 {
519 if (s->args.nelts != 1) {
520 return NGX_MAIL_PARSE_INVALID_COMMAND;
521 }
456 rc = ngx_mail_auth_parse(s, c);
457
458 switch (rc) {
459
460 case NGX_MAIL_AUTH_LOGIN:
461
462 s->out.len = sizeof(pop3_username) - 1;
463 s->out.data = pop3_username;
464 s->mail_state = ngx_pop3_auth_login_username;
465
466 return NGX_OK;
467
468 case NGX_MAIL_AUTH_PLAIN:
469
470 s->out.len = sizeof(pop3_next) - 1;
471 s->out.data = pop3_next;
472 s->mail_state = ngx_pop3_auth_plain;
473
474 return NGX_OK;
475
476 case NGX_MAIL_AUTH_CRAM_MD5:
522477
523478 if (!(cscf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
524479 return NGX_MAIL_PARSE_INVALID_COMMAND;
525480 }
526481
527 p = ngx_palloc(c->pool,
528 sizeof("+ " CRLF) - 1
529 + ngx_base64_encoded_length(s->salt.len));
530 if (p == NULL) {
531 return NGX_ERROR;
532 }
533
534 p[0] = '+'; p[1]= ' ';
535 salt.data = &p[2];
536 s->salt.len -= 2;
537
538 ngx_encode_base64(&salt, &s->salt);
539
540 s->salt.len += 2;
541 n = 2 + salt.len;
542 p[n++] = CR; p[n++] = LF;
543
544 s->out.len = n;
545 s->out.data = p;
546 s->mail_state = ngx_pop3_auth_cram_md5;
547
548 return NGX_OK;
549 }
550
551 return NGX_MAIL_PARSE_INVALID_COMMAND;
552 }
482 if (ngx_mail_auth_cram_md5_salt(s, c, "+ ", 2) == NGX_OK) {
483 s->mail_state = ngx_pop3_auth_cram_md5;
484 return NGX_OK;
485 }
486
487 return NGX_ERROR;
488 }
489
490 return rc;
491 }
283283 static ngx_int_t
284284 ngx_mail_smtp_auth(ngx_mail_session_t *s, ngx_connection_t *c)
285285 {
286 u_char *p;
287 ngx_str_t *arg, salt;
288 ngx_uint_t n;
286 ngx_int_t rc;
289287 ngx_mail_core_srv_conf_t *cscf;
288
290289 #if (NGX_MAIL_SSL)
291 ngx_mail_ssl_conf_t *sslcf;
292
293 if (c->ssl == NULL) {
294 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
295
296 if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
297 return NGX_MAIL_PARSE_INVALID_COMMAND;
298 }
299 }
300
290 if (ngx_mail_starttls_only(s, c)) {
291 return NGX_MAIL_PARSE_INVALID_COMMAND;
292 }
301293 #endif
302294
303295 if (s->args.nelts == 0) {
307299 return NGX_OK;
308300 }
309301
310 if (s->args.nelts != 1) {
311 return NGX_MAIL_PARSE_INVALID_COMMAND;
312 }
313
314 arg = s->args.elts;
315
316 if (arg[0].len == 5) {
317
318 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
319
320 if (s->args.nelts != 1) {
321 return NGX_MAIL_PARSE_INVALID_COMMAND;
322 }
323
324 s->out.len = sizeof(smtp_username) - 1;
325 s->out.data = smtp_username;
326 s->mail_state = ngx_smtp_auth_login_username;
327
328 return NGX_OK;
329
330 } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
331
332 s->out.len = sizeof(smtp_next) - 1;
333 s->out.data = smtp_next;
334 s->mail_state = ngx_smtp_auth_plain;
335
336 return NGX_OK;
337 }
338
339 } else if (arg[0].len == 8
340 && ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0)
341 {
342 if (s->args.nelts != 1) {
343 return NGX_MAIL_PARSE_INVALID_COMMAND;
344 }
302 rc = ngx_mail_auth_parse(s, c);
303
304 switch (rc) {
305
306 case NGX_MAIL_AUTH_LOGIN:
307
308 s->out.len = sizeof(smtp_username) - 1;
309 s->out.data = smtp_username;
310 s->mail_state = ngx_smtp_auth_login_username;
311
312 return NGX_OK;
313
314 case NGX_MAIL_AUTH_PLAIN:
315
316 s->out.len = sizeof(smtp_next) - 1;
317 s->out.data = smtp_next;
318 s->mail_state = ngx_smtp_auth_plain;
319
320 return NGX_OK;
321
322 case NGX_MAIL_AUTH_CRAM_MD5:
345323
346324 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
347325
349327 return NGX_MAIL_PARSE_INVALID_COMMAND;
350328 }
351329
352 p = ngx_palloc(c->pool,
353 sizeof("334 " CRLF) - 1
354 + ngx_base64_encoded_length(s->salt.len));
355 if (p == NULL) {
356 return NGX_ERROR;
357 }
358
359 p[0] = '3'; p[1]= '3'; p[2] = '4'; p[3]= ' ';
360 salt.data = &p[4];
361 s->salt.len -= 2;
362
363 ngx_encode_base64(&salt, &s->salt);
364
365 s->salt.len += 2;
366 n = 4 + salt.len;
367 p[n++] = CR; p[n++] = LF;
368
369 s->out.len = n;
370 s->out.data = p;
371 s->mail_state = ngx_smtp_auth_cram_md5;
372
373 return NGX_OK;
374 }
375
376 return NGX_MAIL_PARSE_INVALID_COMMAND;
330 if (ngx_mail_auth_cram_md5_salt(s, c, "334 ", 4) == NGX_OK) {
331 s->mail_state = ngx_smtp_auth_cram_md5;
332 return NGX_OK;
333 }
334
335 return NGX_ERROR;
336 }
337
338 return rc;
377339 }
378340
379341