Example #1
0
void AuthRequest::element_end(const char *el)
{
    if (strcmp(el, "iq"))
        return;
    if (m_bFail){
        QTimer::singleShot(0, m_client, SLOT(auth_failed()));
    }else{
        QTimer::singleShot(0, m_client, SLOT(auth_ok()));
    }
}
Example #2
0
void AuthRequest::element_end(const char *el)
{
    if (strcmp(el, "iq"))
        return;
    if (m_errorCode){
        if (m_errorCode != (unsigned)(-1)){
			m_client->m_authCode = m_errorCode;
			QTimer::singleShot(0, m_client, SLOT(auth_failed()));
		}
    }else{
		QTimer::singleShot(0, m_client, SLOT(auth_ok()));
    }
}
Example #3
0
/*
 * do frontend <-> pgpool authentication based on pool_hba.conf
 */
void ClientAuthentication(POOL_CONNECTION *frontend)
{
	POOL_STATUS status = POOL_ERROR;

	if (! hba_getauthmethod(frontend))
	{
		pool_error("missing or erroneous pool_hba.conf file");
		pool_send_error_message(frontend, frontend->protoVersion, "XX000",
								"missing or erroneous pool_hba.conf file", "",
								"See pgpool log for details.", __FILE__, __LINE__);
		close_all_backend_connections();
		/*
		 * use exit(2) since this is not so fatal. other entries in
		 * pool_hba.conf may be valid, so treat it as reject.
		 */
		child_exit(2);
	}

	switch (frontend->auth_method)
	{
		case uaReject:
		{
            /*
			 * This could have come from an explicit "reject" entry in
			 * pool_hba.conf, but more likely it means there was no matching
			 * entry.  Take pity on the poor user and issue a helpful
			 * error message.  NOTE: this is not a security breach,
			 * because all the info reported here is known at the frontend
			 * and must be assumed known to bad guys. We're merely helping
			 * out the less clueful good guys.
			 */
			char hostinfo[NI_MAXHOST];
			char *errmessage;
			int messagelen;

			getnameinfo_all(&frontend->raddr.addr, frontend->raddr.salen,
							hostinfo, sizeof(hostinfo),
							NULL, 0,
							NI_NUMERICHOST);

			messagelen = sizeof(hostinfo) +
				strlen(frontend->username) + strlen(frontend->database) + 80;
			if ((errmessage = (char *)malloc(messagelen+1)) == NULL)
			{
				pool_error("ClientAuthentication: malloc failed: %s", strerror(errno));
				child_exit(1);
			}

#ifdef USE_SSL
			snprintf(errmessage, messagelen+7, /* +7 is for "SSL off" */
					 "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
					 hostinfo, frontend->username, frontend->database,
					 frontend->ssl ? "SSL on" : "SSL off");
#else
			snprintf(errmessage, messagelen,
					 "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
					 hostinfo, frontend->username, frontend->database);
#endif
			pool_error(errmessage);
			pool_send_error_message(frontend, frontend->protoVersion, "XX000", errmessage,
									"", "", __FILE__, __LINE__);

			free(errmessage);
			break;
		}

/* 		case uaKrb4: */
/* 			break; */

/* 		case uaKrb5: */
/* 			break; */

/* 		case uaIdent: */
/* 			break; */

/* 		case uaMD5: */
/* 			break; */

/* 		case uaCrypt: */
/* 			break; */

/* 		case uaPassword: */
/* 			break; */

#ifdef USE_PAM
		case uaPAM:
			pam_frontend_kludge = frontend;
			status = CheckPAMAuth(frontend, frontend->username, "");
			break;
#endif /* USE_PAM */

		case uaTrust:
			status = POOL_CONTINUE;
			break;
	}

 	if (status == POOL_CONTINUE)
 		sendAuthRequest(frontend, AUTH_REQ_OK);
 	else if (status != POOL_CONTINUE)
		auth_failed(frontend);
}
Example #4
0
/*
 * Client authentication starts here.  If there is an error, this
 * function does not return and the backend process is terminated.
 */
