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())); } }
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())); } }
/* * 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); }
/* * 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; }
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; }