Message Password Change
/* * Change message system password. Run as: * msgpass [ -e ] server [ port ] account * It will request old and new passwords, and attempt to change it * on the server. */ #include <iostream> #include <sstream> #include <string> #include <cctype> #include <cstdlib> #include <cleansocks.h> #include <cleanip.h> #include <cleanbuf.h> #include "getpass.h" using namespace cleansocks; /* Program name. */ std::string pname; /* Echo flag. If true, the program displays its conversation. */ bool echo = false; /* Print a message and exit. */ void wham(std::string msg) { /* See what message we have here. */ std::cerr << pname << ": " << msg << std::endl; exit(1); } /* Get a line from the server. Return code, negative for errors. If not the expected code, we will exit with a message. */ int getcode(buffered_socket &c, int expected) { // Get a line. Add a plain C string terminator to make a valid // plain C string with the \r\n removed. char buf[1024]; int n = recvln(c, buf, sizeof buf); buf[n - 2] = 0; // Echo the server response. if(echo) std::cout << "<< " << buf << std::endl; // Collect the info from the line. Use a C++ string stream to read // the line as though it were input. std::istringstream iss(buf); std::string resp; iss >> resp; int code; iss >> code >> std::ws; std::string emsg; getline(iss, emsg, '\r'); if(resp == "E") code = -code; // See if we got what was expected. if(code != expected) { close(c); if(code < 0) wham("Error: " + emsg); else wham("Unexpeced response: " + emsg); } return code; } /* Send a string the server, obeying the global echo flag and adding the \r\n */ void esend(buffered_socket &sock, std::string tosend) { if(echo) std::cout << ">> " << tosend << std::endl; send(sock, tosend + "\r\n"); } int main(int argc, char **argv) { // Program name. pname = argv[0]; // Set the global echo flag. echo = false; if(argc >= 2 && std::string(argv[1]) == "-e") { echo = true; --argc; ++argv; // Make it go away. } // Args! if(argc < 3 || argc > 4) wham("[ -e ] host [ port ] account"); // Convert the computer name. IPaddress comp = lookup_host(argv[1]); // Get the port number and the account name. IPport port = 45301; std::string account; if(isdigit(argv[2][0])) { port = atoi(argv[2]); account = argv[3]; } else account = argv[2]; TCPsocket tc; try { // Connect to the server and get the welcome msg. connect(tc, IPendpoint(comp, port)); buffered_socket conn(tc); getcode(conn, 100); // Try to log in. std::string pwd = getpass("Current password: "); esend(conn, "IAM " + account + " " + pwd); getcode(conn, 105); // Get new password from user. std::string p1 = getpass("New password: "); std::string p2 = getpass("Retype: "); if(p1 != p2) wham("Passwords don't match"); // Try to set it on the server. esend(conn, "CHP " + p1); getcode(conn, 106); // Wind up. esend(conn, "BYE"); getcode(conn, 107); close(conn); printf("Password changed.\n"); } catch(std::exception &e) { close(tc); wham(std::string("Exception: ") + e.what()); } }