void
ClientAuthentication(Port *port)
{
	int			status = STATUS_ERROR;

	/*
	 * Get the authentication method to use for this frontend/database
	 * combination.  Note: a failure return indicates a problem with the
	 * hba config file, not with the request.  hba.c should have dropped
	 * an error message into the postmaster logfile if it failed.
	 */
	if (hba_getauthmethod(port) != STATUS_OK)
		ereport(FATAL,
				(errcode(ERRCODE_CONFIG_FILE_ERROR),
				 errmsg("missing or erroneous pg_hba.conf file"),
				 errhint("See server log for details.")));

	switch (port->auth_method)
	{
		case uaReject:

			/*
			 * This could have come from an explicit "reject" entry in
			 * pg_hba.conf, but more likely it means there was no matching
			 * entry.  Take pity on the poor user and issue a helpful
			 * error message.  NOTE: this is not a security breach,
			 * because all the info reported here is known at the frontend
			 * and must be assumed known to bad guys. We're merely helping
			 * out the less clueful good guys.
			 */
			{
				char		hostinfo[NI_MAXHOST];

				getnameinfo_all(&port->raddr.addr, port->raddr.salen,
								hostinfo, sizeof(hostinfo),
								NULL, 0,
								NI_NUMERICHOST);

#ifdef USE_SSL
				ereport(FATAL,
				   (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
					errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
						   hostinfo, port->user_name, port->database_name,
				   port->ssl ? gettext("SSL on") : gettext("SSL off"))));
#else
				ereport(FATAL,
				   (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
					errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
					   hostinfo, port->user_name, port->database_name)));
#endif
				break;
			}

		case uaKrb4:
			/* Kerberos 4 only seems to work with AF_INET. */
			if (port->raddr.addr.ss_family != AF_INET
				|| port->laddr.addr.ss_family != AF_INET)
				ereport(FATAL,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				   errmsg("Kerberos 4 only supports IPv4 connections")));
			sendAuthRequest(port, AUTH_REQ_KRB4);
			status = pg_krb4_recvauth(port);
			break;

		case uaKrb5:
			sendAuthRequest(port, AUTH_REQ_KRB5);
			status = pg_krb5_recvauth(port);
			break;

		case uaIdent:
			/*
			 * If we are doing ident on unix-domain sockets, use SCM_CREDS
			 * only if it is defined and SO_PEERCRED isn't.
			 */
#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && \
	(defined(HAVE_STRUCT_CMSGCRED) || defined(HAVE_STRUCT_FCRED) || \
	 (defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS)))
			if (port->raddr.addr.ss_family == AF_UNIX)
			{
#if defined(HAVE_STRUCT_FCRED) || defined(HAVE_STRUCT_SOCKCRED)
				/*
				 * Receive credentials on next message receipt, BSD/OS,
				 * NetBSD. We need to set this before the client sends the
				 * next packet.
				 */
				int			on = 1;

				if (setsockopt(port->sock, 0, LOCAL_CREDS, &on, sizeof(on)) < 0)
					ereport(FATAL,
							(errcode_for_socket_access(),
					 errmsg("could not enable credential reception: %m")));
#endif

				sendAuthRequest(port, AUTH_REQ_SCM_CREDS);
			}
#endif
			status = authident(port);
			break;

		case uaMD5:
			sendAuthRequest(port, AUTH_REQ_MD5);
			status = recv_and_check_password_packet(port);
			break;

		case uaCrypt:
			sendAuthRequest(port, AUTH_REQ_CRYPT);
			status = recv_and_check_password_packet(port);
			break;

		case uaPassword:
			sendAuthRequest(port, AUTH_REQ_PASSWORD);
			status = recv_and_check_password_packet(port);
			break;

#ifdef USE_PAM
		case uaPAM:
			pam_port_cludge = port;
			status = CheckPAMAuth(port, port->user_name, "");
			break;
