示例#1
0
文件: smtp.c 项目: icyfork/ecartis
int try_connect_HELO(const char *hostname)
{
    char dbg_hostname[BIG_BUF];
    char dbg_version[BIG_BUF];
    char buf[BIG_BUF];
    char testme[BIG_BUF];

    /* Try the HELO protocal */
    if(my_socket != -1)
        sock_close(my_socket);

    if (sock_open(get_string("mailserver"), get_number("smtp-socket", 25), &my_socket))
        return 0;

    if (sock_readline(my_socket, buf, sizeof(buf)) == 0)
        return 0;

    if(!sscanf(buf,"220 %s %s", &dbg_hostname[0], &dbg_version[0]))
        return 0;
    log_printf(9, "Connected: %s (%s)\n", dbg_hostname, dbg_version);

    sock_printf(my_socket, "HELO %s\r\n", hostname);
    if(sock_readline(my_socket, buf, sizeof(buf)) == 0)
        return 0;
    if(!sscanf(buf, "250 %s", testme))
        return 0;
    return 1;
}
示例#2
0
/*
 * reads in an entire message from the ftp server.
 */
char *read_sock(int sock)
{
    char ibuf[8192], *bigbuf = NULL;
    int r;
    unsigned int total = 0;

    for(;;)
    {
	memset(ibuf, 0x0, sizeof(ibuf));
	r = sock_readline(sock, ibuf, sizeof(ibuf) - 1);
	
	bigbuf = Realloc(bigbuf, (total + strlen(ibuf) + 1) * sizeof(char));
	memcpy(bigbuf + total, ibuf, strlen(ibuf));
	bigbuf[total + strlen(ibuf)] = 0x0;
	total += strlen(ibuf);

	if(strlen(ibuf) < 4)
	    break;

	/* multi-lined responses have a dash as the 4th character */
	if(ibuf[3] != '-')
	    break;
    }
   
    if(debug_read)
    {
	printf(" < %s", bigbuf);
	fflush(stdout);
    }

    return bigbuf;
    
}
示例#3
0
文件: smtp.c 项目: icyfork/ecartis
int try_connect_EHLO(const char *hostname)
{
    char dbg_hostname[BIG_BUF];
    char dbg_version[BIG_BUF];
    char buf[BIG_BUF];
    char testme[BIG_BUF];
    int read_data = 0;

    if(my_socket != -1)
        sock_close(my_socket);

    log_printf(9, "Attempting to connect to %s\n", get_string("mailserver"));

    if (sock_open(get_string("mailserver"), get_number("smtp-socket", 25), &my_socket))
        return 0;

    while(sock_readline(my_socket, buf, sizeof(buf)) != 0) {
        int val;
        char ch;

        read_data = 1;
        log_printf(9,"Server sent: %s\n", buf);

        sscanf(buf, "%d%c%s %s", &val, &ch, &dbg_hostname[0], &dbg_version[0]);
        if(val != 220) {
             return 0;
        }
        if(ch != '-') {
            log_printf(9, "Connected: %s (%s)\n", dbg_hostname, dbg_version);
            break;
        }
    }
    if(!read_data)
        return 0;

    sock_printf(my_socket, "EHLO %s\r\n", hostname);
    if(sock_readline(my_socket, buf, sizeof(buf)) == 0)
        return 0;

    /* Check for valid response */
    if(!sscanf(buf, "250-%s", testme))
        return 0;

    /* Okay, we have a valid ESMTP server.  Read the server caps */
    while(sock_readline(my_socket, buf, sizeof(buf)) != 0) {
        int val;
        char ch;

        log_printf(9,"Server sent: %s\n", buf);

        sscanf(buf, "%d%c%s", &val, &ch, testme);
        if(val != 250) {
             return 0;
        }
        if(ch != '-')
            break;
        else {
            if (!strcmp(testme,"DSN")) {
                servercaps &= CAPS_DSN;
                log_printf(9, "Server caps: server supports DSN\n");
            } else if (!strcmp(testme,"8BITMIME")) {
                servercaps &= CAPS_MIME;
                log_printf(9, "Server caps: server supports MIME\n");
            }
        }
    }
    return 1;
}
// main check password function which do real job of authentication against dovecot
static authn_status check_password(request_rec * r, const char *user, const char *password)
{
	authn_dovecot_config_rec *conf = ap_get_module_config(r->per_dir_config,
							      &authn_dovecot_module);
	apr_pool_t *p;		// sub pool of r->pool

	int i, auths, readsocks, result, opts, fdmax, cnt, auth_in_progress, retval;
	struct sockaddr_un address;
	struct timeval tv;
	struct connection_state cs;

	apr_pool_create(&p, r->pool);	// create subpool for local functions, variables...

	// setting default values for connection state 
	cs.version_ok = 0;
	cs.mech_available = 0;
	cs.hshake_done = 0;
	cs.authenticated = 0;	// by default user is NOT authenticated :)
	cs.handshake_sent = 0;
	cs.user = NULL;

	fd_set socks_r;
	fd_set socks_w;
	fd_set error_fd;
	
	char * const line = apr_pcalloc(p, sizeof(char) * (BUFFMAX + 1));
	ap_assert(line != NULL);
	auths = socket(AF_UNIX, SOCK_STREAM, 0);
	opts = fcntl(auths, F_GETFL);
	opts = (opts | O_NONBLOCK);
	if (fcntl(auths, F_SETFL, opts) < 0) {
		perror("fcntl(F_SETFL)");
	}
	address.sun_family = AF_UNIX;
	strncpy(address.sun_path,conf->dovecotauthsocket, strlen(conf->dovecotauthsocket));
	result = connect(auths, (struct sockaddr *)&address, sizeof address);
	if (result) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: could not connect to dovecot socket");
		if (conf->authoritative == 0) {
			return DECLINED;
		} else {
			return AUTH_USER_NOT_FOUND;
		}
	}
	cnt = 0;

	auth_in_progress = 0;
	// loop trough sockets for writability and for data on socket to read,
	// wait untill authenticated or if timeoout occurs error out with AUTH_USER_NOT_FOUND and log it
	while (cnt < conf->dovecotauthtimeout) {
		fdmax = auths;	// simply this is only one really used socket so ...
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		FD_ZERO(&socks_r);
		FD_SET(auths, &socks_r);
		FD_ZERO(&error_fd);
		FD_SET(auths, &error_fd);
		if (cs.handshake_sent == 0) {
			FD_ZERO(&socks_w);
			FD_SET(auths, &socks_w);
		} else {
			FD_ZERO(&socks_w);
		}

		readsocks = select(fdmax + 1, &socks_r, &socks_w, NULL, &tv);
		if (readsocks < 0) {
			ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: socket select");
			return DECLINED;
		}

		if (readsocks == 0) {
			cnt++;	// wait for timeout and count to conf->dovecotauthtimeout
			// only add to counter in case of timeout!
			//fprintf(stderr, "%i ", cnt);
			fflush(stdout);
		} else {
			for (i = 0; i <= fdmax; i++) {
				if (FD_ISSET(i, &socks_w)) {
					if (cs.handshake_sent == 0) {
						cs.handshake_sent = send_handshake(p, r, i);
						ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: handshake is sent");
					}
				}
				if (FD_ISSET(i, &socks_r)) {
					while ((retval = sock_readline(p, r, i, line)) > 0) {
						if (!receive_data(p, r, &cs, line)) {
							ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: problems while receiving data from socket");
							if (conf->authoritative == 0) {
								return DECLINED;
							} else {
								return AUTH_USER_NOT_FOUND;
							}
						} else {
							if (cs.hshake_done == 1) {
								if (!cs.version_ok && !cs.mech_available) {
									ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
										      "Dovecot Authentication: No authentication possible protocol version wrong or plaintext method not available...");
									close(auths);
									return AUTH_USER_NOT_FOUND;
								} else {
									if (auth_in_progress != 1) {
										ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: Sending authentication request");
										send_auth_request(p, r, i, user, password,
#if MODULE_MAGIC_NUMBER_MAJOR >= 20120211
                                            r->connection->client_ip
#else
                                            r->connection->remote_ip
#endif
                                            );
										auth_in_progress = 1;
									}
								}
							}
							if (cs.authenticated == 1) {
								ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Dovecot Authentication: Authenticated user=\"%s\"", user);
								close(auths);
								if (cs.user != NULL) {
									r->user = cs.user;
								}
								return AUTH_GRANTED;
							}
							if (cs.authenticated == -1) {
								ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: Denied authentication for user=\"%s\"", user);
								close(auths);
								if (conf->authoritative == 0) {
									return DECLINED;
								} else {
									return AUTH_USER_NOT_FOUND;
								}
							}
							break;
						}
					}
					if (retval == -1) {
						ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication: socket reading failed bailing out");
						close(auths);
						if (conf->authoritative == 0) {
							return DECLINED;
						} else {
							return AUTH_USER_NOT_FOUND;
						}
					}
				}
			}
		}
	}
	close(auths);
	ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Dovecot Authentication Timeout");
	if (conf->authoritative == 0) {
		return DECLINED;
	} else {
		return AUTH_USER_NOT_FOUND;
	}
}