Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

swh:1:snp:158a3f36b0bd3da461fb7458de44cfa2c94e4270
  • Code
  • Branches (0)
  • Releases (20)
    • Branches
    • Releases
      • 1.18.0-6ubuntu14.1
      • 1.18.0-6ubuntu14
      • 1.18.0-6ubuntu11.1
      • 1.18.0-6ubuntu11
      • 1.18.0-6ubuntu8.2
      • 1.18.0-6ubuntu8
      • 1.18.0-0ubuntu1.3
      • 1.17.10-0ubuntu1
      • 1.14.0-0ubuntu1.10
      • 1.10.3-0ubuntu0.16.04.5
      • 1.9.15-0ubuntu1
      • 1.4.6-1ubuntu3.9
      • 1.4.6-1ubuntu3
    • 8a09c6d
    • /
    • src
    • /
    • mail
    • /
    • ngx_mail_pop3_handler.c
    Raw File Download

    To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
    Select below a type of object currently browsed in order to display its associated SWHID and permalink.

    • content
    • directory
    • snapshot
    • release
    content badge
    swh:1:cnt:9310c2750f44aaa4828be00aafd3c80ac4582dcf
    directory badge
    swh:1:dir:ea789ae195f6ab23d5fb34c88546141202c9dd0f
    snapshot badge
    swh:1:snp:158a3f36b0bd3da461fb7458de44cfa2c94e4270
    release badge
    swh:1:rel:f9c63742be1925f2d34a163674596c4e6edfb19d

    This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
    Select below a type of object currently browsed in order to generate citations for them.

    • content
    • directory
    • snapshot
    • release
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    Generate software citation in BibTex format (requires biblatex-software package)
    Generating citation ...
    ngx_mail_pop3_handler.c
    
    /*
     * Copyright (C) Igor Sysoev
     * Copyright (C) Nginx, Inc.
     */
    
    
    #include <ngx_config.h>
    #include <ngx_core.h>
    #include <ngx_event.h>
    #include <ngx_mail.h>
    #include <ngx_mail_pop3_module.h>
    
    
    static ngx_int_t ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c);
    static ngx_int_t ngx_mail_pop3_pass(ngx_mail_session_t *s, ngx_connection_t *c);
    static ngx_int_t ngx_mail_pop3_capa(ngx_mail_session_t *s, ngx_connection_t *c,
        ngx_int_t stls);
    static ngx_int_t ngx_mail_pop3_stls(ngx_mail_session_t *s, ngx_connection_t *c);
    static ngx_int_t ngx_mail_pop3_apop(ngx_mail_session_t *s, ngx_connection_t *c);
    static ngx_int_t ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c);
    
    
    static u_char  pop3_greeting[] = "+OK POP3 ready" CRLF;
    static u_char  pop3_ok[] = "+OK" CRLF;
    static u_char  pop3_next[] = "+ " CRLF;
    static u_char  pop3_username[] = "+ VXNlcm5hbWU6" CRLF;
    static u_char  pop3_password[] = "+ UGFzc3dvcmQ6" CRLF;
    static u_char  pop3_invalid_command[] = "-ERR invalid command" CRLF;
    
    
    void
    ngx_mail_pop3_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
    {
        u_char                    *p;
        ngx_mail_core_srv_conf_t  *cscf;
        ngx_mail_pop3_srv_conf_t  *pscf;
    
        pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
        cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
    
        if (pscf->auth_methods
            & (NGX_MAIL_AUTH_APOP_ENABLED|NGX_MAIL_AUTH_CRAM_MD5_ENABLED))
        {
            if (ngx_mail_salt(s, c, cscf) != NGX_OK) {
                ngx_mail_session_internal_server_error(s);
                return;
            }
    
            s->out.data = ngx_pnalloc(c->pool, sizeof(pop3_greeting) + s->salt.len);
            if (s->out.data == NULL) {
                ngx_mail_session_internal_server_error(s);
                return;
            }
    
            p = ngx_cpymem(s->out.data, pop3_greeting, sizeof(pop3_greeting) - 3);
            *p++ = ' ';
            p = ngx_cpymem(p, s->salt.data, s->salt.len);
    
            s->out.len = p - s->out.data;
    
        } else {
            ngx_str_set(&s->out, pop3_greeting);
        }
    
        c->read->handler = ngx_mail_pop3_init_protocol;
    
        ngx_add_timer(c->read, cscf->timeout);
    
        if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
            ngx_mail_close_connection(c);
        }
    
        ngx_mail_send(c->write);
    }
    
    
    void
    ngx_mail_pop3_init_protocol(ngx_event_t *rev)
    {
        ngx_connection_t    *c;
        ngx_mail_session_t  *s;
    
        c = rev->data;
    
        c->log->action = "in auth state";
    
        if (rev->timedout) {
            ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
            c->timedout = 1;
            ngx_mail_close_connection(c);
            return;
        }
    
        s = c->data;
    
        if (s->buffer == NULL) {
            if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t))
                == NGX_ERROR)
            {
                ngx_mail_session_internal_server_error(s);
                return;
            }
    
            s->buffer = ngx_create_temp_buf(c->pool, 128);
            if (s->buffer == NULL) {
                ngx_mail_session_internal_server_error(s);
                return;
            }
        }
    
        s->mail_state = ngx_pop3_start;
        c->read->handler = ngx_mail_pop3_auth_state;
    
        ngx_mail_pop3_auth_state(rev);
    }
    
    
    void
    ngx_mail_pop3_auth_state(ngx_event_t *rev)
    {
        ngx_int_t            rc;
        ngx_connection_t    *c;
        ngx_mail_session_t  *s;
    
        c = rev->data;
        s = c->data;
    
        ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 auth state");
    
        if (rev->timedout) {
            ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
            c->timedout = 1;
            ngx_mail_close_connection(c);
            return;
        }
    
        if (s->out.len) {
            ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "pop3 send handler busy");
            s->blocked = 1;
            return;
        }
    
        s->blocked = 0;
    
        rc = ngx_mail_read_command(s, c);
    
        if (rc == NGX_AGAIN || rc == NGX_ERROR) {
            return;
        }
    
        ngx_str_set(&s->out, pop3_ok);
    
        if (rc == NGX_OK) {
            switch (s->mail_state) {
    
            case ngx_pop3_start:
    
                switch (s->command) {
    
                case NGX_POP3_USER:
                    rc = ngx_mail_pop3_user(s, c);
                    break;
    
                case NGX_POP3_CAPA:
                    rc = ngx_mail_pop3_capa(s, c, 1);
                    break;
    
                case NGX_POP3_APOP:
                    rc = ngx_mail_pop3_apop(s, c);
                    break;
    
                case NGX_POP3_AUTH:
                    rc = ngx_mail_pop3_auth(s, c);
                    break;
    
                case NGX_POP3_QUIT:
                    s->quit = 1;
                    break;
    
                case NGX_POP3_NOOP:
                    break;
    
                case NGX_POP3_STLS:
                    rc = ngx_mail_pop3_stls(s, c);
                    break;
    
                default:
                    rc = NGX_MAIL_PARSE_INVALID_COMMAND;
                    break;
                }
    
                break;
    
            case ngx_pop3_user:
    
                switch (s->command) {
    
                case NGX_POP3_PASS:
                    rc = ngx_mail_pop3_pass(s, c);
                    break;
    
                case NGX_POP3_CAPA:
                    rc = ngx_mail_pop3_capa(s, c, 0);
                    break;
    
                case NGX_POP3_QUIT:
                    s->quit = 1;
                    break;
    
                case NGX_POP3_NOOP:
                    break;
    
                default:
                    rc = NGX_MAIL_PARSE_INVALID_COMMAND;
                    break;
                }
    
                break;
    
            /* suppress warnings */
            case ngx_pop3_passwd:
                break;
    
            case ngx_pop3_auth_login_username:
                rc = ngx_mail_auth_login_username(s, c, 0);
    
                ngx_str_set(&s->out, pop3_password);
                s->mail_state = ngx_pop3_auth_login_password;
                break;
    
            case ngx_pop3_auth_login_password:
                rc = ngx_mail_auth_login_password(s, c);
                break;
    
            case ngx_pop3_auth_plain:
                rc = ngx_mail_auth_plain(s, c, 0);
                break;
    
            case ngx_pop3_auth_cram_md5:
                rc = ngx_mail_auth_cram_md5(s, c);
                break;
    
            case ngx_pop3_auth_external:
                rc = ngx_mail_auth_external(s, c, 0);
                break;
            }
        }
    
        switch (rc) {
    
        case NGX_DONE:
            ngx_mail_auth(s, c);
            return;
    
        case NGX_ERROR:
            ngx_mail_session_internal_server_error(s);
            return;
    
        case NGX_MAIL_PARSE_INVALID_COMMAND:
            s->mail_state = ngx_pop3_start;
            s->state = 0;
    
            ngx_str_set(&s->out, pop3_invalid_command);
    
            /* fall through */
    
        case NGX_OK:
    
            s->args.nelts = 0;
            s->buffer->pos = s->buffer->start;
            s->buffer->last = s->buffer->start;
    
            if (s->state) {
                s->arg_start = s->buffer->start;
            }
    
            ngx_mail_send(c->write);
        }
    }
    
    static ngx_int_t
    ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c)
    {
        ngx_str_t  *arg;
    
    #if (NGX_MAIL_SSL)
        if (ngx_mail_starttls_only(s, c)) {
            return NGX_MAIL_PARSE_INVALID_COMMAND;
        }
    #endif
    
        if (s->args.nelts != 1) {
            return NGX_MAIL_PARSE_INVALID_COMMAND;
        }
    
        arg = s->args.elts;
        s->login.len = arg[0].len;
        s->login.data = ngx_pnalloc(c->pool, s->login.len);
        if (s->login.data == NULL) {
            return NGX_ERROR;
        }
    
        ngx_memcpy(s->login.data, arg[0].data, s->login.len);
    
        ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                       "pop3 login: \"%V\"", &s->login);
    
        s->mail_state = ngx_pop3_user;
    
        return NGX_OK;
    }
    
    
    static ngx_int_t
    ngx_mail_pop3_pass(ngx_mail_session_t *s, ngx_connection_t *c)
    {
        ngx_str_t  *arg;
    
        if (s->args.nelts != 1) {
            return NGX_MAIL_PARSE_INVALID_COMMAND;
        }
    
        arg = s->args.elts;
        s->passwd.len = arg[0].len;
        s->passwd.data = ngx_pnalloc(c->pool, s->passwd.len);
        if (s->passwd.data == NULL) {
            return NGX_ERROR;
        }
    
        ngx_memcpy(s->passwd.data, arg[0].data, s->passwd.len);
    
    #if (NGX_DEBUG_MAIL_PASSWD)
        ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
                       "pop3 passwd: \"%V\"", &s->passwd);
    #endif
    
        return NGX_DONE;
    }
    
    
    static ngx_int_t
    ngx_mail_pop3_capa(ngx_mail_session_t *s, ngx_connection_t *c, ngx_int_t stls)
    {
        ngx_mail_pop3_srv_conf_t  *pscf;
    
        pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
    
    #if (NGX_MAIL_SSL)
    
        if (stls && c->ssl == NULL) {
            ngx_mail_ssl_conf_t  *sslcf;
    
            sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
    
            if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
                s->out = pscf->starttls_capability;
                return NGX_OK;
            }
    
            if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
                s->out = pscf->starttls_only_capability;
                return NGX_OK;
            }
        }
    
    #endif
    
        s->out = pscf->capability;
        return NGX_OK;
    }
    
    
    static ngx_int_t
    ngx_mail_pop3_stls(ngx_mail_session_t *s, ngx_connection_t *c)
    {
    #if (NGX_MAIL_SSL)
        ngx_mail_ssl_conf_t  *sslcf;
    
        if (c->ssl == NULL) {
            sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
            if (sslcf->starttls) {
                c->read->handler = ngx_mail_starttls_handler;
                return NGX_OK;
            }
        }
    
    #endif
    
        return NGX_MAIL_PARSE_INVALID_COMMAND;
    }
    
    
    static ngx_int_t
    ngx_mail_pop3_apop(ngx_mail_session_t *s, ngx_connection_t *c)
    {
        ngx_str_t                 *arg;
        ngx_mail_pop3_srv_conf_t  *pscf;
    
    #if (NGX_MAIL_SSL)
        if (ngx_mail_starttls_only(s, c)) {
            return NGX_MAIL_PARSE_INVALID_COMMAND;
        }
    #endif
    
        if (s->args.nelts != 2) {
            return NGX_MAIL_PARSE_INVALID_COMMAND;
        }
    
        pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
    
        if (!(pscf->auth_methods & NGX_MAIL_AUTH_APOP_ENABLED)) {
            return NGX_MAIL_PARSE_INVALID_COMMAND;
        }
    
        arg = s->args.elts;
    
        s->login.len = arg[0].len;
        s->login.data = ngx_pnalloc(c->pool, s->login.len);
        if (s->login.data == NULL) {
            return NGX_ERROR;
        }
    
        ngx_memcpy(s->login.data, arg[0].data, s->login.len);
    
        s->passwd.len = arg[1].len;
        s->passwd.data = ngx_pnalloc(c->pool, s->passwd.len);
        if (s->passwd.data == NULL) {
            return NGX_ERROR;
        }
    
        ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len);
    
        ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
                       "pop3 apop: \"%V\" \"%V\"", &s->login, &s->passwd);
    
        s->auth_method = NGX_MAIL_AUTH_APOP;
    
        return NGX_DONE;
    }
    
    
    static ngx_int_t
    ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c)
    {
        ngx_int_t                  rc;
        ngx_mail_pop3_srv_conf_t  *pscf;
    
    #if (NGX_MAIL_SSL)
        if (ngx_mail_starttls_only(s, c)) {
            return NGX_MAIL_PARSE_INVALID_COMMAND;
        }
    #endif
    
        pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module);
    
        if (s->args.nelts == 0) {
            s->out = pscf->auth_capability;
            s->state = 0;
    
            return NGX_OK;
        }
    
        rc = ngx_mail_auth_parse(s, c);
    
        switch (rc) {
    
        case NGX_MAIL_AUTH_LOGIN:
    
            ngx_str_set(&s->out, pop3_username);
            s->mail_state = ngx_pop3_auth_login_username;
    
            return NGX_OK;
    
        case NGX_MAIL_AUTH_LOGIN_USERNAME:
    
            ngx_str_set(&s->out, pop3_password);
            s->mail_state = ngx_pop3_auth_login_password;
    
            return ngx_mail_auth_login_username(s, c, 1);
    
        case NGX_MAIL_AUTH_PLAIN:
    
            ngx_str_set(&s->out, pop3_next);
            s->mail_state = ngx_pop3_auth_plain;
    
            return NGX_OK;
    
        case NGX_MAIL_AUTH_CRAM_MD5:
    
            if (!(pscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
                return NGX_MAIL_PARSE_INVALID_COMMAND;
            }
    
            if (ngx_mail_auth_cram_md5_salt(s, c, "+ ", 2) == NGX_OK) {
                s->mail_state = ngx_pop3_auth_cram_md5;
                return NGX_OK;
            }
    
            return NGX_ERROR;
    
        case NGX_MAIL_AUTH_EXTERNAL:
    
            if (!(pscf->auth_methods & NGX_MAIL_AUTH_EXTERNAL_ENABLED)) {
                return NGX_MAIL_PARSE_INVALID_COMMAND;
            }
    
            ngx_str_set(&s->out, pop3_username);
            s->mail_state = ngx_pop3_auth_external;
    
            return NGX_OK;
        }
    
        return rc;
    }
    

    back to top

    Software Heritage — Copyright (C) 2015–2026, The Software Heritage developers. License: GNU AGPLv3+.
    The source code of Software Heritage itself is available on our development forge.
    The source code files archived by Software Heritage are available under their own copyright and licenses.
    Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API