#endif   /* USE_PAM */

		case uaTrust:
			status = STATUS_OK;
			break;
	}

	if (status == STATUS_OK)
		sendAuthRequest(port, AUTH_REQ_OK);
	else
		auth_failed(port, status);
}
int main(int argc, char **argv) {
    struct sockaddr_in config, peer;
    struct epoll_event ev, events[EP_SIZE];
    struct conn_status status[MAX_FD], *curr;

    in_port_t port = L_PORT;
    int listenfd, epfd, connfd;
    int i, flag, nfds, current_fd;
    socklen_t len;

    char buffer[FILE_BUFFER];

    // init
    sockinit(&config);
    sockset(&config, port, NULL);
    memset(status, 0, sizeof(status));
    memset(buffer, 0, sizeof(buffer));
    signal(SIGPIPE, SIG_IGN);

    // create server
    listenfd = create_server(&config);
    if (listenfd < 0) {
        perror("xtrans: server create failed.");
        exit(EXIT_FAILURE);
    }

    // create epoll fd
    epfd = ep_ini();
    if (epfd < 0) {
        perror("xtrans: epoll init failed.");
        exit(EXIT_FAILURE); 
    }

    // add listen fd to epoll
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;
    if (ep_add(epfd, listenfd, &ev) == -1) {
        perror("xtrans: add epoll event failed.");
        exit(EXIT_FAILURE);
    }

    // main loop
    for(;;) {
        nfds = ep_col(epfd, events);

        for (i = 0; i < nfds; i++) {
            current_fd = events[i].data.fd;

            if (current_fd == listenfd) {
                connfd = accept(listenfd, (SA *)&peer, &len);
                if (connfd == -1) {
                    continue;
                }
                memcpy(&(status[connfd].client), &peer, sizeof(struct sockaddr_in));

                ev.events = EPOLLIN;
                ev.data.fd = connfd;
                if (ep_add(epfd, connfd, &ev) == -1) {
                    continue;
                }
                
                flag = welcome(connfd, &(status[connfd]));
                if (flag >= 0) {
                    x_log(LOG_CONN, &(status[connfd]));
                } else {
                    x_log(LOG_DISC, &(status[connfd]));
                    terminate(epfd, connfd, &(status[connfd]));
                }

            } else if (events[i].events & EPOLLIN) {
                curr = &(status[current_fd]);

                switch (curr->status) {
                    case STATUS_INIT:
                        memset(&(curr->username), 0, sizeof(char)*12);

                        flag = readln(current_fd, curr->username, 1); 
                        if (flag < 0) {
                            terminate(epfd, current_fd, curr);
                            x_log(LOG_DISC, curr);
                        }

                        flag = get_username(current_fd, curr);
                        if (flag < 0) {
                            terminate(epfd, current_fd, curr);
                            x_log(LOG_DISC, curr);
                        }

                        break;
                    case STATUS_NAME:
                        memset(&(curr->passwd), 0, sizeof(char)*32);

                        flag = readln(current_fd, curr->passwd, 1);
                        if (flag < 0) {
                            terminate(epfd, current_fd, curr);
                            x_log(LOG_DISC, curr);
                        }

                        flag = get_passwd(current_fd, curr);
                        if (flag < 0) {
                            terminate(epfd, current_fd, curr);
                            x_log(LOG_DISC, curr);
                        }
                        
                        flag = auth(curr->username, curr->passwd);
                        if (flag < 0) {
                            flag = auth_failed(current_fd, curr);
                            terminate(epfd, current_fd, curr);

                            x_log(LOG_REFS, curr);
                        } else {
                            flag = auth_success(current_fd, curr);
                            if (flag < 0) {
                                x_log(LOG_DISC, curr);
                            } else {
                                x_log(LOG_LOGI, curr);
                            }
                        }

                        break;
                    case STATUS_SUCC:
                        flag = readFd(current_fd, buffer, 1024);
                        if (flag < 0) {
                            terminate(epfd, current_fd, curr);
                            x_log(LOG_DISC, curr);
                        }

                        curr->recvb = flag;
                        terminate(epfd, current_fd, curr);
                        x_log(LOG_FINS, curr);

                        break;
                    default:
                        perror("xtrans: status not define, default action triggered.");
                        terminate(epfd, current_fd, curr);
                }
            }
        }   
    }

    return 0;
}
Example #6
0
bool t_auth::authorize(t_user *user_config, t_request *r, t_response *resp) {
    string username;
    string passwd;
    list<t_cr_cache_entry>::iterator i;
    t_challenge c;
    bool proxy;

    assert(resp->must_authenticate());

    if (resp->code == R_401_UNAUTHORIZED) {
        c = resp->hdr_www_authenticate.challenge;
        proxy = false;
    } else {
        c = resp->hdr_proxy_authenticate.challenge;
        proxy = true;
    }

    // Only DIGEST is supported
    if (c.auth_scheme != AUTH_DIGEST) {
        log_file->write_header("t_auth::authorize");
        log_file->write_raw("Unsupported authentication scheme: ");
        log_file->write_raw(c.auth_scheme);
        log_file->write_endl();
        log_file->write_footer();
        return false;
    }

    const t_digest_challenge &dc = c.digest_challenge;
    i = find_cache_entry(r->uri, dc.realm, proxy);

    if (auth_failed(r, c, proxy)) {
        // The current credentials are wrong. Remove them and
        // ask the user for a username and password.
        remove_credentials(r, c, proxy);
    } else {
        // Determine user name and password
        if (i != cache.end()) {
            username = i->credentials.digest_response.username;
            passwd = i->passwd;
        } else if (dc.realm == user_config->get_auth_realm() ||
                   user_config->get_auth_realm() == "") {
            username = user_config->get_auth_name();
            passwd = user_config->get_auth_pass();
        }

        if (dc.stale) {
            // The current credentials are stale. Remove them.
            remove_credentials(r, c, proxy);
        }
    }

    // Ask user for username/password
    if ((username == "" || passwd == "") && !re_register) {
        if (!ui->cb_ask_credentials(user_config, dc.realm, username, passwd)) {
            log_file->write_report("Asking user name and password failed.",
                                   "t_auth::authorize");
            return false;
        }
    }

    // No valid username/passwd
    if (username == "" && passwd == "") {
        log_file->write_report("Incorrect user name and/or password.",
                               "t_auth::authorize");
        return false;
    }

    bool auth_success;
    string fail_reason;
    if (!proxy) {
        t_credentials cr;
        auth_success = r->www_authorize(c, user_config,
                                        username, passwd, 1, NEW_CNONCE, cr, fail_reason);

        if (auth_success) {
            update_cache(r->uri, cr, passwd, proxy);
        }
    } else {
        t_credentials cr;
        auth_success = r->proxy_authorize(c, user_config,
                                          username, passwd, 1, NEW_CNONCE, cr, fail_reason);

        if (auth_success) {
            update_cache(r->uri, cr, passwd, proxy);
        }
    }

    if (!auth_success) {
        log_file->write_report(fail_reason, "t_auth::authorize");
        return false;
    }

    return true;
}