Exemplo n.º 1
0
QByteArray SshPacketParser::asString(const QByteArray &data, quint32 *offset)
{
    const quint32 length = asUint32(data, offset);
    if (size(data) < *offset + length)
        throw SshPacketParseException();
    const QByteArray &string = data.mid(*offset, length);
    *offset += length;
    return string;
}
Exemplo n.º 2
0
quint32 SshPacketParser::asUint32(const QByteArray &data, quint32 offset)
{
    if (size(data) < offset + 4)
        throw SshPacketParseException();
    const quint32 value = ((data.at(offset) & 0xff) << 24)
        + ((data.at(offset + 1) & 0xff) << 16)
        + ((data.at(offset + 2) & 0xff) << 8) + (data.at(offset + 3) & 0xff);
    return value;
}
Exemplo n.º 3
0
SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &pubKeyAlgo) const
{
    Q_ASSERT(isComplete());
    Q_ASSERT(type() == SSH_MSG_KEXDH_REPLY);

    try {
        SshKeyExchangeReply replyData;
        quint32 offset = TypeOffset + 1;
        const quint32 k_sLength
            = SshPacketParser::asUint32(m_data, &offset);
        if (offset + k_sLength > currentDataSize())
            throw SshPacketParseException();
        replyData.k_s = m_data.mid(offset - 4, k_sLength + 4);
        if (SshPacketParser::asString(m_data, &offset) != pubKeyAlgo)
            throw SshPacketParseException();

        // DSS: p and q, RSA: e and n
        replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);
        replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);

        // g and y
        if (pubKeyAlgo == SshCapabilities::PubKeyDss) {
            replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);
            replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);
        }

        replyData.f = SshPacketParser::asBigInt(m_data, &offset);
        offset += 4;
        if (SshPacketParser::asString(m_data, &offset) != pubKeyAlgo)
            throw SshPacketParseException();
        replyData.signatureBlob = SshPacketParser::asString(m_data, &offset);
        return replyData;
    } catch (SshPacketParseException &) {
        throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
            "Key exchange failed: "
            "Server sent invalid SSH_MSG_KEXDH_REPLY packet.");
    }
}
Exemplo n.º 4
0
quint64 SshPacketParser::asUint64(const QByteArray &data, quint32 offset)
{
    if (size(data) < offset + 8)
        throw SshPacketParseException();
    const quint64 value = (static_cast<quint64>(data.at(offset) & 0xff) << 56)
        + (static_cast<quint64>(data.at(offset + 1) & 0xff) << 48)
        + (static_cast<quint64>(data.at(offset + 2) & 0xff) << 40)
        + (static_cast<quint64>(data.at(offset + 3) & 0xff) << 32)
        + ((data.at(offset + 4) & 0xff) << 24)
        + ((data.at(offset + 5) & 0xff) << 16)
        + ((data.at(offset + 6) & 0xff) << 8)
        + (data.at(offset + 7) & 0xff);
    return value;
}
Exemplo n.º 5
0
SshNameList SshPacketParser::asNameList(const QByteArray &data, quint32 *offset)
{
    const quint32 length = asUint32(data, offset);
    const int listEndPos = *offset + length;
    if (data.size() < listEndPos)
        throw SshPacketParseException();
    SshNameList names(length + 4);
    int nextNameOffset = *offset;
    int nextCommaOffset = data.indexOf(',', nextNameOffset);
    while (nextNameOffset > 0 && nextNameOffset < listEndPos) {
        const int stringEndPos = nextCommaOffset == -1
            || nextCommaOffset > listEndPos ? listEndPos : nextCommaOffset;
        names.names << QByteArray(data.constData() + nextNameOffset,
            stringEndPos - nextNameOffset);
        nextNameOffset = nextCommaOffset + 1;
        nextCommaOffset = data.indexOf(',', nextNameOffset);
    }
    *offset += length;
    return names;
}
Exemplo n.º 6
0
SshChannelExitStatus SshIncomingPacket::extractChannelExitStatus() const
{
    Q_ASSERT(isComplete());
    Q_ASSERT(type() == SSH_MSG_CHANNEL_REQUEST);

    SshChannelExitStatus exitStatus;
    try {
        quint32 offset = TypeOffset + 1;
        exitStatus.localChannel = SshPacketParser::asUint32(m_data, &offset);
        const QByteArray &type = SshPacketParser::asString(m_data, &offset);
        Q_ASSERT(type == ExitStatusType);
        Q_UNUSED(type);
        if (SshPacketParser::asBool(m_data, &offset))
            throw SshPacketParseException();
        exitStatus.exitStatus = SshPacketParser::asUint32(m_data, &offset);
    } catch (SshPacketParseException &) {
        throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
            "Invalid exit-status packet.");
    }
    return exitStatus;
}
Exemplo n.º 7
0
SshChannelExitSignal SshIncomingPacket::extractChannelExitSignal() const
{
    Q_ASSERT(isComplete());
    Q_ASSERT(type() == SSH_MSG_CHANNEL_REQUEST);

    SshChannelExitSignal exitSignal;
    try {
        quint32 offset = TypeOffset + 1;
        exitSignal.localChannel = SshPacketParser::asUint32(m_data, &offset);
        const QByteArray &type = SshPacketParser::asString(m_data, &offset);
        Q_ASSERT(type == ExitSignalType);
        Q_UNUSED(type);
        if (SshPacketParser::asBool(m_data, &offset))
            throw SshPacketParseException();
        exitSignal.signal = SshPacketParser::asString(m_data, &offset);
        exitSignal.coreDumped = SshPacketParser::asBool(m_data, &offset);
        exitSignal.error = SshPacketParser::asUserString(m_data, &offset);
        exitSignal.language = SshPacketParser::asString(m_data, &offset);
    } catch (SshPacketParseException &) {
        throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
            "Invalid exit-signal packet.");
    }
    return exitSignal;
}
Exemplo n.º 8
0
bool SshPacketParser::asBool(const QByteArray &data, quint32 offset)
{
    if (size(data) <= offset)
        throw SshPacketParseException();
    return data.at(offset);
}