# # # add_file "www/automation.php" # content [d1b73648bccf7838555c77030daa3fb8106b2a94] # # patch "www/admin-source_control.php" # from [35af3e3fedbd74da5b196194442aa9bd75860f3d] # to [7e051f8e151fc1c289cf364650ba81894dd0a098] # # patch "www/admin-source_control_backend.php" # from [7b8dd85a0964b66aaf36c39344f6b0593d2a6740] # to [916c9c6d9717504088e99d96ebdf5c37608723f6] # # patch "www/common.php" # from [8f3bd6047bd0e87b006cb882abe899342a200533] # to [3ed2c6d820cc12003c3ea66d6b117294a268e89d] # ============================================================ --- www/automation.php d1b73648bccf7838555c77030daa3fb8106b2a94 +++ www/automation.php d1b73648bccf7838555c77030daa3fb8106b2a94 @@ -0,0 +1,131 @@ += '0') { + $out = $out . $got; + } else { + return false; + } + } +} + +function read_packet($sock) { + $cmdnum = read_int_to_colon($sock); + if ($cmdnum === false) { + return false; + } + $errcode = read_int_to_colon($sock); + if ($errcode === false) { + return false; + } + + $last = socket_read($sock, 1); + if ($last === false || strlen($last) == 0) { + return false; + } + $colon = socket_read($sock, 1); + if ($colon != ":") { + return false; + } + + $length = read_int_to_colon($sock); + if ($length === false) { + return false; + } + $contents = ''; + while(strlen($contents) < $length) { + $got = socket_read($sock, $length - strlen($contents)); + if ($got === false || strlen($got) == 0) { + return false; + } + $contents = $contents . $got; + } + return array("num" => $cmdnum, "err" => $errcode, + "last" => $last, "data" => $contents); +} + +function mtn_automate($command, $args) { + global $automateaddr, $automateport; + global $project; + + $cmdstring = $project . "\n"; + + $cmdstring = $cmdstring . "o"; + reset($args); + while(list($key, $val) = each($args)) { + $cmdstring = $cmdstring . strlen($key) . ":" . $key . strlen($val) . ":" . $val; + } + $cmdstring = $cmdstring . "el"; + reset($command); + while(list($key, $val) = each($command)) { + $cmdstring = $cmdstring . strlen($val) . ":" . $val; + } + $cmdstring = $cmdstring . "e"; + + $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); + if ($sock === false) { + return false; + } + if (socket_connect($sock, $automateaddr, $automateport) === false) { + socket_close($sock); + return false; + } + + do { + $wrote = socket_write($sock, $cmdstring); + if ($wrote === false) { + socket_close($sock); + return false; + } + $cmdstring = substr($cmdstring, $wrote); + } while (strlen($cmdstring) > 0); + + $result = array("data" => "", "error" => "", "errcode" => 0); + do { + $packet = read_packet($sock); + if ($packet === false) { + $result = false; + } else { + if ($packet["err"] == 0) { + $result["data"] = $result["data"] . $packet["data"]; + } else { + $result["errcode"] = $packet["err"]; + $result["error"] = $result["error"] . $packet["data"]; + } + } + } while(!($packet === false || $packet["last"] = 'l')); + + socket_close($sock); + return $result; +} + +/* +$keylist = mtn_automate(array("keys"), array()); + +print "vvvvvvvvvv\n"; +print $keylist["data"]; +print "^^^^^^^^^^\n"; + + +print_r(parse_basic_io($keylist["data"], false)); +print_r(parse_basic_io($keylist["data"], true)); +*/ + +?> \ No newline at end of file ============================================================ --- www/admin-source_control.php 35af3e3fedbd74da5b196194442aa9bd75860f3d +++ www/admin-source_control.php 7e051f8e151fc1c289cf364650ba81894dd0a098 @@ -11,20 +11,14 @@ Keys already in the database:
Keys already in the database:
"); - } - } - } +include_once("automation.php"); +$keydata = mtn_automate(array("keys"), array()); +$keylist = parse_basic_io($keydata["data"], true); +while(list($garbage, $key_item) = each($keylist)) { + if (array_search("database", $key_item["public_location"]) !== false) { + print($key_item["name"][0] . "
"); + } + } ?>
============================================================ --- www/admin-source_control_backend.php 7b8dd85a0964b66aaf36c39344f6b0593d2a6740 +++ www/admin-source_control_backend.php 916c9c6d9717504088e99d96ebdf5c37608723f6 @@ -1,5 +1,6 @@ include_once("common-ctrl.php"); keydata; - preg_match('/^\[[^ \]]* ([^\]]*)\]/', $args->keydata, $matches); - $keyname = $matches[1]; - if($keyname == null) - print $json->encode(array("error" => "Cannot extract key name.")); - else { - $out = array(); - file_put_contents($projdir . "/keyfile", $args->keydata, LOCK_EX); - exec("$monotone -d '$projdir/kdb' db init 2>&1", $out, $res1); - exec("$monotone -d '$projdir/kdb' read '$projdir/keyfile'", $out, $res2); - exec("$monotone --key-to-push '$keyname' -d '$projdir/kdb' push '$project.$hostname' '' -k '$hostkey' 2>&1", $out, $res3); - exec("rm -f '$projdir/kdb' '$projdir/kdb-journal' '$projdir/keyfile'"); - if($res1 || $res2 || $res3) { - $outstr = ""; - foreach ($out as $i) - $outstr = $outstr . $i . "\n"; - print $json->encode(array("error" => "Key upload failed...", - "verboseError" => $outstr)); - } else - print $json->encode(array("result" => "ok")); - } - } + if(allowed('access')) { + $args->keydata; + $match_ok = preg_match('/^\[pubkey ([^\]]*)\][^\[\]]+\[end\]\s*$/', $args->keydata, $matches); + if (!$match_ok) { + print $json->encode(array("error" => "Key data doesn't look like a key.")); + } else { + $result = mtn_automate(array("read_packets", $args->keydata), array()); + if ($result === false) { + print $json->encode(array("error" => "Unknown error.")); + } elseif ($result["errcode"] != 0) { + print $json->encode(array("error" => "Internal error: " . $result["error"])); + } else { + print $json->encode(array("result" => "ok")); + } + } + } } else if ($action === "chwriters") { if(allowed('access')) { file_put_contents($projdir . "/write-permissions", $args->newperm, LOCK_EX); ============================================================ --- www/common.php 8f3bd6047bd0e87b006cb882abe899342a200533 +++ www/common.php 3ed2c6d820cc12003c3ea66d6b117294a268e89d @@ -1,5 +1,6 @@ ini_set("display_errors", false); '; @@ -7,59 +8,99 @@ $conffile = $confdir . "/hostconfig"; $conffile = $confdir . "/hostconfig"; # read conffile -$firstkey = '^[^\s"[]\S*'; -$key = '\s+[^\s"[]\S*'; -$str = '\s+"(?:\\\\"|\\\\\\\\|[^\\\\"])*"'; -$hex = '\s+\[[[:xdigit:]]*\]'; -$conf = file_get_contents($conffile); -$pattern = "$firstkey|$key|$hex|$str"; -preg_match_all("/$pattern/", $conf, $splitconf, PREG_SET_ORDER); +// array of ('key' => key, 'values' => array(...)) /* no stanza */ +// array of (key => array(values)) /* with stanza */ +function parse_basic_io($data, $keep_stanzas) { + // not-a-space that doesn't start like one of the others + $key = '[^\s"[]\S*'; + // escaped quote or backslash, or other + $str = '"(?:\\\\"|\\\\\\\\|[^\\\\"])*"'; + // hex digits in square brackets + $hex = '\[[[:xdigit:]]*\]'; + $pattern = "(?:^|\s+)(?:($key)|($hex)|($str))"; -function nxt(&$arr) { - $foo = each($arr); - return preg_replace('/^\s*["[](.*)[\]"]\s*$/', '$1', $foo['value'][0]); + preg_match_all("/$pattern/", $data, $splitted, PREG_SET_ORDER); + $out = array(); + $idx = 0; + while(list($splitted_index, $value) = each($splitted)) { + if($value[1]) { // key + if ($keep_stanzas) { + $key = $value[1]; + $newline1 = strpos($value[0], "\n"); + $newline2 = false; + if ($newline1 !== false) { + $newline2 = strpos($value[0], "\n", $newline1 + 1); + } + if ($newline2 !== false || $newline1 === false) { + // Zero or two newlines -- beginning of file, or a blank line + $idx = array_push($out, array()) - 1; + } + $out[$idx][$key] = array(); + } else { + $idx = array_push($out, array()) - 1; + $out[$idx]["key"] = $value[1]; + $out[$idx]["value"] = array(); + } + } elseif($value[2]) { // hex + $val = preg_replace('/[][]/', '', $value[2]); + if ($keep_stanzas) { + array_push($out[$idx][$key], $val); + } else { + array_push($out[$idx]["value"], $val); + } + } elseif($value[3]) { // str + $val = preg_replace('/\\\\(.)/', '$1', $value[3]); + $val = preg_replace('/^"|"$/', '', $val); + if ($keep_stanzas) { + array_push($out[$idx][$key], $val); + } else { + array_push($out[$idx]["value"], $val); + } + } + } + return $out; } -reset($splitconf); -while($v = each($splitconf)) { - $i = $v['value'][0]; - $i = preg_replace("/\n+\$/", '', $i); - $i = preg_replace("/^\n+/", '', $i); - $i = preg_replace('/^\s+/', '', $i); - $i = preg_replace('/\s+$/', '', $i); - if($i[0]=='"'||$i[0]=='[') - continue; - if($i == "userpass") { - $adminuser = nxt($splitconf); - $adminpass = nxt($splitconf); - } elseif($i == "hostname") { - $hostname = nxt($splitconf); - } elseif($i == "project_dir") { - $project_dir = nxt($splitconf); - } elseif($i == "adodb_path") { - $adodb_path = nxt($splitconf); - } elseif($i == "graph_dir") { - $graph_dir = nxt($splitconf); - } elseif($i == "www_dir") { - $www_dir = nxt($splitconf); - } elseif($i == "dbstring") { - $dbstring = nxt($splitconf); - } elseif($i == "hostkey") { - $hostkey = nxt($splitconf); - } elseif($i == "hostkeypass") { - $hostkeypass = nxt($splitconf); - } elseif($i == "adminaddr") { - # addr:port - list($adminaddr, $adminport) = split(":", nxt($splitconf)); - } elseif($i == "monotone") { - $monotone = nxt($splitconf); - } elseif($i == "site_owner_email") { - $site_owner_email = nxt($splitconf); - } elseif($i == "base_url") { - $base_url = nxt($splitconf); - } + + + +$conf = parse_basic_io(file_get_contents($conffile), false); + +while(list($garbage, $item) = each($conf)) { + $key = $item["key"]; + $value = $item["value"]; + if($key == "userpass") { + $adminuser = $value[0]; + $adminpass = $value[1]; + } elseif($key == "hostname") { + $hostname = $value[0]; + } elseif($key == "project_dir") { + $project_dir = $value[0]; + } elseif($key == "adodb_path") { + $adodb_path = $value[0]; + } elseif($key == "graph_dir") { + $graph_dir = $value[0]; + } elseif($key == "www_dir") { + $www_dir = $value[0]; + } elseif($key == "dbstring") { + $dbstring = $value[0]; + } elseif($key == "hostkey") { + $hostkey = $value[0]; + } elseif($key == "hostkeypass") { + $hostkeypass = $value[0]; + } elseif($key == "adminaddr") { + // addr:port + list($adminaddr, $adminport) = split(":", $value[0]); + } elseif($key == "automateaddr") { + list($automateaddr, $automateport) = split(":", $value[0]); + } elseif($key == "monotone") { + $monotone = $value[0]; + } elseif($key == "site_owner_email") { + $site_owner_email = $value[0]; + } elseif($key == "base_url") { + $base_url = $value[0]; + } } -reset($splitconf); include_once("JSON.php"); $json = new Services_JSON(); @@ -102,6 +143,7 @@ $db = &ADONewConnection( $dbstring ); $administrator = false; $pass_ok = false; $db = &ADONewConnection( $dbstring ); + $result = $db->Execute("SELECT password, admin, email, active FROM users WHERE username=?", array($username)); if ($result) { $rows = $result->RecordCount(); @@ -147,4 +189,5 @@ function get_permissions($who, $what) { } return $permissions; } -?> + +?> \ No newline at end of file