int tcp_connect_sockaddr( struct sockaddr *sa, /* I */ size_t sa_size) /* I */ { int rc = PBSE_NONE; int stream = TRANSIENT_SOCKET_FAIL; char *err_msg = NULL; char local_err_buf[LOCAL_LOG_BUF]; char *tmp_ip = NULL; int retryCount = 5; errno = 0; while (retryCount-- >= 0) { if ((stream = socket_get_tcp_priv()) < 0) { /* FAILED */ log_err(errno,__func__,"Failed when trying to get privileged port - socket_get_tcp_priv() failed"); } else if ((rc = socket_connect_addr(&stream, sa, sa_size, 1, &err_msg)) != PBSE_NONE) { /* FAILED */ if (errno != EINTR) //Interrupted system call is a retryable error so try it again. { retryCount = -1; } else { usleep(10000); //Catch a breath on a retryable error. } tmp_ip = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); snprintf(local_err_buf, LOCAL_LOG_BUF, "Failed when trying to open tcp connection - connect() failed [rc = %d] [addr = %s:%d]", rc, tmp_ip, htons(((struct sockaddr_in *)sa)->sin_port)); log_err(-1,__func__,local_err_buf); if (err_msg != NULL) { log_err(-1,__func__,err_msg); free(err_msg); err_msg = NULL; } } else { /* SUCCESS */ return(stream); } /* FAILURE */ if (IS_VALID_STREAM(stream)) { close(stream); stream = TRANSIENT_SOCKET_FAIL; } } return(stream); } /* END tcp_connect_sockaddr() */
int tcp_connect_sockaddr( struct sockaddr *sa, /* I */ size_t sa_size) /* I */ { char *id = "tcp_connect_sockaddr"; int rc = PBSE_NONE; int stream = -1; char *err_msg = NULL; char local_err_buf[LOCAL_LOG_BUF]; char *tmp_ip = NULL; /* int stream = socket(AF_INET,SOCK_STREAM,0); if (stream < 0) { log_err(errno,id,"Failed when trying to open tcp connection - socket() failed"); } else if (setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)) < 0) { log_err(errno,id,"Failed when trying to open tcp connection - setsockopt() failed"); } else if (bindresvport(stream,NULL) < 0) { log_err(errno,id,"Failed when trying to open tcp connection - bindresvport() failed"); } */ if ((stream = socket_get_tcp_priv()) < 0) { /* FAILED */ log_err(errno,id,"Failed when trying to get privileged port - socket_get_tcp_priv() failed"); } else if ((rc = socket_connect_addr(&stream, sa, sa_size, 1, &err_msg)) != PBSE_NONE) { /* FAILED */ tmp_ip = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); snprintf(local_err_buf, LOCAL_LOG_BUF, "Failed when trying to open tcp connection - connect() failed [rc = %d] [addr = %s:%d]", rc, tmp_ip, htons(((struct sockaddr_in *)sa)->sin_port)); log_err(errno,id,local_err_buf); if (err_msg != NULL) { log_err(errno,id,err_msg); free(err_msg); } } else { /* SUCCESS */ return(stream); } /* FAILURE */ if (IS_VALID_STREAM(stream)) close(stream); return(-1); } /* END tcp_connect_sockaddr() */
void *process_svr_conn( void *sock) { char *className = "trqauthd"; int rc = PBSE_NONE; char *server_name = NULL; int server_port = 0; int auth_type = 0; char *user_name = NULL; int user_sock = 0; char *error_msg = NULL; char *send_message = NULL; int send_len = 0; char *trq_server_addr = NULL; int trq_server_addr_len = 0; int disconnect_svr = TRUE; int svr_sock = 0; int msg_len = 0; int debug_mark = 0; int local_socket = *(int *)sock; char msg_buf[1024]; /* incoming message format is: * trq_system_len|trq_system|trq_port|Validation_type|user_len|user|psock| * message format to pbs_server is: * +2+22+492+user+sock+0 * format from pbs_server is: * +2+2+0+0+1 * outgoing message format is: * #|msg_len|message| * Send response to client here!! * Disconnect message to svr: * +2+22+592+{user_len}{user} * * msg to client in the case of success: * 0|0|| */ if ((rc = parse_request_client(local_socket, &server_name, &server_port, &auth_type, &user_name, &user_sock)) != PBSE_NONE) { disconnect_svr = FALSE; debug_mark = 1; } else if ((rc = get_trq_server_addr(server_name, &trq_server_addr, &trq_server_addr_len)) != PBSE_NONE) { disconnect_svr = FALSE; debug_mark = 2; } else if ((svr_sock = socket_get_tcp_priv()) < 0) { rc = PBSE_SOCKET_FAULT; disconnect_svr = FALSE; debug_mark = 3; } else if ((rc = socket_connect(&svr_sock, trq_server_addr, trq_server_addr_len, server_port, AF_INET, 1, &error_msg)) != PBSE_NONE) { disconnect_svr = FALSE; debug_mark = 4; socket_close(svr_sock); } else if ((rc = build_request_svr(auth_type, user_name, user_sock, &send_message)) != PBSE_NONE) { socket_close(svr_sock); debug_mark = 5; } else if ((send_len = ((send_message == NULL)?0:strlen(send_message)) ) <= 0) { socket_close(svr_sock); rc = PBSE_INTERNAL; debug_mark = 6; } else if ((rc = socket_write(svr_sock, send_message, send_len)) != send_len) { socket_close(svr_sock); rc = PBSE_SOCKET_WRITE; debug_mark = 7; } else if ((rc = parse_response_svr(svr_sock, &error_msg)) != PBSE_NONE) { socket_close(svr_sock); debug_mark = 8; } else { /* Success case */ if (send_message != NULL) free(send_message); send_message = (char *)calloc(1, 6); if(send_message != NULL) strcat(send_message, "0|0||"); if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d success. Conn %d authorized\n", server_name, server_port, user_sock); } snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d logged in", user_name, server_name, server_port); log_record(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } if (rc != PBSE_NONE) { /* Failure case */ if (send_message != NULL) free(send_message); msg_len = 6 + 1 + 6 + 1 + 1; if (error_msg == NULL) error_msg = strdup(pbse_to_txt(rc)); msg_len += strlen(error_msg); send_message = (char *)calloc(1, msg_len); if(send_message != NULL) snprintf(send_message, msg_len, "%d|%d|%s|", rc, (int)strlen(error_msg), error_msg); if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d Fail. Conn %d not authorized (dm = %d, Err Num %d)\n", server_name, server_port, user_sock, debug_mark, rc); } snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d login attempt failed --%s", user_name, server_name, server_port, error_msg); log_record(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } if(send_message != NULL) rc = socket_write(local_socket, send_message, strlen(send_message)); if (TRUE == disconnect_svr) { send_svr_disconnect(svr_sock, user_name); socket_close(svr_sock); } if (trq_server_addr != NULL) free(trq_server_addr); if (server_name != NULL) free(server_name); if (user_name != NULL) free(user_name); if (error_msg != NULL) free(error_msg); if (send_message != NULL) free(send_message); socket_close(local_socket); free(sock); return(NULL); } /* END process_svr_conn() */
int authorize_socket( int local_socket, std::string &message, char *msg_buf, char **server_name_ptr, char **user_name_ptr, std::string &err_msg) { int rc; bool disconnect_svr = true; int server_port; int auth_type = 0; int svr_sock = -1; int user_pid = 0; int user_sock = 0; int trq_server_addr_len = 0; char *trq_server_addr = NULL; const char *className = "trqauthd"; /* incoming message format is: * trq_system_len|trq_system|trq_port|Validation_type|user_len|user|pid|psock| * message format to pbs_server is: * +2+22+492+user+sock+0 * format from pbs_server is: * +2+2+0+0+1 * outgoing message format is: * #|msg_len|message| * Send response to client here!! * Disconnect message to svr: * +2+22+592+{user_len}{user} * * msg to client in the case of success: * 0|0|| */ if ((rc = parse_request_client(local_socket, server_name_ptr, &server_port, &auth_type, user_name_ptr, &user_pid, &user_sock)) != PBSE_NONE) { if (*server_name_ptr != NULL) free(*server_name_ptr); if (*user_name_ptr != NULL) free(*user_name_ptr); return(rc); } else { int retries = 0; char *server_name = *server_name_ptr; while (retries < MAX_RETRIES) { rc = PBSE_NONE; disconnect_svr = true; if ((rc = validate_user(local_socket, *user_name_ptr, user_pid, msg_buf)) != PBSE_NONE) { log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, __func__, msg_buf); disconnect_svr = false; retries++; usleep(20000); continue; } else if ((rc = get_trq_server_addr(server_name, &trq_server_addr, &trq_server_addr_len)) != PBSE_NONE) { disconnect_svr = false; retries++; usleep(20000); continue; } else if ((svr_sock = socket_get_tcp_priv()) < 0) { rc = PBSE_SOCKET_FAULT; disconnect_svr = false; retries++; usleep(10000); continue; } else if ((rc = socket_connect(svr_sock, trq_server_addr, trq_server_addr_len, server_port, AF_INET, 1, err_msg)) != PBSE_NONE) { /* for now we only need ssh_key and sign_key as dummys */ char *ssh_key = NULL; char *sign_key = NULL; char log_buf[LOCAL_LOG_BUF_SIZE]; validate_server(server_name, server_port, ssh_key, &sign_key); sprintf(log_buf, "Active server is %s", active_pbs_server); log_event(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, __func__, log_buf); disconnect_svr = false; socket_close(svr_sock); retries++; usleep(50000); continue; } else if ((rc = build_request_svr(auth_type, *user_name_ptr, user_sock, message)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = false; retries++; usleep(50000); continue; } else if (message.size() <= 0) { socket_close(svr_sock); disconnect_svr = false; rc = PBSE_INTERNAL; retries++; usleep(50000); continue; } else if ((rc = socket_write(svr_sock, message.c_str(), message.size())) != (int)message.size()) { socket_close(svr_sock); disconnect_svr = false; rc = PBSE_SOCKET_WRITE; retries++; usleep(50000); continue; } else if ((rc = parse_response_svr(svr_sock, err_msg)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = false; retries++; usleep(50000); continue; } else { /* Success case */ message = "0|0||"; if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d success. Conn %d authorized\n", server_name, server_port, user_sock); } sprintf(msg_buf, "User %s at IP:port %s:%d logged in", *user_name_ptr, server_name, server_port); log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } break; } } if (disconnect_svr == true) { send_svr_disconnect(svr_sock, *user_name_ptr); socket_close(svr_sock); } if (trq_server_addr != NULL) free(trq_server_addr); return(rc); } // END authorize_socket()
int socket_connect_addr( int *socket, struct sockaddr *remote, size_t remote_size, int is_privileged, char **error_msg) { int cntr = 0; int rc = PBSE_NONE; char tmp_buf[LOCAL_LOG_BUF_SIZE+1]; const char id[] = "socket_connect_addr"; int local_socket = *socket; while (((rc = connect(local_socket, remote, remote_size)) != 0) && (cntr < RES_PORT_RETRY)) { cntr++; /* fprintf(stdout, "rc != 0 (%d)-(%d) (port_number=%d)\n", rc, errno, *local_socket); */ switch (errno) { case ECONNREFUSED: /* Connection refused */ snprintf(tmp_buf, LOCAL_LOG_BUF_SIZE, "cannot connect to port %d in %s - connection refused", local_socket, id); *error_msg = strdup(tmp_buf); rc = PBS_NET_RC_RETRY; close(local_socket); local_socket = -1; break; case EINPROGRESS: /* Operation now in progress */ case EALREADY: /* Operation already in progress */ case EISCONN: /* Transport endpoint is already connected */ case ETIMEDOUT: /* Connection timed out */ case EAGAIN: /* Operation would block */ case EINTR: /* Interrupted system call */ if ((rc = socket_wait_for_write(local_socket)) == PBSE_NONE) { /* no network failures detected, socket available */ break; } /* socket not ready for writing after 5 timeout */ case EINVAL: /* Invalid argument */ case EADDRINUSE: /* Address already in use */ case EADDRNOTAVAIL: /* Cannot assign requested address */ if (is_privileged) { rc = PBSE_SOCKET_FAULT; /* 3 connect attempts are made to each socket */ /* Fail on RES_PORT_RETRY */ if (cntr < RES_PORT_RETRY) { close(local_socket); if ((local_socket = socket_get_tcp_priv()) < 0) rc = PBSE_SOCKET_FAULT; else { rc = PBSE_NONE; continue; } } else { close(local_socket); local_socket = -1; } } break; default: snprintf(tmp_buf, LOCAL_LOG_BUF_SIZE, "cannot connect to port %d in %s - errno:%d %s", local_socket, id, errno, strerror(errno)); *error_msg = strdup(tmp_buf); close(local_socket); rc = PBSE_SOCKET_FAULT; local_socket = -1; break; } } if (rc == PBSE_NONE) *socket = local_socket; return rc; } /* END socket_connect() */
void *process_svr_conn( void *sock) { const char *className = "trqauthd"; int rc = PBSE_NONE; char *server_name = NULL; int server_port = 0; int auth_type = 0; char *user_name = NULL; int user_pid = 0; int user_sock = 0; char *error_msg = NULL; std::string message; int send_len = 0; char *trq_server_addr = NULL; int trq_server_addr_len = 0; int svr_sock = -1; int msg_len = 0; int debug_mark = 0; int local_socket = *(int *)sock; char msg_buf[1024]; long long req_type; /* Type of request coming in */ rc = socket_read_num(local_socket, &req_type); if (rc == PBSE_NONE) { switch (req_type) { case TRQ_DOWN_TRQAUTHD: { rc = parse_terminate_request(local_socket, &user_name, &user_pid); if (rc != PBSE_NONE) break; /* root is the only user that can terminate trqauthd */ if (strcmp(user_name, "root")) { rc = PBSE_PERM; break; } rc = validate_user(local_socket, user_name, user_pid, msg_buf); if (rc == PBSE_NONE) { trqauthd_up = false; rc = build_active_server_response(message); } break; } case TRQ_PING_SERVER: case TRQ_GET_ACTIVE_SERVER: { /* rc will get evaluated after the switch statement. */ rc = build_active_server_response(message); break; } case TRQ_VALIDATE_ACTIVE_SERVER: { if ((rc = validate_server(server_name, server_port, NULL, NULL)) != PBSE_NONE) { break; } else if ((rc = build_active_server_response(message)) != PBSE_NONE) { break; } break; } case TRQ_AUTH_CONNECTION: { int disconnect_svr = TRUE; /* incoming message format is: * trq_system_len|trq_system|trq_port|Validation_type|user_len|user|pid|psock| * message format to pbs_server is: * +2+22+492+user+sock+0 * format from pbs_server is: * +2+2+0+0+1 * outgoing message format is: * #|msg_len|message| * Send response to client here!! * Disconnect message to svr: * +2+22+592+{user_len}{user} * * msg to client in the case of success: * 0|0|| */ if ((rc = parse_request_client(local_socket, &server_name, &server_port, &auth_type, &user_name, &user_pid, &user_sock)) != PBSE_NONE) { disconnect_svr = FALSE; debug_mark = 1; } else { int retries = 0; while (retries < MAX_RETRIES) { rc = PBSE_NONE; disconnect_svr = TRUE; if ((rc = validate_user(local_socket, user_name, user_pid, msg_buf)) != PBSE_NONE) { log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, __func__, msg_buf); disconnect_svr = FALSE; debug_mark = 1; retries++; usleep(20000); continue; } else if ((rc = get_trq_server_addr(server_name, &trq_server_addr, &trq_server_addr_len)) != PBSE_NONE) { disconnect_svr = FALSE; debug_mark = 2; retries++; usleep(20000); continue; } else if ((svr_sock = socket_get_tcp_priv()) < 0) { rc = PBSE_SOCKET_FAULT; disconnect_svr = FALSE; debug_mark = 3; retries++; usleep(10000); continue; } else if ((rc = socket_connect(&svr_sock, trq_server_addr, trq_server_addr_len, server_port, AF_INET, 1, &error_msg)) != PBSE_NONE) { /* for now we only need ssh_key and sign_key as dummys */ char *ssh_key = NULL; char *sign_key = NULL; char log_buf[LOCAL_LOG_BUF_SIZE]; validate_server(server_name, server_port, ssh_key, &sign_key); sprintf(log_buf, "Active server is %s", active_pbs_server); log_event(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, __func__, log_buf); disconnect_svr = FALSE; debug_mark = 4; socket_close(svr_sock); retries++; usleep(50000); continue; } else if ((rc = build_request_svr(auth_type, user_name, user_sock, message)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = FALSE; debug_mark = 5; retries++; usleep(50000); continue; } else if ((send_len = message.length()) <= 0) { socket_close(svr_sock); disconnect_svr = FALSE; rc = PBSE_INTERNAL; debug_mark = 6; retries++; usleep(50000); continue; } else if ((rc = socket_write(svr_sock, message.c_str(), send_len)) != send_len) { socket_close(svr_sock); disconnect_svr = FALSE; rc = PBSE_SOCKET_WRITE; debug_mark = 7; retries++; usleep(50000); continue; } else if ((rc = parse_response_svr(svr_sock, &error_msg)) != PBSE_NONE) { socket_close(svr_sock); disconnect_svr = FALSE; debug_mark = 8; retries++; usleep(50000); continue; } else { /* Success case */ message = "0|0||"; if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d success. Conn %d authorized\n", server_name, server_port, user_sock); } snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d logged in", user_name, server_name, server_port); log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } break; } } if (TRUE == disconnect_svr) { send_svr_disconnect(svr_sock, user_name); socket_close(svr_sock); } break; } default: rc = PBSE_IVALREQ; break; } } else { sprintf(msg_buf, "socket_read_num failed: %d", rc); log_record(PBSEVENT_CLIENTAUTH, PBS_EVENTCLASS_TRQAUTHD, __func__, msg_buf); } #ifdef UNIT_TEST /* process_svr_conn_rc is used by ./test/trq_auth/test_trq_auth.c to discover the status of unit test calls to process_svr_conn */ process_svr_conn_rc = rc; #endif if (rc != PBSE_NONE) { /* Failure case */ msg_len = 6 + 1 + 6 + 1 + 1; if (error_msg == NULL) { char *tmp_err = pbse_to_txt(rc); if (tmp_err != NULL) error_msg = strdup(tmp_err); else error_msg = strdup(""); } msg_len += strlen(error_msg); message = string_format("%d|%d|%s|",rc,strlen(error_msg),error_msg); if (debug_mode == TRUE) { fprintf(stderr, "Conn to %s port %d Fail. Conn %d not authorized (dm = %d, Err Num %d)\n", server_name, server_port, user_sock, debug_mark, rc); } snprintf(msg_buf, sizeof(msg_buf), "User %s at IP:port %s:%d login attempt failed --%s", (user_name) ? user_name : "null", (server_name) ? server_name : "null", server_port, (error_msg) ? error_msg : "null"); log_record(PBSEVENT_CLIENTAUTH | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, className, msg_buf); } if (message.length() != 0) rc = socket_write(local_socket, message.c_str(), message.length()); if (trq_server_addr != NULL) free(trq_server_addr); if (server_name != NULL) free(server_name); if (user_name != NULL) free(user_name); if (error_msg != NULL) free(error_msg); socket_close(local_socket); free(sock); return(NULL); } /* END process_svr_conn() */