#include #include #include #include #include #include #include #include #include #include #include //IPv6 #include #include #include #include #include #include #include #include #include "node.h" ax25io *NodeIo = NULL; void node_prompt(); int aliascmd = 0; /* * Do some validity checking for callsign pointed to by `s'. */ static int check_call(const char *s) { int len = 0; int nums = 0; int ssid = 0; char *p[1]; if (s == NULL) return -1; while (*s && *s != '-') { if (!isalnum(*s)) return -1; if (isdigit(*s)) nums++; len++; s++; } if (*s == '-') { if (!isdigit(*++s)) return -1; ssid = strtol(s, p, 10); if (**p) return -1; } if (len < 4 || len > 6 || !nums || nums > 2 || ssid < 0 || ssid > 15) return -1; return 0; } static void alarm_handler(int sig) { axio_eolmode(NodeIo, EOLMODE_TEXT); axio_puts("\n",NodeIo); if (check_perms(PERM_ANSI, 0L) != -1) { axio_printf(NodeIo,"\e[05;31m"); } if (User.ul_type == AF_NETROM) { node_msg("%s} Inactivity timeout! Closing circuit... ", NodeId); } if ((User.ul_type == AF_AX25) || (User.ul_type == AF_ROSE)) { node_msg("Inactivity timeout! Disconnecting you... "); } if ((User.ul_type == AF_INET) || (User.ul_type == AF_INET6)) { node_msg("Inactivity timeout! Disconnecting you..."); } if ((User.ul_type == AF_INET) || (User.ul_type == AF_INET6)) { if (check_perms(PERM_ANSI, 0L) != -1) { axio_printf(NodeIo,"\e[0;m"); } } node_logout("User timed out"); } static void term_handler(int sig) { axio_eolmode(NodeIo, EOLMODE_TEXT); if (User.ul_type == AF_NETROM) { node_msg("%s} Termination received!", NodeId); } else { node_msg("%s - System going down! Disconnecting...", FlexId); } node_logout("SIGTERM"); } static void quit_handler(int sig) { axio_eolmode(NodeIo, EOLMODE_TEXT); node_logout("User terminated at remote"); } int main(int argc, char *argv[]) { union { struct full_sockaddr_ax25 sax; #ifdef HAVE_ROSE struct sockaddr_rose srose; #endif struct sockaddr_in sin; } saddr; int i, slen = sizeof(saddr); #ifdef HAVEMOTD char *p, buf[256], *pw; #else char *p, *pw; #endif int paclen; #ifdef HAVEMOTD FILE *fp; #endif int invalid_cmds = 0; int no_password = 2; int first_time = 1; signal(SIGALRM, alarm_handler); signal(SIGTERM, term_handler); signal(SIGPIPE, quit_handler); signal(SIGQUIT, quit_handler); #ifdef HAVE_AX25 if (ax25_config_load_ports() == 0) { node_log(LOGLVL_ERROR, "No AX.25 port data configured"); return 1; } #endif #ifdef HAVE_NETROM nr_config_load_ports(); #endif #ifdef HAVE_ROSE rs_config_load_ports(); #endif if (getpeername(STDOUT_FILENO, (struct sockaddr *)&saddr, &slen) == -1) { if (errno != ENOTSOCK) { node_log(LOGLVL_ERROR, "getpeername: %s", strerror(errno)); return 1; } User.ul_type = AF_UNSPEC; } else User.ul_type = saddr.sax.fsa_ax25.sax25_family; switch (User.ul_type) { case AF_FLEXNET: case AF_AX25: strcpy(User.call, ax25_ntoa(&saddr.sax.fsa_ax25.sax25_call)); if (getsockname(STDOUT_FILENO, (struct sockaddr *)&saddr.sax, &slen) == -1) { node_log(LOGLVL_ERROR, "getsockname: %s", strerror(errno)); return 1; } strcpy(User.ul_name, ax25_config_get_port(&saddr.sax.fsa_digipeater[0])); paclen = ax25_config_get_paclen(User.ul_name); p = AX25_EOL; break; case AF_NETROM: strcpy(User.call, ax25_ntoa(&saddr.sax.fsa_ax25.sax25_call)); strcpy(User.ul_name, ax25_ntoa(&saddr.sax.fsa_digipeater[0])); if (getsockname(STDOUT_FILENO, (struct sockaddr *)&saddr.sax, &slen) == -1) { node_log(LOGLVL_ERROR, "getsockname: %s", strerror(errno)); return 1; } strcpy(User.ul_port, nr_config_get_port(&saddr.sax.fsa_ax25.sax25_call)); paclen = nr_config_get_paclen(User.ul_port); p = NETROM_EOL; break; #ifdef HAVE_ROSE case AF_ROSE: strcpy(User.call, ax25_ntoa(&saddr.srose.srose_call)); strcpy(User.ul_name, rose_ntoa(&saddr.srose.srose_addr)); paclen = rs_config_get_paclen(NULL); p = ROSE_EOL; break; #endif case AF_INET: case AF_INET6: strcpy(User.ul_name, inet_ntoa(saddr.sin.sin_addr)); paclen = 1024; p = INET_EOL; break; case AF_UNSPEC: strcpy(User.ul_name, "local"); if ((p = get_call(getuid())) == NULL) { node_log(LOGLVL_ERROR, "No uid->callsign association found", -1); printf("Launching: telnet localhost 3694 ...\n"); printf("if this fails please RTFM to see how to properly configure it.\n - 73 de N1URO\a\n"); node_log(LOGLVL_ERROR, "Tool ran me from the console so I'm forcing", -1); node_log(LOGLVL_ERROR, "a telnet session to port 3694/tcp on them.", -1); /* axio_flush(NodeIo); */ if(NodeIo!=NULL) axio_flush(NodeIo); if (system("telnet localhost 3694") < 0 ) { /* VE3TOK - 18Nov2014, return value */ syslog(LOG_DEBUG, "Can't \"execute telnet ::1 or 127.0.0.1 3694\""); return 1; } node_log(LOGLVL_ERROR,"Closing console telnet session.", -1); return -1; } strcpy(User.call, p); paclen = 1024; p = UNSPEC_EOL; break; default: node_log(LOGLVL_ERROR, "Unsupported address family %d", User.ul_type); return 1; } NodeIo = axio_init(STDIN_FILENO, STDOUT_FILENO, paclen, p); if (NodeIo == NULL) { node_log(LOGLVL_ERROR, "Error initializing I/O"); return 1; } #ifdef HAVE_ZLIB_H if (argc > 1 && strcmp(argv[1], "-c") == 0) { axio_compr(NodeIo, 1); } #endif if ((User.ul_type == AF_INET) || (User.ul_type == AF_INET6)) { axio_tnmode(NodeIo, 1); axio_tn_do_linemode(NodeIo); } init_nodecmds(); if (read_config() == -1) { axio_end(NodeIo); return 1; } for(i=1;i