⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sftpc.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  }  CMD("prot") {    NO_ARG1 {      cout << "current data protection level: "            << getDSLString(dataSecLevel) << endl;    }    ARG1("p") {      setDataEncryption(DSL_PRIVATE);    }    ARG1("c") {      setDataEncryption(DSL_CLEAR);    }    ARG1("t") {      // deliberately avoiding 's' because I botched its meaning earlier      setDataEncryption(DSL_INTEGRITY);    }    ELSE_BAD_ARG1  }  // -------- "ftp"-like protocol actions ------------  CMD("pwd") {    checkedRequest(CMD_PWD);  }  CMD("cd") {    if (tok >= 1) {      checkedRequest(CMD_CWD, command + tok.offset(1));    // issues with spaces..    }    else {      checkedRequest(CMD_CWD);       // cd to home directory    }  }  CMD("cdup") {    checkedRequest(CMD_CDUP);  }  CMD("dir") {    dataTransfer(CMD_LIST, arg1, NULL);  }  CMD("nlist") {    dataTransfer(CMD_NLST, arg1, NULL);  }  CMD("get") {    REQUIRE_ARGS(1);    dataTransfer(CMD_RETR, arg1, arg2? arg2 : arg1);  }  CMD("put") {    REQUIRE_ARGS(1);    if (arg2 != NULL) {      dataTransfer(CMD_STOR, arg2 /*remote*/, arg1 /*local*/);    }    else {      dataTransfer(CMD_STOR, arg1, arg1);    }  }  CMD("mget") {    REQUIRE_ARGS(1);    mgetCommand(arg1);  }  CMD("mput") {    REQUIRE_ARGS(1);    mputCommand(arg1);  }  CMD("mls") {    REQUIRE_ARGS(1);    mlsCommand(arg1);  }  CMD("mdelete") {    REQUIRE_ARGS(1);    mdeleteCommand(arg1);  }  CMD("mkdir") {    REQUIRE_ARGS(1);    checkedRequest(CMD_MKD, arg1);  }  CMD("rmdir") {    REQUIRE_ARGS(1);    checkedRequest(CMD_RMD, arg1);  }  CMD("mv") {    REQUIRE_ARGS(2);    checkedRequest(CMD_RNFR, arg1);    checkedRequest(CMD_RNTO, arg2);  }  CMD("abort") {    checkedRequest(CMD_ABOR);  }  CMD("rm") {    REQUIRE_ARGS(1);    checkedRequest(CMD_DELE, arg1);  }  // -------------------- help -------------------------  CMD("help") {    // detailed command documentation strings are now in sftpcdoc.cpp    NO_ARG1 {      cout <<        "sftpc is a command-line SafeTP client.  SafeTP is File Transfer\n"        "Protocol (FTP), with cryptographic authentication and privacy.\n"        "More information: http://safetp.cs.berkeley.edu\n"        "\n"        "Here are some of the most common commands:\n";      printCommandList(true /*common*/);    }    ARG1("commands") {      cout << "Common commands:\n";      printCommandList(true /*common*/);      cout << "Less-common commands:\n";      printCommandList(false /*common*/);    }    ARG1("aliases") {      cout << "Command             Alias(es)\n"              "----------------    ---------------------";      char const *prevExp = "";      for (int i=0; i<numAliases; i++) {        char const *e = aliases[i].expansion;        char const *a = aliases[i].alias;        if (0==strcmp(prevExp, e)) {          // add this alias to the current line          cout << ", " << a;        }        else {          // start a new line          prevExp = e;          cout << endl << e;          for (int s = strlen(e); s < 20; s++) {            cout << " ";          // pad to aliases column          }          cout << a;        }      }      cout << endl;    }    ARG1("crlf") {      cout <<        "Unfortunately, one of the most annoying incompatibilities\n"        "between unix and windows is the way text file lines are\n"        "separated.  unix separates lines with a single Line Feed (LF)\n"        "character, whereas windows separates lines with an LF followed\n"        "by a Carriage Return (CR) character.\n"        "\n"        "Thus, when transferring files between systems, it is important\n"        "to (1) distinguish text files from binary files (the latter do\n"        "not need translation, generally), and (2) tell the software which\n"        "ones to translate.  As far as this note goes, you're on your own\n"        "for (1).  (When in doubt, use binary, which is sftpc's default.)\n"        "\n"        "The FTP protocol handles this issue by specifying two transfer\n"        "modes, \"ascii\" and \"image\" (binary).  In image mode, files\n"        "are transferred without translation.  In ascii mode, files are\n"        "treated as text, and are transferred across the network with\n"        "CRLF separators, with each machine translating locally as necessary.\n"        "\n"        "To tell sftpc to transfer in ascii mode, use the \"ascii\"\n"        "command.  To transfer in image (binary) mode, use the \"binary\"\n"        "command.  Both commands affect all subsequent transfer operations,\n"        "until another \"ascii\" or \"binary\" command is issued.\n"        "\n"        "sftpc, when working with ascii data, will report things\n"        "that it finds suspicious.  In particular, data that is supposed\n"        "to be CRLF-separated, but contains LFs or CRs by themselves, is\n"        "suspicious.  Likewise, data that is supposed to be LF-separated,\n"        "but has CRs (any at all) is suspicious.  In both circumstances,\n"        "the number of suspicious bytes are reported, and they are\n"        "*removed* from the data stream.\n"        ;    }    else {      // check tables      int alias = findAlias(tok[1]);      int cmd = findCommand(tok[1]);      // shouldn't be documented as both      xassert(!( alias!=-1 && cmd!=-1 ));      if (alias != -1) {        // alias documentation        Alias const &a = aliases[alias];        cout << a.alias << ": alias for \""             << a.expansion << "\"\n";        // show docs for expanded command        userCommand(stringb("help " << a.expansion));      }      else if (cmd != -1) {        // command documentation        Command const &c = commands[cmd];        cout << c.name << " " << c.args << endl             << "  " << c.blurb << endl;        // per-argument descs        {          StrtokParse tok(c.arglines, "\n");          for (int t=0; t<tok; t++) {            cout << "    " << tok[t] << endl;          }        }        // description of command as a whole        {          StrtokParse tok(c.desc, "\n");          for (int t=0; t<tok; t++) {            cout << "  " << tok[t] << endl;          }        }      }      else {     // not found        cout << "Unknown help topic: " << tok[1]             << "\nTry \"help commands\"\n";      }    }  }  // --------------- last case ----------------  else {    // check aliases    int i = findAlias(tok[0]);    if (i != -1) {      // expand the alias and recursively call this fn      string expanded = aliases[i].expansion;      if (tok > 1) {        // append arguments; we only do this if there are arguments        // because otherwise we have a trailing space, which some        // ftpd's choke on        expanded = stringb(aliases[i].expansion << " " << afterCmd);      }      userCommand(expanded);    }    else {      // nothing matches      cout << "Unknown command: " << tok[0]           << "\nTry \"help\" or \"help commands\"\n";    }  }  // manual scoping (ug)  #undef WORDnIS  #undef CMDIS  #undef CMD  #undef NO_ARG1  #undef ARG1IS  #undef ARG1  #undef SET_VAR  #undef TOGGLE_VAR  #undef TOGGLE_ON_OFF_VAR  #undef REQUIRE_ARGS  #undef ELSE_BAD_ARG1}void SFTPC::dumpVariables(){  PVAL(security);  PVAL(securityName);  PVAL(serverPort);  PVAL(serverName);  PVAL(control);  //PVAL(dataBuffer);  PVAL(PBSZ);  //PVAL(digt);  PVAL(sentFirstAuth);  PVAL(authenticated);  cout << "data channel protection: " << getDSLString(dataSecLevel) << endl;  PVAL(requestedPBSZ);  PVAL(transferPassively);  PVAL(asciiTransfers);  PVAL(localConventionIsCRLF);  PVAL(printOutgoing);  PVAL(interactivePrompting);  PVAL(quitProgram);  PVAL(printHashMarks);  PVAL(useRfc959);  PVAL(acceptNewKeysSilently);  PVAL(auto959Dropdown);  PVAL(showDiagnostics);  PVAL(showAdats);  PVAL(useDebuggingLogin);  PVAL(quitAfterNegotiation);  PVAL(binaryTransferAnyway);  PVAL(localGlobbing);}int SFTPC::emptyResponseQueue(){  int ret=0;  // since we hang if there isn't a reply, we'd better check  while (control->hasUnprocessedData() ||         pollReadable(control->socket)) {    // improve user-friendliness on server closure    checkClosed(control->socket);    // may throw xSocket    // read reply    Reply reply = readReply();    // DIGT and ADAT processing    handleAdatAndDigt(reply);    // since we don't know what this reply was for,    // there isn't anything intelligent to do with    // its reply code, so we'll just ignore it    ret++;  }  return ret;}// interactive loop to login// returns false to tell caller to exit programbool SFTPC::login(){  if (useDebuggingLogin) {       // just me testing at home    // I should mention that this 'debug' login is *not* something    // sftpd treats differently.  Rather, it is the name of the    // account I have defined on my debugging ftp daemons for this    // purpose.  sftpd is oblivious to this fact.    checkedRequest(CMD_USER, "pepe");    checkedRequest(CMD_PASS, "pepe");    // clever password, eh?    // if no exception thrown, we're in    return true;  }  string defaultUsername = getCurrentUsername();  // loop until successful login  for(;;) {    // get username    cout << "\nUser name (Enter = " << defaultUsername << ")? ";    cout.flush();    string username;    cin >> username;    if (username == string("quit") || username == string("exit")) {      // I sometimes do this, trying to exit 'ftp', and it thinks it's      // a user name, and traps me in passwd prompt where ^C doesn't      // work.. so let's just take the obvious hint and bail.      return false;    }    if (username == string("")) {      username = defaultUsername;    }    try {      checkedRequest(CMD_USER, username);    }    catch (xReply &) {      // this is unlikely, because servers don't typically confirm      // whether a username is valid      //cout << x.why() << endl;      // we can always assume that a reply was already      // printed, so there's no need to print it here      continue;    }    // if the user name was accepted, let's change the    // default (for this session) to what the user just    // typed    defaultUsername = username;    // get password    string password;    if (username != string("ftp") &&        username != string("anonymous")) {      // read password without echoing to terminal      char const *prompt =        isControlChannelEncrypted()?          "Password: " :          "Password (will be sent as cleartext!): ";      password = readNonechoString(prompt);    }    else {      // for anonymous login, echo password, since most      // places want an email addr as a password      cout << "Anonymous login; email addr? ";      cout.flush();      cin >> password;    }    try {      checkedRequest(CMD_PASS, password);    }    catch (xReply &) {      //cout << x.why() << endl;      continue;    }    // done    return true;   // don't exit program  }}    // returns false to mean the server (or the current mode) cannot// support the requested security level; other errors yield exceptionsbool SFTPC::setDataEncryption(DataSecurityLevel newLevel){  if (useRfc959) {    cout << "sftpc: I am current in 959 (no encryption) mode, so\n"            "       data channel protection is unavailable.\n";    return false;  }  // if we're turning on data encryption for the first time,  // negotiate a PBSZ  if (!negotiatedPBSZ()) {    // fix: was checking that newLevel != DSL_CLEAR, but 2228    // specifies that PBSZ must come first even for "PROT C"    requestPBSZ();  }  // figure out how to communicate the desire for this protection  // level via the control channel  char protCode;  if (newLevel != DSL_CLEAR) {    xassert(newLevel & security->data().getSupportedProtLevels());    protCode = security->data().getCodeForLevel(newLevel);  }  else {    // cleartext is implemented in sftpc directly    protCode = 'C';  }  // do so  try {    checkedRequest(CMD_PROT, stringb(protCode));  }  catch (xReply &) {    cout << "The server does not support the requested data security level.\n";    return false;  }  // if it succeeded, we're in the new level  dataSecLevel = newLevel;  return true;}// for extracting things like "PBSZ=number"bool embeddedValue(int &value, char const *text, char const *prefix){  char const *p = strstr(text, prefix);  if (p != NULL) {    value = atoi(p+strlen(prefix));    return true;  }  else {    return false;  }}// general complaint about server's protocol behaviorvoid protocolError(char const *message){  // it would be nice to have an XProtocol or something

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -