sshpacketparser.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /**************************************************************************
  2. **
  3. ** This file is part of Qt Creator
  4. **
  5. ** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
  6. **
  7. ** Contact: http://www.qt-project.org/
  8. **
  9. **
  10. ** GNU Lesser General Public License Usage
  11. **
  12. ** This file may be used under the terms of the GNU Lesser General Public
  13. ** License version 2.1 as published by the Free Software Foundation and
  14. ** appearing in the file LICENSE.LGPL included in the packaging of this file.
  15. ** Please review the following information to ensure the GNU Lesser General
  16. ** Public License version 2.1 requirements will be met:
  17. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  18. **
  19. ** In addition, as a special exception, Nokia gives you certain additional
  20. ** rights. These rights are described in the Nokia Qt LGPL Exception
  21. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  22. **
  23. ** Other Usage
  24. **
  25. ** Alternatively, this file may be used in accordance with the terms and
  26. ** conditions contained in a signed written agreement between you and Nokia.
  27. **
  28. **
  29. **************************************************************************/
  30. #include "sshpacketparser_p.h"
  31. #include <cctype>
  32. #include <QtEndian>
  33. namespace QSsh {
  34. namespace Internal {
  35. namespace { quint32 size(const QByteArray &data) { return data.size(); } }
  36. QString SshPacketParser::asUserString(const QByteArray &rawString)
  37. {
  38. QByteArray filteredString;
  39. filteredString.resize(rawString.size());
  40. for (int i = 0; i < rawString.size(); ++i) {
  41. const char c = rawString.at(i);
  42. filteredString[i]
  43. = std::isprint(c) || c == '\n' || c == '\r' || c == '\t' ? c : '?';
  44. }
  45. return QString::fromUtf8(filteredString);
  46. }
  47. bool SshPacketParser::asBool(const QByteArray &data, quint32 offset)
  48. {
  49. if (size(data) <= offset)
  50. throw SshPacketParseException();
  51. return data.at(offset);
  52. }
  53. bool SshPacketParser::asBool(const QByteArray &data, quint32 *offset)
  54. {
  55. bool b = asBool(data, *offset);
  56. ++(*offset);
  57. return b;
  58. }
  59. quint32 SshPacketParser::asUint32(const QByteArray &data, quint32 offset)
  60. {
  61. if (size(data) < offset + 4)
  62. throw SshPacketParseException();
  63. return qFromBigEndian<quint32>(data.constData() + offset);
  64. }
  65. quint32 SshPacketParser::asUint32(const QByteArray &data, quint32 *offset)
  66. {
  67. const quint32 v = asUint32(data, *offset);
  68. *offset += 4;
  69. return v;
  70. }
  71. quint64 SshPacketParser::asUint64(const QByteArray &data, quint32 offset)
  72. {
  73. if (size(data) < offset + 8)
  74. throw SshPacketParseException();
  75. return qFromBigEndian<quint64>(data.constData() + offset);
  76. }
  77. quint64 SshPacketParser::asUint64(const QByteArray &data, quint32 *offset)
  78. {
  79. const quint64 val = asUint64(data, *offset);
  80. *offset += 8;
  81. return val;
  82. }
  83. QByteArray SshPacketParser::asString(const QByteArray &data, quint32 offset)
  84. {
  85. return asString(data, &offset);
  86. }
  87. QByteArray SshPacketParser::asString(const QByteArray &data, quint32 *offset)
  88. {
  89. const quint32 length = asUint32(data, offset);
  90. if (size(data) < *offset + length)
  91. throw SshPacketParseException();
  92. const QByteArray &string = data.mid(*offset, length);
  93. *offset += length;
  94. return string;
  95. }
  96. QString SshPacketParser::asUserString(const QByteArray &data, quint32 *offset)
  97. {
  98. return asUserString(asString(data, offset));
  99. }
  100. SshNameList SshPacketParser::asNameList(const QByteArray &data, quint32 *offset)
  101. {
  102. const quint32 length = asUint32(data, offset);
  103. const int listEndPos = *offset + length;
  104. if (data.size() < listEndPos)
  105. throw SshPacketParseException();
  106. SshNameList names(length + 4);
  107. int nextNameOffset = *offset;
  108. int nextCommaOffset = data.indexOf(',', nextNameOffset);
  109. while (nextNameOffset > 0 && nextNameOffset < listEndPos) {
  110. const int stringEndPos = nextCommaOffset == -1
  111. || nextCommaOffset > listEndPos ? listEndPos : nextCommaOffset;
  112. names.names << QByteArray(data.constData() + nextNameOffset,
  113. stringEndPos - nextNameOffset);
  114. nextNameOffset = nextCommaOffset + 1;
  115. nextCommaOffset = data.indexOf(',', nextNameOffset);
  116. }
  117. *offset += length;
  118. return names;
  119. }
  120. Botan::BigInt SshPacketParser::asBigInt(const QByteArray &data, quint32 *offset)
  121. {
  122. const quint32 length = asUint32(data, offset);
  123. if (length == 0)
  124. return Botan::BigInt();
  125. const Botan::byte *numberStart
  126. = reinterpret_cast<const Botan::byte *>(data.constData() + *offset);
  127. *offset += length;
  128. return Botan::BigInt::decode(numberStart, length);
  129. }
  130. } // namespace Internal
  131. } // namespace QSsh