/* * Starnet Data Accounting Client * Open Source Version, 1.0 * * February 2000 Matt Chapman and Shuying Wang * Comments to */ #include #include #include #include #include #include #include #define SDAS_HOST "129.94.197.99" #define SDAS_PORT 8000 #define CLIENT_VERSION "Linux-Open-1.0" #define LOGON 1 #define LOGOFF 2 /* Prompt for and read a line of input */ int read_line(char *buffer, int size, char *prompt, int hide_input) { struct termios saved_attr, new_attr; char *p; printf("%s", prompt); if (hide_input) { tcgetattr(STDIN_FILENO, &saved_attr); new_attr = saved_attr; new_attr.c_lflag &= ~ECHO; tcsetattr(STDIN_FILENO, TCSANOW, &new_attr); } if (fgets(buffer, size, stdin) == NULL) return -1; p = strchr(buffer, '\n'); if (p != NULL) *p = 0; if (hide_input) { printf("\n"); tcsetattr(STDIN_FILENO, TCSANOW, &saved_attr); } return 0; } /* Establish a TCP connection */ int connect_server(char *server) { struct hostent *nslookup; struct sockaddr_in servaddr; int sock; if ((nslookup = gethostbyname(server)) != NULL) { memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr)); } else if (!(servaddr.sin_addr.s_addr = inet_addr(server))) { fprintf(stderr, "%s: unable to resolve host\n", server); return -1; } if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return -1; } servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SDAS_PORT); if (connect(sock, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) < 0) { perror("connect"); close(sock); return -1; } return sock; } /* Get a string representing the local IP address of a socket */ char *get_localip(int sock) { struct sockaddr_in cliaddr; socklen_t len = sizeof(cliaddr); getsockname(sock, &cliaddr, &len); return inet_ntoa(cliaddr.sin_addr); } /* Encode a string using a sliding Caesar cipher (length 7) */ void encode(char *string, int length) { int i; for (i = 0; i < length; i++) { string[i] += i % 7; } } /* Decode a string using a sliding Caesar cipher (length 7) */ void decode(char *string, int length) { int i; for (i = 0; i < length; i++) { string[i] -= i % 7; } } /* Program entrypoint */ int main(int argc, char *argv[]) { char buffer[128]; char username[32]; char password[32]; int got_username = 0, got_password = 0; int operation = LOGON; char *opname = "on"; int sock, len; char *p; /* Log off if name of executable is sdalogoff */ p = strrchr(argv[0], '/'); if (p == NULL) p = argv[0]; else p++; if ((strcmp(p, "sdalogout") == 0) || (strcmp(p, "sdalogoff") == 0)) { operation = LOGOFF; opname = "off"; got_password = 1; strncpy(password, "x", sizeof(password)); } /* Read username and password from command line if present */ if (argc >= 2) { got_username = 1; strncpy(username, argv[1], sizeof(username)); } if (argc >= 3) { got_password = 1; strncpy(password, argv[1], sizeof(password)); } printf("Starnet Data Accounting Client (%s) - Logging %s\n", CLIENT_VERSION, opname); /* Prompt for username and password if necessary */ if (!got_username && (read_line(username, sizeof(username), "Username: ", 0) == -1)) return 1; if (!got_password && (read_line(password, sizeof(password), "Password: ", 1) == -1)) return 1; /* Connect to server */ sock = connect_server(SDAS_HOST); if (sock == -1) return 1; /* Send request to server */ len = snprintf(buffer, sizeof(buffer), "%d %s %s %s 0 %s ", operation, username, password, get_localip(sock), CLIENT_VERSION); encode(buffer, len); write(sock, buffer, len); /* Receive response */ len = read(sock, buffer, sizeof(buffer)-1); if (len < 0) { perror("read"); return 1; } /* Decode response */ buffer[len] = 0; decode(buffer, len); printf("%s\n", buffer); close(sock); return 0; }