/** * @function poll_fsa * @brief Update our finite state machine if any messages from Bluetooth or ACH came through */ void Test2_Server::poll_fsa() { if( mMsg_received_flag ) { // Exception messages if( mMsg_type == RESET_MSG ) { reset_server(); } else if( mMsg_type == GO_BACK_MSG ) { printf("Go back was gotten in poll fsa \n"); goBack(); } else { int action = mFsa.evaluate( mMsg_source, mMsg_type ); if( action != NO_ACTION ) { this->do_action( action ); } } // Reset msg flag mMsg_received_flag = false; // Optional: Show state name for easy debugging this->showStateName(); } }
int tac_account_read(tacacs_conf_t *conf, tacacs_server_t *server, const char **ret_err_msg) { int err = 0; HDR th; struct acct_reply *tb = NULL; int len_from_header, r, len_from_body; const char *msg = NULL; int msg_len, data_len; if (ret_err_msg == NULL) { syslog(LOG_ERR, "%s: error no err msg buffer provided", __FUNCTION__); err = -1; goto bail; } *ret_err_msg = NULL; if (server == NULL) { syslog(LOG_ERR, "%s: error no TACACS+ server specified", __FUNCTION__); err = -1; *ret_err_msg = no_server_err_msg; goto bail; } reset_server(server, FALSE); r=read(conf->sockfd, &th, TAC_PLUS_HDR_SIZE); if(r < TAC_PLUS_HDR_SIZE) { syslog(LOG_ERR, "%s: short acct header, %d of %d: %m", __FUNCTION__, r, TAC_PLUS_HDR_SIZE); err = -1; *ret_err_msg = r == 0 ? "No response from server" : "Truncated response from server"; goto bail; } /* check the reply fields in header */ err = _tac_check_header(&th, TAC_PLUS_ACCT, server, &msg); if (err) { *ret_err_msg = msg; goto bail; } len_from_header=ntohl(th.datalength); tb=(struct acct_reply *) xcalloc(1, len_from_header); /* read reply packet body */ r=read(conf->sockfd, tb, len_from_header); if(r < len_from_header) { syslog(LOG_ERR, "%s: incomplete message body, %d bytes, expected %d: %m", __FUNCTION__, r, len_from_header); err = -1; *ret_err_msg = r == 0 ? "Empty response message from server" : "Incomplete response message from server"; goto bail; } /* decrypt the body */ _tac_crypt(server->secret, (u_char *) tb, &th, len_from_header); msg_len = tb->msg_len; data_len = tb->data_len; /* check the length fields */ len_from_body=sizeof(tb->msg_len) + sizeof(tb->data_len) + sizeof(tb->status) + msg_len + data_len; if(len_from_header != len_from_body) { syslog(LOG_ERR, "%s: invalid reply content, incorrect key?", __FUNCTION__); err = -1; *ret_err_msg = system_err_msg; goto bail; } /* save status and clean up */ r=tb->status; if(msg_len) { server->server_msg=(char *) xcalloc(1, msg_len); bcopy(tb+TAC_ACCT_REPLY_FIXED_FIELDS_SIZE, server->server_msg, msg_len); *ret_err_msg = server->server_msg; } /* server logged our request successfully */ if(r == TAC_PLUS_ACCT_STATUS_SUCCESS) { TACDEBUG((LOG_DEBUG, "%s: accounted ok", __FUNCTION__)); *ret_err_msg = NULL; } else { /* return pointer to server message */ syslog(LOG_ERR, "%s: accounting failed, server reply was %d " "(%s)", __FUNCTION__, r, server->server_msg); if (*ret_err_msg == NULL) { *ret_err_msg = "Accounting failed"; } err = -1; goto bail; } bail: if (tb) { free(tb); } return(err); }
/* * reads packet from TACACS+ server; returns: NULL if the authentication * succeded string pointer if it failed */ int tac_authen_read(tacacs_conf_t *conf, tacacs_server_t *server, const char **ret_err_msg, int *ret_status) { HDR th; struct authen_reply *tb = NULL; int len_from_header, r, len_from_body; int serv_msg_len, data_len; char *msg = NULL; int err = 0; if (ret_status) { *ret_status = TAC_PLUS_AUTHEN_STATUS_ERROR; } if (ret_err_msg == NULL) { syslog(LOG_ERR, "%s: error no err msg buffer provided", __FUNCTION__); err = -1; goto bail; } *ret_err_msg = NULL; if (server == NULL) { syslog(LOG_ERR, "%s: error no TACACS+ server specified", __FUNCTION__); err = -1; *ret_err_msg = no_server_err_msg; goto bail; } /* Free from any previous server messages */ reset_server(server, FALSE); /* * read the reply header * XXX it would appear that the reads are being done on non-blocking * sockets. This should be fixed to deal with partial reads. */ r = read(conf->sockfd, &th, TAC_PLUS_HDR_SIZE); if (r < TAC_PLUS_HDR_SIZE) { syslog(LOG_ERR, "%s: error reading authen header, read %d of %d: %m", __FUNCTION__, r, TAC_PLUS_HDR_SIZE); *ret_err_msg = system_err_msg; err = -1; goto bail; } /* check the reply fields in header */ err = _tac_check_header(&th, TAC_PLUS_AUTHEN, server, ret_err_msg); if (err) { goto bail; } len_from_header = ntohl(th.datalength); tb = (struct authen_reply *) xcalloc(1, len_from_header); /* read reply packet body */ r = read(conf->sockfd, tb, len_from_header); if (r < len_from_header) { syslog(LOG_ERR, "%s: incomplete message body, %d bytes, expected %d: %m", __FUNCTION__, r, len_from_header); *ret_err_msg = system_err_msg; err = -1; goto bail; } /* decrypt the body */ _tac_crypt(server->secret, (u_char *) tb, &th, len_from_header); serv_msg_len = ntohs(tb->msg_len); data_len = ntohs(tb->data_len); /* check the length fields */ len_from_body = sizeof(tb->status) + sizeof(tb->flags) + sizeof(tb->msg_len) + sizeof(tb->data_len) + serv_msg_len + data_len; if (len_from_header != len_from_body) { syslog(LOG_ERR, "%s: invalid reply content, incorrect key? (calc %d, hdr %d)", __FUNCTION__, len_from_body, len_from_header); *ret_err_msg = system_err_msg; err = -1; goto bail; } /* Save off any message or data returned by the server */ if (serv_msg_len) { server->server_msg = (char *) xcalloc(1, serv_msg_len); bcopy(tb + TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE, server->server_msg, serv_msg_len); /* Show user what the server said */ *ret_err_msg = server->server_msg; } if (data_len) { server->data = (char *) xcalloc(1, data_len); bcopy(tb + TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE + serv_msg_len, server->data, data_len); } /* save status and clean up */ r = tb->status; if (ret_status) { *ret_status = r; } switch (r) { case TAC_PLUS_AUTHEN_STATUS_PASS: /* server authenticated username and password successfully */ break; case TAC_PLUS_AUTHEN_STATUS_FAIL: if (*ret_err_msg == NULL) { *ret_err_msg = auth_fail_msg; } err = -1; break; case TAC_PLUS_AUTHEN_STATUS_GETDATA: case TAC_PLUS_AUTHEN_STATUS_GETUSER: case TAC_PLUS_AUTHEN_STATUS_GETPASS: break; case TAC_PLUS_AUTHEN_STATUS_ERROR: syslog(LOG_ERR, "%s: TACACS+ authentication failed, server detected error", __FUNCTION__); err = -1; break; case TAC_PLUS_AUTHEN_STATUS_RESTART: case TAC_PLUS_AUTHEN_STATUS_FOLLOW: default: syslog(LOG_ERR, "%s: TACACS+ authentication failed, unexpected status %#x", __FUNCTION__, r); if (*ret_err_msg == NULL) { *ret_err_msg = unexpected_status_msg; } err = -1; break; } bail: if (err && (*ret_err_msg == NULL)) { /* At least say something bad */ *ret_err_msg = bad_login_msg; } if (tb) { free(tb); tb = NULL; } return(err); }
/*------------------------------------------------------------------------ * MAIN PROGRAM *------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { int server_fd, client_fd; struct sockaddr_in remote_address; socklen_t remote_length = sizeof(struct sockaddr_in); ttp_parameter_t parameter; ttp_session_t session; pid_t child_pid; /* initialize our parameters */ memset(&session, 0, sizeof(session)); reset_server(¶meter); /* process our command-line options */ process_options(argc, argv, ¶meter); /* obtain our server socket */ server_fd = create_tcp_socket(¶meter); if (server_fd < 0) { sprintf(g_error, "Could not create server socket on port %d", parameter.tcp_port); return error(g_error); } /* install a signal handler for our children */ signal(SIGCHLD, reap); /* now show version / build information */ #ifdef VSIB_REALTIME fprintf(stderr, "Tsunami Realtime Server for protocol rev %X\nRevision: %s\nCompiled: %s %s\n" " /dev/vsib VSIB accesses mode=%d, sample skip=%d, gigabit=%d, 1pps embed=%d\n" "Waiting for clients to connect.\n", PROTOCOL_REVISION, TSUNAMI_CVS_BUILDNR, __DATE__ , __TIME__, vsib_mode, vsib_mode_skip_samples, vsib_mode_gigabit, vsib_mode_embed_1pps_markers); #else fprintf(stderr, "Tsunami Server for protocol rev %X\nRevision: %s\nCompiled: %s %s\n" "Waiting for clients to connect.\n", PROTOCOL_REVISION, TSUNAMI_CVS_BUILDNR, __DATE__ , __TIME__); #endif /* while our little world keeps turning */ while (1) { /* accept a new client connection */ client_fd = accept(server_fd, (struct sockaddr *) &remote_address, &remote_length); if (client_fd < 0) { warn("Could not accept client connection"); continue; } else { fprintf(stderr, "New client connecting from %s...\n", inet_ntoa(remote_address.sin_addr)); } /* and fork a new child process to handle it */ child_pid = fork(); if (child_pid < 0) { warn("Could not create child process"); continue; } session.session_id++; /* if we're the child */ if (child_pid == 0) { /* close the server socket */ close(server_fd); /* set up the session structure */ session.client_fd = client_fd; session.parameter = ¶meter; memset(&session.transfer, 0, sizeof(session.transfer)); session.transfer.ipd_current = 0.0; /* and run the client handler */ client_handler(&session); return 0; /* if we're the parent */ } else { /* close the client socket */ close(client_fd); } } }