Example #1
0
if (!extension_loaded("SimpleXML")) {
    $reply = new SimpleXMLElement("<reply></reply>");
    $node = $reply->addChild("status", "ERROR");
    $node->addAttribute("error", "The SimpleXML extension is required");
    echo gda_add_hash($init_shared, $reply->asXml());
    session_destroy();
    exit(1);
}
$cmdfile = get_command_filename(session_id());
$replyfile = get_reply_filename(session_id());
umask(0);
$mode = 0600;
posix_mkfifo($cmdfile, $mode);
posix_mkfifo($replyfile, $mode);
if (!file_exists($cmdfile) || !file_exists($replyfile)) {
    $reply = new SimpleXMLElement("<reply></reply>");
    $node = $reply->addChild("status", "ERROR");
    $node->addAttribute("error", "Can't create named pipes");
    echo gda_add_hash($init_shared, $reply->asXml());
    @unlink($cmdfile);
    @unlink($replyfile);
    session_destroy();
    exit(1);
}
/* all setup */
$reply = new SimpleXMLElement("<reply></reply>");
$reply->addChild('session', htmlspecialchars(SID));
$reply->addChild("status", "OK");
echo gda_add_hash($init_shared, $reply->asXml());
flush();
ob_flush();
Example #2
0
function gda_handle_xml($xml, &$doquit)
{
    //var_dump($xml);
    $reply = new SimpleXMLElement("<reply></reply>");
    $apply_md5_to_key = false;
    $doquit = false;
    global $debug;
    global $init_shared;
    global $cnc;
    global $dsn;
    global $mdb2;
    $token = "-";
    $status = "";
    if ($xml->getName() != "request") {
        throw new GdaException('Bad XML input', true);
    }
    foreach ($xml->children() as $child) {
        if ($child->getName() == "token") {
            $token = $child[0];
            if ($_SESSION['key'] == $init_shared) {
                /* change $_SESSION['key'] depending on the configured connections */
                foreach ($cnc as $dbname => $dbpass) {
                    $computed_token = hmac($dbname . "/AND/" . $dbpass, $_SESSION['challenge']);
                    if ($computed_token == $token) {
                        $_SESSION['key'] = $dbname . "/AND/" . $dbpass;
                        $_SESSION['dsn'] = $dsn[$dbname];
                        $cncfound = true;
                        break;
                    }
                }
                if (!isset($cncfound)) {
                    throw new GdaException('Connection not found', true);
                }
            } else {
                $computed_token = hmac($_SESSION['key'], $_SESSION['challenge']);
                if ($computed_token != $token) {
                    throw new GdaException('Authentication error', true);
                }
            }
        } else {
            if ($child->getName() == "cmd") {
                switch ($child[0]) {
                    case "HELLO":
                        /* just output a new challenge */
                        $_SESSION['key'] = $init_shared;
                        $reply->addChild('session', htmlspecialchars(SID));
                        $status = "OK";
                        break;
                    case "CONNECT":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        /* actually open the connection */
                        $mdb2 = real_connect($_SESSION['dsn'], $reply);
                        $apply_md5_to_key = true;
                        $dbtype = determine_db_type($mdb2);
                        if ($dbtype) {
                            $reply->addChild('servertype', $dbtype);
                        }
                        $reply->addChild('serverversion', $mdb2->getServerVersion(true));
                        $status = "OK";
                        break;
                    case "BYE":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        /* actually close the connection */
                        if (isset($mdb2)) {
                            $mdb2->disconnect();
                        }
                        $status = "CLOSED";
                        $doquit = true;
                        $_SESSION["cncclosed"] = true;
                        break;
                    case "PREPARE":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        $argsnode = null;
                        $type_is_result = false;
                        foreach ($child->children() as $sqlnode) {
                            if ($sqlnode->getName() == "sql") {
                                $sql = $sqlnode[0];
                                foreach ($sqlnode->attributes() as $a => $b) {
                                    if ($a == "type" && $b == "SELECT") {
                                        $type_is_result = true;
                                        break;
                                    }
                                }
                            } else {
                                if ($sqlnode->getName() == "arguments") {
                                    $argsnode = $sqlnode;
                                }
                            }
                        }
                        if (!isset($sql)) {
                            throw new GdaException('Bad XML input', true);
                        }
                        /* actually execute SQL in $sql */
                        if (!isset($mdb2)) {
                            $mdb2 = real_connect($_SESSION['dsn'], $reply);
                        }
                        do_prepare($reply, $mdb2, $sql, $type_is_result, $argsnode);
                        $status = "OK";
                        break;
                    case "UNPREPARE":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        $pstmt_hash = null;
                        foreach ($child->children() as $sqlnode) {
                            if ($sqlnode->getName() == "preparehash") {
                                $pstmt_hash = $sqlnode[0];
                                break;
                            }
                        }
                        /* actually execute SQL in $sql */
                        if (isset($mdb2) && isset($pstmt_hash)) {
                            do_unprepare($reply, $mdb2, $pstmt_hash);
                        }
                        $status = "OK";
                        break;
                    case "EXEC":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        $argsnode = null;
                        $pstmt_hash = null;
                        $type_is_result = false;
                        foreach ($child->children() as $sqlnode) {
                            if ($sqlnode->getName() == "sql") {
                                $sql = $sqlnode[0];
                                foreach ($sqlnode->attributes() as $a => $b) {
                                    if ($a == "type" && $b == "SELECT") {
                                        $type_is_result = true;
                                        break;
                                    }
                                }
                            } else {
                                if ($sqlnode->getName() == "arguments") {
                                    $argsnode = $sqlnode;
                                } else {
                                    if ($sqlnode->getName() == "preparehash") {
                                        $pstmt_hash = $sqlnode[0];
                                    }
                                }
                            }
                        }
                        if (!isset($sql)) {
                            throw new GdaException('Bad XML input', true);
                        }
                        /* actually execute SQL in $sql */
                        if (!isset($mdb2)) {
                            $mdb2 = real_connect($_SESSION['dsn'], $reply);
                        }
                        do_exec($reply, $mdb2, $pstmt_hash, $sql, $type_is_result, $argsnode);
                        $status = "OK";
                        break;
                    case "BEGIN":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        /* actually execute SQL in $sql */
                        if (!isset($mdb2)) {
                            $mdb2 = real_connect($_SESSION['dsn'], $reply);
                        }
                        foreach ($child->attributes() as $a => $b) {
                            if ($a == "svpname") {
                                $svpname = $b;
                                break;
                            }
                        }
                        if (isset($svpname)) {
                            $res = $mdb2->beginTransaction($svpname);
                        } else {
                            $res = $mdb2->beginTransaction();
                        }
                        handle_pear_error($res, $reply);
                        $status = "OK";
                        break;
                    case "COMMIT":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        /* actually execute SQL in $sql */
                        if (!isset($mdb2)) {
                            $mdb2 = real_connect($_SESSION['dsn'], $reply);
                        }
                        $res = $mdb2->commit();
                        handle_pear_error($res, $reply);
                        $status = "OK";
                        break;
                    case "ROLLBACK":
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        /* actually execute SQL in $sql */
                        if (!isset($mdb2)) {
                            $mdb2 = real_connect($_SESSION['dsn'], $reply);
                        }
                        foreach ($child->attributes() as $a => $b) {
                            if ($a == "svpname") {
                                $svpname = $b;
                                break;
                            }
                        }
                        if (isset($svpname)) {
                            $res = $mdb2->rollback($svpname);
                        } else {
                            $res = $mdb2->rollback();
                        }
                        handle_pear_error($res, $reply);
                        $status = "OK";
                        break;
                    case 'META':
                        if (!isset($_SESSION['key'])) {
                            throw new GdaException('Protocol error', true);
                        }
                        if ($token == "-") {
                            throw new GdaException('Not authenticated', true);
                        }
                        $args = array();
                        foreach ($child->children() as $sqlnode) {
                            if ($sqlnode->getName() == "arg") {
                                foreach ($sqlnode->attributes() as $a => $b) {
                                    if ($a == "name") {
                                        $args[$b] = $sqlnode[0];
                                        break;
                                    }
                                }
                            }
                        }
                        foreach ($child->attributes() as $a => $b) {
                            if ($a == "type") {
                                $type = $b;
                                break;
                            }
                        }
                        if (!isset($type)) {
                            throw new GdaException('Bad XML input', true);
                        }
                        if (!isset($mdb2)) {
                            $mdb2 = real_connect($_SESSION['dsn'], $reply);
                        }
                        do_meta($reply, $mdb2, $type, $args);
                        $status = "OK";
                        break;
                    default:
                        throw new GdaException('Unknown command ' . $child[0], false);
                }
            } else {
                throw new GdaException('Bad XML input', true);
            }
        }
    }
    if ($status != "CLOSED") {
        $chal = rand_str();
        $_SESSION['challenge'] = $chal;
        $reply->addChild('challenge', $chal);
    }
    if ($status != "") {
        $reply->addChild('status', $status);
    }
    $reply->addChild("counter", $_SESSION["counter"]);
    if (isset($debug) && $debug && $status != "CLOSED") {
        $reply->addChild('session', htmlspecialchars(SID));
    }
    /* output reply */
    $retval = gda_add_hash($_SESSION['key'], $reply->asXml());
    if ($apply_md5_to_key) {
        /* modify $key so it's possible for the client to forget about password */
        $_SESSION['key'] = md5($_SESSION['key']);
    }
    return $retval;
}