Example #1
0
void Sasl::respond(qpid::SaslServer::Status status, const std::string& chllnge)
{
    switch (status) {
      case qpid::SaslServer::OK:
        connection.setUserid(authenticator->getUserid());
        completed(true);
        //can't set authenticated & failed until we have actually sent the outcome
        state = SUCCESS_PENDING;
        securityLayer = authenticator->getSecurityLayer(65535);
        if (securityLayer.get()) {
            QPID_LOG_CAT(info, security, id << " Security layer installed");
            securityLayer->init(&connection);
            connection.setSaslSsf(securityLayer->getSsf());
        }
        QPID_LOG_CAT(info, security, id << " Authenticated as " << authenticator->getUserid());
        break;
      case qpid::SaslServer::FAIL:
        completed(false);
        state = FAILURE_PENDING;
        QPID_LOG_CAT(info, security, id << " Failed to authenticate");
        break;
      case qpid::SaslServer::CHALLENGE:
        challenge(&chllnge);
        QPID_LOG_CAT(info, security, id << " Challenge issued");
        break;
    }
    haveOutput = true;
    out.activateOutput();
}
Example #2
0
std::size_t ConnectionContext::encode(char* buffer, std::size_t size)
{
    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
    QPID_LOG(trace, id << " encode(" << size << ")");
    if (writeHeader) {
        size_t encoded = writeProtocolHeader(buffer, size);
        if (encoded < size) {
            encoded += encode(buffer + encoded, size - encoded);
        }
        return encoded;
    }

    ssize_t n = pn_transport_output(engine, buffer, size);
    if (n > 0) {
        QPID_LOG_CAT(debug, network, id << " encoded " << n << " bytes from " << size)
        haveOutput = true;
        return n;
    } else if (n == PN_ERR) {
        throw qpid::Exception(QPID_MSG("Error on output: " << getError()));
    } else if (n == PN_EOS) {
        haveOutput = false;
        return 0;//Is this right?
    } else {
        haveOutput = false;
        return 0;
    }
}
Example #3
0
std::size_t ConnectionContext::decode(const char* buffer, std::size_t size)
{
    qpid::sys::ScopedLock<qpid::sys::Monitor> l(lock);
    QPID_LOG(trace, id << " decode(" << size << ")");
    if (readHeader) {
        size_t decoded = readProtocolHeader(buffer, size);
        if (decoded < size) {
            decoded += decode(buffer + decoded, size - decoded);
        }
        return decoded;
    }

    //TODO: Fix pn_engine_input() to take const buffer
    ssize_t n = pn_transport_input(engine, const_cast<char*>(buffer), size);
    if (n > 0 || n == PN_EOS) {
        //If engine returns EOS, have no way of knowing how many bytes
        //it processed, but can assume none need to be reprocessed so
        //consider them all read:
        if (n == PN_EOS) n = size;
        QPID_LOG_CAT(debug, network, id << " decoded " << n << " bytes from " << size)
        pn_transport_tick(engine, 0);
        lock.notifyAll();
        return n;
    } else if (n == PN_ERR) {
        throw qpid::Exception(QPID_MSG("Error on input: " << getError()));
    } else {
        return 0;
    }

}
Example #4
0
void Sasl::init(const std::string& mechanism, const std::string* response, const std::string* /*hostname*/)
{
    QPID_LOG_CAT(debug, protocol, id << " Received SASL-INIT(" << mechanism << ", " << (response ? *response : EMPTY) <<  ")");
    //TODO: what should we do with hostname here?
    std::string c;
    respond(authenticator->start(mechanism, response, c), c);
    connection.setSaslMechanism(mechanism);
}
Example #5
0
void SaslServer::completed(bool succeeded)
{
    void* frameToken = startFrame();

    void* listToken = encoder.startList8(&SASL_OUTCOME);
    encoder.writeUByte(succeeded ? 0 : 1);
    encoder.endList8(1, listToken);

    endFrame(frameToken);
    QPID_LOG_CAT(debug, protocol, id << " Sent SASL-OUTCOME(" << (succeeded ? 0 : 1) << ") " << encoder.getPosition());
}
Example #6
0
void SaslServer::challenge(const std::string* c)
{
    void* frameToken = startFrame();

    void* listToken = encoder.startList32(&SASL_CHALLENGE);
    if (c) encoder.writeBinary(*c);
    else encoder.writeNull();
    encoder.endList32(1, listToken);

    endFrame(frameToken);
    QPID_LOG_CAT(debug, protocol, id << " Sent SASL-CHALLENGE(" << (c ? *c : NULL_) << ") " << encoder.getPosition());
}
Example #7
0
void SaslClient::response(const std::string* r)
{
    void* frame = startFrame();

    void* token = encoder.startList32(&SASL_RESPONSE);
    if (r) encoder.writeBinary(*r);
    else encoder.writeNull();
    encoder.endList32(1, token);

    endFrame(frame);
    QPID_LOG_CAT(debug, protocol, id << " Sent SASL-RESPONSE(" << (r ? *r : "null") << ")");
}
Example #8
0
std::size_t ConnectionContext::readProtocolHeader(const char* buffer, std::size_t size)
{
    framing::ProtocolInitiation pi(getVersion());
    if (size >= pi.encodedSize()) {
        readHeader = false;
        qpid::framing::Buffer out(const_cast<char*>(buffer), size);
        pi.decode(out);
        QPID_LOG_CAT(debug, protocol, id << " read protocol header: " << pi);
        return pi.encodedSize();
    } else {
        return 0;
    }
}
Example #9
0
std::size_t ConnectionContext::writeProtocolHeader(char* buffer, std::size_t size)
{
    framing::ProtocolInitiation pi(getVersion());
    if (size >= pi.encodedSize()) {
        QPID_LOG_CAT(debug, protocol, id << " writing protocol header: " << pi);
        writeHeader = false;
        qpid::framing::Buffer out(buffer, size);
        pi.encode(out);
        return pi.encodedSize();
    } else {
        QPID_LOG_CAT(debug, protocol, id << " insufficient buffer for protocol header: " << size)
        return 0;
    }
}
Example #10
0
void SaslClient::init(const std::string& mechanism, const std::string* response, const std::string* hostname)
{
    void* frame = startFrame();

    void* token = encoder.startList32(&SASL_INIT);
    encoder.writeSymbol(mechanism);
    if (response) encoder.writeBinary(*response);
    else encoder.writeNull();
    if (hostname) encoder.writeString(*hostname);
    else encoder.writeNull();
    encoder.endList32(3, token);

    endFrame(frame);
    QPID_LOG_CAT(debug, protocol, id << " Sent SASL-INIT(" << mechanism << ", " << (response ? *response : "null") << ", " << (hostname ? *hostname : "null") << ")");
}
Example #11
0
void Interconnect::process()
{
    QPID_LOG(trace, id << " processing interconnect");
    if (closeRequested) {
        close();
    } else {
        if ((pn_connection_state(connection) & UNINIT) == UNINIT) {
            QPID_LOG_CAT(debug, model, id << " interconnect open initiated");
            pn_connection_set_container(connection, getBroker().getFederationTag().c_str());
            setProperties(connection);
            pn_connection_open(connection);
            out.connectionEstablished();
            setInterconnectDomain(domain);
        }
        if (!isOpened && (pn_connection_state(connection) & PN_REMOTE_ACTIVE)) {
            QPID_LOG_CAT(debug, model, id << " interconnect open completed, attaching link");
            isOpened = true;
            readPeerProperties();
            const char* containerid(pn_connection_remote_container(connection));
            if (containerid) {
                setContainerId(std::string(containerid));
            }
            opened();
            getBroker().getConnectionObservers().opened(*this);
            pn_session_t* s = pn_session(connection);
            pn_session_open(s);
            boost::shared_ptr<Session> ssn(new Session(s, *this, out));
            sessions[s] = ssn;

            pn_link_t* l = incoming ? pn_receiver(s, name.c_str()) : pn_sender(s, name.c_str());
            pn_link_open(l);
            ssn->attach(l, source, target, relay);
        }
        Connection::process();
    }
}
Example #12
0
void SaslServer::mechanisms(const std::string& mechanisms)
{
    void* frameToken = startFrame();

    std::vector<std::string> parts = split(mechanisms, SPACE);
    void* listToken = encoder.startList32(&SASL_MECHANISMS);
    if (parts.size() > 1) {
        void* arrayToken = encoder.startArray8(Constructor(SYMBOL8));
        for (std::vector<std::string>::const_iterator i = parts.begin();i != parts.end(); ++i) {
            uint8_t size = i->size() > std::numeric_limits<uint8_t>::max() ? std::numeric_limits<uint8_t>::max() : i->size();
            encoder.write(size);
            encoder.writeBytes(i->data(), size);
        }
        encoder.endArray8(parts.size(), arrayToken);
    } else {
        encoder.writeSymbol(mechanisms);
    }
    encoder.endList32(1, listToken);

    endFrame(frameToken);
    QPID_LOG_CAT(debug, protocol, id << " Sent SASL-MECHANISMS(" << mechanisms << ") " << encoder.getPosition());
}
Example #13
0
void Connection::process()
{
    QPID_LOG(trace, id << " process()");
    if ((pn_connection_state(connection) & REQUIRES_OPEN) == REQUIRES_OPEN) {
        QPID_LOG_CAT(debug, model, id << " connection opened");
        pn_connection_set_container(connection, broker.getFederationTag().c_str());
        pn_connection_open(connection);
    }

    for (pn_session_t* s = pn_session_head(connection, REQUIRES_OPEN); s; s = pn_session_next(s, REQUIRES_OPEN)) {
        QPID_LOG_CAT(debug, model, id << " session begun");
        pn_session_open(s);
        boost::shared_ptr<Session> ssn(new Session(s, broker, *this, out));
        sessions[s] = ssn;
    }
    for (pn_link_t* l = pn_link_head(connection, REQUIRES_OPEN); l; l = pn_link_next(l, REQUIRES_OPEN)) {
        pn_link_open(l);

        Sessions::iterator session = sessions.find(pn_link_session(l));
        if (session == sessions.end()) {
            QPID_LOG(error, id << " Link attached on unknown session!");
        } else {
            try {
                session->second->attach(l);
                QPID_LOG_CAT(debug, protocol, id << " link " << l << " attached on " << pn_link_session(l));
            } catch (const std::exception& e) {
                QPID_LOG_CAT(error, protocol, "Error on attach: " << e.what());
                //TODO: set error details on detach when that is exposed via engine API
                pn_link_close(l);
            }
        }
    }

    //handle deliveries
    for (pn_delivery_t* delivery = pn_work_head(connection); delivery; delivery = pn_work_next(delivery)) {
        pn_link_t* link = pn_delivery_link(delivery);
        if (pn_link_is_receiver(link)) {
            Sessions::iterator i = sessions.find(pn_link_session(link));
            if (i != sessions.end()) {
                i->second->readable(link, delivery);
            } else {
                pn_delivery_update(delivery, PN_REJECTED);
            }
        } else { //i.e. SENDER
            Sessions::iterator i = sessions.find(pn_link_session(link));
            if (i != sessions.end()) {
                QPID_LOG(trace, id << " handling outgoing delivery for " << link << " on session " << pn_link_session(link));
                i->second->writable(link, delivery);
            } else {
                QPID_LOG(error, id << " Got delivery for non-existent session: " << pn_link_session(link) << ", link: " << link);
            }
        }
    }


    for (pn_link_t* l = pn_link_head(connection, REQUIRES_CLOSE); l; l = pn_link_next(l, REQUIRES_CLOSE)) {
        pn_link_close(l);
        Sessions::iterator session = sessions.find(pn_link_session(l));
        if (session == sessions.end()) {
            QPID_LOG(error, id << " peer attempted to detach link on unknown session!");
        } else {
            session->second->detach(l);
            QPID_LOG_CAT(debug, model, id << " link detached");
        }
    }
    for (pn_session_t* s = pn_session_head(connection, REQUIRES_CLOSE); s; s = pn_session_next(s, REQUIRES_CLOSE)) {
        pn_session_close(s);
        Sessions::iterator i = sessions.find(s);
        if (i != sessions.end()) {
            i->second->close();
            sessions.erase(i);
            QPID_LOG_CAT(debug, model, id << " session ended");
        } else {
            QPID_LOG(error, id << " peer attempted to close unrecognised session");
        }
    }
    if ((pn_connection_state(connection) & REQUIRES_CLOSE) == REQUIRES_CLOSE) {
        QPID_LOG_CAT(debug, model, id << " connection closed");
        pn_connection_close(connection);
    }
}
Example #14
0
void Sasl::response(const std::string* r)
{
    QPID_LOG_CAT(debug, protocol, id << " Received SASL-RESPONSE(" << (r ? *r : EMPTY) <<  ")");
    std::string c;
    respond(authenticator->step(r, c), c);
}