コード例 #1
0
ファイル: shd-tgen-transfer.c プロジェクト: Moscarda/shadow
static void _tgentransfer_changeError(TGenTransfer* transfer, TGenTransferError error) {
    TGEN_ASSERT(transfer);
    tgen_info("transfer %s moving from error %s to error %s", _tgentransfer_toString(transfer),
            _tgentransfer_errorToString(transfer->error), _tgentransfer_errorToString(error));
    transfer->error = error;
    _tgentransfer_resetString(transfer);
}
コード例 #2
0
ファイル: shd-tgen-transfer.c プロジェクト: Moscarda/shadow
static void _tgentransfer_changeState(TGenTransfer* transfer, TGenTransferState state) {
    TGEN_ASSERT(transfer);
    tgen_info("transfer %s moving from state %s to state %s", _tgentransfer_toString(transfer),
            _tgentransfer_stateToString(transfer->state), _tgentransfer_stateToString(state));
    transfer->state = state;
    _tgentransfer_resetString(transfer);
}
コード例 #3
0
ファイル: shd-tgen-transport.c プロジェクト: 4sp1r3/shadow
static void _tgentransport_changeError(TGenTransport* transport, TGenTransportError error) {
    TGEN_ASSERT(transport);
    tgen_info("transport %s moving from error %s to error %s", tgentransport_toString(transport),
            _tgentransport_errorToString(transport->error), _tgentransport_errorToString(error));
    transport->error = error;
    _tgentransport_resetString(transport);
}
コード例 #4
0
ファイル: shd-tgen-transport.c プロジェクト: 4sp1r3/shadow
static void _tgentransport_changeState(TGenTransport* transport, TGenTransportState state) {
    TGEN_ASSERT(transport);
    tgen_info("transport %s moving from state %s to state %s", tgentransport_toString(transport),
            _tgentransport_stateToString(transport->state), _tgentransport_stateToString(state));
    transport->state = state;
    _tgentransport_resetString(transport);
}
コード例 #5
0
ファイル: shd-tgen-transfer.c プロジェクト: Moscarda/shadow
static void _tgentransfer_log(TGenTransfer* transfer, gboolean wasActive) {
    TGEN_ASSERT(transfer);


    if(transfer->state == TGEN_XFER_ERROR) {
        /* we had an error at some point and will unlikely be able to complete.
         * only log an error once. */
        if(transfer->time.lastTimeErrorReport == 0) {
            gchar* bytesMessage = _tgentransfer_getBytesStatusReport(transfer);
            gchar* timeMessage = _tgentransfer_getTimeStatusReport(transfer);

            tgen_message("[transfer-error] transport %s transfer %s %s %s",
                    tgentransport_toString(transfer->transport),
                    _tgentransfer_toString(transfer), bytesMessage, timeMessage);

            gint64 now = g_get_monotonic_time();
            transfer->time.lastBytesStatusReport = now;
            transfer->time.lastTimeErrorReport = now;
            g_free(bytesMessage);
        }
    } else if(transfer->state == TGEN_XFER_SUCCESS) {
        /* we completed the transfer. yay. only log once. */
        if(transfer->time.lastTimeStatusReport == 0) {
            gchar* bytesMessage = _tgentransfer_getBytesStatusReport(transfer);
            gchar* timeMessage = _tgentransfer_getTimeStatusReport(transfer);

            tgen_message("[transfer-complete] transport %s transfer %s %s %s",
                    tgentransport_toString(transfer->transport),
                    _tgentransfer_toString(transfer), bytesMessage, timeMessage);

            gint64 now = g_get_monotonic_time();
            transfer->time.lastBytesStatusReport = now;
            transfer->time.lastTimeStatusReport = now;
            g_free(bytesMessage);
            g_free(timeMessage);
        }
    } else {
        /* the transfer is still working. only log on new activity */
        if(wasActive) {
            gchar* bytesMessage = _tgentransfer_getBytesStatusReport(transfer);

            tgen_info("[transfer-status] transport %s transfer %s %s",
                    tgentransport_toString(transfer->transport),
                    _tgentransfer_toString(transfer), bytesMessage);

            transfer->time.lastBytesStatusReport = g_get_monotonic_time();;
            g_free(bytesMessage);
        }
    }
}
コード例 #6
0
ファイル: shd-tgen-graph.c プロジェクト: MileB/shadow
static igraph_t* _tgengraph_loadNewGraph(const gchar* path) {
    /* get the file */
    FILE* graphFile = fopen(path, "r");
    if(!graphFile) {
        tgen_critical("fopen returned NULL, problem opening graph file path '%s'", path);
        return FALSE;
    }

    tgen_info("reading graphml action graph at '%s'...", path);

    igraph_t* graph = g_new0(igraph_t, 1);
    gint result = igraph_read_graph_graphml(graph, graphFile, 0);
    fclose(graphFile);

    if(result != IGRAPH_SUCCESS) {
        tgen_critical("igraph_read_graph_graphml return non-success code %i", result);
        g_free(graph);
        return NULL;
    }

    tgen_info("successfully read graphml action graph at '%s'", path);

    return graph;
}
コード例 #7
0
ファイル: shd-tgen-graph.c プロジェクト: MileB/shadow
static GError* _tgengraph_parseGraphEdges(TGenGraph* g) {
    TGEN_ASSERT(g);

    tgen_debug("checking graph edges...");

    /* we will iterate through the edges */
    igraph_eit_t edgeIterator;

    gint result = igraph_eit_create(g->graph, igraph_ess_all(IGRAPH_EDGEORDER_ID), &edgeIterator);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_eit_create return non-success code %i", result);
    }

    /* count the edges as we iterate */
    igraph_integer_t edgeCount = 0;
    GError* error = NULL;

    while (!IGRAPH_EIT_END(edgeIterator)) {
        igraph_integer_t edgeIndex = IGRAPH_EIT_GET(edgeIterator);

        igraph_integer_t fromVertexIndex, toVertexIndex;

        gint result = igraph_edge(g->graph, edgeIndex, &fromVertexIndex, &toVertexIndex);
        if(result != IGRAPH_SUCCESS) {
            error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                    "igraph_edge return non-success code %i", result);
            break;
        }

        const gchar* fromIDStr = (g->knownAttributes&TGEN_VA_ID) ?
                VAS(g->graph, "id", fromVertexIndex) : NULL;
        if(!fromIDStr) {
            error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_MISSING_ATTRIBUTE,
                    "found vertex %li with missing 'id' attribute", (glong)fromVertexIndex);
            break;
        }

        const gchar* toIDStr = (g->knownAttributes&TGEN_VA_ID) ?
                VAS(g->graph, "id", toVertexIndex) : NULL;
        if(!toIDStr) {
            error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_MISSING_ATTRIBUTE,
                    "found vertex %li with missing 'id' attribute", (glong)toVertexIndex);
            break;
        }

        tgen_debug("found edge %li from vertex %li (%s) to vertex %li (%s)",
                (glong)edgeIndex, (glong)fromVertexIndex, fromIDStr, (glong)toVertexIndex, toIDStr);

        const gchar* weightStr = (g->knownAttributes&TGEN_EA_WEIGHT) ?
                EAS(g->graph, "weight", edgeIndex) : NULL;
        if(weightStr != NULL) {
            if(g_ascii_strncasecmp(weightStr, "\0", (gsize) 1)) {
                gdouble weight = g_ascii_strtod(weightStr, NULL);
                _tgengraph_storeWeight(g, weight, edgeIndex);
            }
        }

        edgeCount++;
        IGRAPH_EIT_NEXT(edgeIterator);
    }

    igraph_eit_destroy(&edgeIterator);

    if(!error) {
        g->edgeCount = igraph_ecount(g->graph);
        if(g->edgeCount != edgeCount) {
            tgen_warning("igraph_vcount %f does not match iterator count %f", g->edgeCount, edgeCount);
        }

        tgen_info("%u graph edges ok", (guint) g->edgeCount);
    }

    return error;
}
コード例 #8
0
ファイル: shd-tgen-graph.c プロジェクト: MileB/shadow
static GError* _tgengraph_parseGraphProperties(TGenGraph* g) {
    TGEN_ASSERT(g);
    gint result = 0;

    tgen_debug("checking graph properties...");

    /* IGRAPH_WEAK means the undirected version of the graph is connected
     * IGRAPH_STRONG means a vertex can reach all others via a directed path */
    result = igraph_is_connected(g->graph, &(g->isConnected), IGRAPH_WEAK);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_is_connected return non-success code %i", result);
    }

    igraph_integer_t clusterCount;
    result = igraph_clusters(g->graph, NULL, NULL, &(g->clusterCount), IGRAPH_WEAK);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_clusters return non-success code %i", result);
    }

    /* it must be connected */
    if(!g->isConnected || g->clusterCount > 1) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                "graph must be but is not connected");
    }

    g->isDirected = igraph_is_directed(g->graph);

    tgen_debug("checking graph attributes...");

    /* now check list of all attributes */
    igraph_strvector_t gnames, vnames, enames;
    igraph_vector_t gtypes, vtypes, etypes;
    igraph_strvector_init(&gnames, 25);
    igraph_vector_init(&gtypes, 25);
    igraph_strvector_init(&vnames, 25);
    igraph_vector_init(&vtypes, 25);
    igraph_strvector_init(&enames, 25);
    igraph_vector_init(&etypes, 25);

    result = igraph_cattribute_list(g->graph, &gnames, &gtypes, &vnames, &vtypes, &enames, &etypes);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_cattribute_list return non-success code %i", result);
    }

    gint i = 0;
    for(i = 0; i < igraph_strvector_size(&gnames); i++) {
        gchar* name = NULL;
        igraph_strvector_get(&gnames, (glong) i, &name);

        tgen_debug("found graph attribute '%s'", name);
    }
    for(i = 0; i < igraph_strvector_size(&vnames); i++) {
        gchar* name = NULL;
        igraph_strvector_get(&vnames, (glong) i, &name);

        tgen_debug("found vertex attribute '%s'", name);
        g->knownAttributes |= _tgengraph_vertexAttributeToFlag(name);
    }
    for(i = 0; i < igraph_strvector_size(&enames); i++) {
        gchar* name = NULL;
        igraph_strvector_get(&enames, (glong) i, &name);

        tgen_debug("found edge attribute '%s'", name);
        g->knownAttributes |= _tgengraph_edgeAttributeToFlag(name);
    }

    igraph_strvector_destroy(&gnames);
    igraph_vector_destroy(&gtypes);
    igraph_strvector_destroy(&vnames);
    igraph_vector_destroy(&vtypes);
    igraph_strvector_destroy(&enames);
    igraph_vector_destroy(&etypes);

    tgen_info("successfully verified graph properties and attributes");

    return NULL;
}
コード例 #9
0
ファイル: shd-tgen-graph.c プロジェクト: MileB/shadow
static GError* _tgengraph_parseGraphVertices(TGenGraph* g) {
    TGEN_ASSERT(g);

    tgen_debug("checking graph vertices...");

    /* we will iterate through the vertices */
    igraph_vit_t vertexIterator;

    gint result = igraph_vit_create(g->graph, igraph_vss_all(), &vertexIterator);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_vit_create return non-success code %i", result);
    }

    /* count the vertices as we iterate */
    igraph_integer_t vertexCount = 0;
    GError* error = NULL;

    while (!IGRAPH_VIT_END(vertexIterator)) {
        igraph_integer_t vertexIndex = (igraph_integer_t)IGRAPH_VIT_GET(vertexIterator);

        /* get vertex attributes: S for string and N for numeric */
        const gchar* idStr = (g->knownAttributes&TGEN_VA_ID) ?
                VAS(g->graph, "id", vertexIndex) : NULL;

        if(!idStr) {
            error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_MISSING_ATTRIBUTE,
                    "found vertex %li with missing action 'id' attribute", (glong)vertexIndex);
            break;
        }

        if(g_strstr_len(idStr, (gssize)-1, "start")) {
            error = _tgengraph_parseStartVertex(g, idStr, vertexIndex);
        } else if(g_strstr_len(idStr, (gssize)-1, "end")) {
            error = _tgengraph_parseEndVertex(g, idStr, vertexIndex);
        } else if(g_strstr_len(idStr, (gssize)-1, "pause")) {
            error = _tgengraph_parsePauseVertex(g, idStr, vertexIndex);
        } else if(g_strstr_len(idStr, (gssize)-1, "synchronize")) {
            error = _tgengraph_parseSynchronizeVertex(g, idStr, vertexIndex);
        } else if(g_strstr_len(idStr, (gssize)-1, "transfer")) {
            error = _tgengraph_parseTransferVertex(g, idStr, vertexIndex);
        } else if(g_strstr_len(idStr, (gssize)-1, "choose")) {
            error = _tgengraph_parseChooseVertex(g, idStr, vertexIndex);
        } else {
            error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
                    "found vertex %li (%s) with an unknown action id '%s'",
                    (glong)vertexIndex, idStr, idStr);
        }

        if(error) {
            break;
        }

        vertexCount++;
        IGRAPH_VIT_NEXT(vertexIterator);
    }

    /* clean up */
    igraph_vit_destroy(&vertexIterator);

    if(!g->startHasPeers && g->transferMissingPeers) {
        error = g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                    "peers required in either the 'start' action, or *every* 'transfer' action");
    }

    if(!error) {
        g->vertexCount = igraph_vcount(g->graph);
        if(g->vertexCount != vertexCount) {
            tgen_warning("igraph_vcount %f does not match iterator count %f", g->vertexCount, vertexCount);
        }

        tgen_info("%u graph vertices ok", (guint) g->vertexCount);
    }

    return error;
}
コード例 #10
0
ファイル: shd-tgen-transfer.c プロジェクト: Moscarda/shadow
static void _tgentransfer_readCommand(TGenTransfer* transfer) {
    TGEN_ASSERT(transfer);

    if(_tgentransfer_getLine(transfer)) {
        /* we have read the entire command from the other end */
        gboolean hasError = FALSE;
        transfer->time.command = g_get_monotonic_time();

        gchar* line = g_string_free(transfer->readBuffer, FALSE);
        transfer->readBuffer = NULL;

        if(g_ascii_strncasecmp(line, TGEN_AUTH_PW, 20)) {
            /* password doesn't match */
            tgen_info("transfer authentication error: passwords don't match")
            hasError = TRUE;
            _tgentransfer_changeState(transfer, TGEN_XFER_ERROR);
            _tgentransfer_changeError(transfer, TGEN_XFER_ERR_AUTH);
        } else {
            /* password matches, lets parse the rest of the string */
            gchar** parts = g_strsplit(line, " ", 0);
            if(parts[0] == NULL || parts[1] == NULL || parts[2] == NULL || parts[3] == NULL || parts[4] == NULL || parts[5] == NULL) {
                tgen_critical("error parsing command '%s'", line);
                hasError = TRUE;
            } else {
                g_assert(!transfer->remoteName);
                transfer->remoteName = g_strdup(parts[1]);

                /* we are not the commander so we should not have an id yet */
                g_assert(transfer->id == NULL);
                transfer->id = g_strdup(parts[2]);

                transfer->remoteCount = (gsize)g_ascii_strtoull(parts[3], NULL, 10);
                if(transfer->remoteCount == 0) {
                    tgen_critical("error parsing command ID '%s'", parts[3]);
                    hasError = TRUE;
                }

                if(!g_ascii_strncasecmp(parts[4], "GET", 3)) {
                    /* they are trying to GET, then we need to PUT to them */
                    transfer->type = TGEN_TYPE_PUT;
                    /* we read command, but now need to write payload */
                    transfer->events |= TGEN_EVENT_WRITE;
                } else if(!g_ascii_strncasecmp(parts[4], "PUT", 3)) {
                    /* they want to PUT, so we will GET from them */
                    transfer->type = TGEN_TYPE_GET;
                } else {
                    tgen_critical("error parsing command type '%s'", parts[4]);
                    hasError = TRUE;
                }

                transfer->size = (gsize)g_ascii_strtoull(parts[5], NULL, 10);
                if(transfer->size == 0) {
                    tgen_critical("error parsing command size '%s'", parts[5]);
                    hasError = TRUE;
                }
            }

            g_strfreev(parts);
            g_free(line);

            /* payload phase is next unless there was an error parsing */
            if(hasError) {
                _tgentransfer_changeState(transfer, TGEN_XFER_ERROR);
                _tgentransfer_changeError(transfer, TGEN_XFER_ERR_READ);
            } else {
                /* we need to update our string with the new command info */
                _tgentransfer_resetString(transfer);
                _tgentransfer_changeState(transfer, TGEN_XFER_RESPONSE);
                transfer->events |= TGEN_EVENT_WRITE;
            }
        }
    } else {
        /* unable to receive entire command, wait for next chance to read */
    }
}
コード例 #11
0
ファイル: shd-tgen-transport.c プロジェクト: 4sp1r3/shadow
static TGenEvent _tgentransport_receiveSocksResponse(TGenTransport* transport) {
    /*
    4 socks response client <-- server
    \x05 (version 5)
    \x00 (request granted)
    \x00 (reserved)

    the server can tell us that we need to reconnect elsewhere

    4a ip address client <-- server
    \x01 (ipv4)
    in_addr_t (4 bytes)
    in_port_t (2 bytes)

    4b hostname client <-- server
    \x03 (domain name)
    \x__ (1 byte name len)
    (name)
    in_port_t (2 bytes)
     */

    gchar buffer[256];
    memset(buffer, 0, 256);
    gssize bytesReceived = tgentransport_read(transport, buffer, 256);
    g_assert(bytesReceived >= 4);
    transport->time.proxyResponse = g_get_monotonic_time();

    if(buffer[0] == 0x05 && buffer[1] == 0x00) {
        if(buffer[3] == 0x01) {
            /* case 4a - IPV4 mode - get address server told us */
            g_assert(bytesReceived == 10);

            /* check if they want us to connect elsewhere */
            in_addr_t socksBindAddress = 0;
            in_port_t socksBindPort = 0;
            g_memmove(&socksBindAddress, &buffer[4], 4);
            g_memmove(&socksBindPort, &buffer[8], 2);

            /* reconnect not supported */
            if(socksBindAddress == 0 && socksBindPort == 0) {
                tgen_info("connection from %s through socks proxy %s to %s successful",
                        tgenpeer_toString(transport->local), tgenpeer_toString(transport->proxy), tgenpeer_toString(transport->remote));

                _tgentransport_changeState(transport, TGEN_XPORT_SUCCESS);
                return TGEN_EVENT_DONE;
            } else {
                _tgentransport_changeError(transport, TGEN_XPORT_ERR_PROXY_RECONN);
                tgen_warning("connection from %s through socks proxy %s to %s failed: "
                        "proxy requested unsupported reconnection to %i:u",
                        tgenpeer_toString(transport->local), tgenpeer_toString(transport->proxy), tgenpeer_toString(transport->remote),
                        (gint)socksBindAddress, (guint)ntohs(socksBindPort));
            }
        } else if (buffer[3] == 0x03) {
            /* case 4b - domain name mode */
            guint8 nameLength = 0;
            g_memmove(&nameLength, &buffer[4], 1);

            g_assert(bytesReceived == nameLength+7);

            gchar namebuf[nameLength+1];
            memset(namebuf, 0, nameLength);
            in_port_t socksBindPort = 0;

            g_memmove(namebuf, &buffer[5], nameLength);
            g_memmove(&socksBindPort, &buffer[5+nameLength], 2);

            /* reconnect not supported */
            if(!g_ascii_strncasecmp(namebuf, "\0", (gsize) 1) && socksBindPort == 0) {
                tgen_info("connection from %s through socks proxy %s to %s successful",
                        tgenpeer_toString(transport->local), tgenpeer_toString(transport->proxy), tgenpeer_toString(transport->remote));

                _tgentransport_changeState(transport, TGEN_XPORT_SUCCESS);
                return TGEN_EVENT_DONE;
            } else {
                _tgentransport_changeError(transport, TGEN_XPORT_ERR_PROXY_RECONN);
                tgen_warning("connection from %s through socks proxy %s to %s failed: "
                        "proxy requested unsupported reconnection to %s:u",
                        tgenpeer_toString(transport->local), tgenpeer_toString(transport->proxy), tgenpeer_toString(transport->remote),
                        namebuf, (guint)ntohs(socksBindPort));
            }
        } else {
            _tgentransport_changeError(transport, TGEN_XPORT_ERR_PROXY_ADDR);
            tgen_warning("connection from %s through socks proxy %s to %s failed: unsupported address type %i",
                    tgenpeer_toString(transport->local), tgenpeer_toString(transport->proxy), tgenpeer_toString(transport->remote),
                    (gint)buffer[3]);
        }
    } else {
        _tgentransport_changeError(transport, (buffer[0] != 0x05) ? TGEN_XPORT_ERR_PROXY_VERSION : TGEN_XPORT_ERR_PROXY_STATUS);
        tgen_warning("connection from %s through socks proxy %s to %s failed: unsupported %s %i",
                tgenpeer_toString(transport->local), tgenpeer_toString(transport->proxy), tgenpeer_toString(transport->remote),
                (buffer[0] != 0x05) ? "version" : "status",
                (buffer[0] != 0x05) ? (gint)buffer[0] : (gint)buffer[1]);
    }

    _tgentransport_changeState(transport, TGEN_XPORT_ERROR);
    return TGEN_EVENT_NONE;
}