.install/scuttlebutt.sh + init

This commit is contained in:
qo-op 2020-03-23 19:07:37 +01:00
parent fefa4a6a88
commit 9bbb0abecd
38 changed files with 2221 additions and 35 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Enable camera on Raspberry Pi
# set_config_var taken from raspi-config
set_config_var() {
lua - "$1" "$2" "$3" <<EOF > "$3.bak"
local key=assert(arg[1])
local value=assert(arg[2])
local fn=assert(arg[3])
local file=assert(io.open(fn))
local made_change=false
for line in file:lines() do
if line:match("^#?%s*"..key.."=.*$") then
line=key.."="..value
made_change=true
end
print(line)
end
if not made_change then
print(key.."="..value)
end
EOF
sudo mv "$3.bak" "$3"
}
# Command extracted from raspi-config
sed /boot/config.txt -i -e "s/^startx/#startx/"
sed /boot/config.txt -i -e "s/^fixup_file/#fixup_file/"
set_config_var start_x 1 /boot/config.txt
set_config_var gpu_mem 128 /boot/config.txt

52
.install/ipfs-pi-stream/install Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env bash
set -e
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Enable camera on the Raspberry Pi
sudo "$BASE_DIR/enable-camera.sh"
# Install ffmpeg and supporting tools
sudo apt-get install -y ffmpeg lsof inotify-tools nginx
# Copy placeholder for audio-only streams
cp "$BASE_DIR/audio.jpg" "$HOME/audio.jpg"
# Add user to be able to modify nginx directories
sudo usermod -a -G "$USER" www-data
sudo chmod g+rw /var/www/html
# TODO: why is this needed?
sudo chmod a+rw /var/www/html
sudo cp -f "$BASE_DIR/process-stream.sh" /usr/bin/process-stream.sh
sudo cp -f "$BASE_DIR/process-stream.service" /etc/systemd/system/process-stream.service
sudo systemctl daemon-reload
sudo systemctl enable process-stream
# Add hourly job to clear out old data
echo "41 * * * * $USER /usr/local/bin/ipfs repo gc" | sudo tee --append /etc/crontab
# Install the ipfs video player
mkdir "$BASE_DIR/tmp"
current_dir="$(pwd)"
git clone https://github.com/tomeshnet/ipfs-live-streaming.git "$BASE_DIR/tmp/ipfs-live-streaming"
cd "$BASE_DIR/tmp/ipfs-live-streaming"
git checkout b9be352582317e5336ddd7183ecf49042dafb33e
cd "$current_dir"
VIDEO_PLAYER_PATH="$BASE_DIR/tmp/ipfs-live-streaming/terraform/shared/video-player"
sed -i s#__IPFS_GATEWAY_SELF__#/ipfs/# "$VIDEO_PLAYER_PATH/js/common.js"
sed -i s#__IPFS_GATEWAY_ORIGIN__#https://ipfs.io/ipfs/# "$VIDEO_PLAYER_PATH/js/common.js"
IPFS_ID=$(ipfs id | grep ID | head -n 1 | awk -F\" '{print $4}')
sed -i "s#live.m3u8#/ipns/$IPFS_ID#" "$VIDEO_PLAYER_PATH/js/common.js"
sed -i s#__M3U8_HTTP_URLS__#\ # "$VIDEO_PLAYER_PATH/js/common.js"
cp -r "$VIDEO_PLAYER_PATH" /var/www/html/video-player
rm -rf "$BASE_DIR/tmp"
# Add entry into nginx home screen
APP="<div class='app'><h2>IPFS Pi Stream Player</h2>IPFS Video player for Pi Stream. <br />M3U8 Stream located <a href='/ipns/$IPFS_ID'>over ipns</a> <br/><a href='/video-player/'>Go </a> and play with built in video player</div>"
sudo sed -i "s#<\!--APPLIST-->#$APP\n<\!--APPLIST-->#" "/var/www/html/index.html"

View File

@ -0,0 +1,16 @@
[Unit]
Description=Service to process RTMP stream
Wants=network.target
After=ipfs.service
[Service]
Type=simple
User=pi
Group=pi
ExecStart=/usr/bin/process-stream.sh
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,124 @@
#!/usr/bin/env bash
HLS_TIME=40
M3U8_SIZE=3
IPFS_GATEWAY="https://ipfs.io"
# Load settings
# Prepare Pi Camera
sudo modprobe bcm2835-v4l2
sudo v4l2-ctl --set-ctrl video_bitrate=100000
function startFFmpeg() {
while true; do
mv ~/ffmpeg.log ~/ffmpeg.1
echo 1 > ~/stream-reset
# Stream Raspberry Pi Camera
ffmpeg -f video4linux2 -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -hls_time "${HLS_TIME}" "${what}.m3u8" > ~/ffmpeg.log 2>&1
# Stream FM Station from a SDR module (see contrib/pi-stream to install drivers)
# Frequency ends in M IE 99.9M
# rtl_fm -f 99.9M -M fm -s 170k -A std -l0 -E deemp -r 44.1k | ffmpeg -r 15 -loop 1 -i ../audio.jpg -f s16le -ac 1 -i pipe:0 -c:v libx264 -tune stillimage -preset ultrafast -hls_time "${HLS_TIME}" "${what}.m3u8" > ~/ffmpeg 2>&1
sleep 0.5
done
}
# Create directory for HLS content
currentpath="$HOME/live"
sudo umount "${currentpath}"
rm -rf "${currentpath}"
mkdir "${currentpath}"
sudo mount -t tmpfs tmpfs "${currentpath}"
# shellcheck disable=SC2164
cd "${currentpath}"
what="$(date +%Y%m%d%H%M)-LIVE"
# Start ffmpeg in background
startFFmpeg &
while true; do
#TODO# Fix this one
# shellcheck disable=SC2086,SC2012
nextfile=$(ls -tr ${what}*.ts 2>/dev/null | head -n 1)
if [ -n "${nextfile}" ]; then
# Check if the next file on the list is still being written to by ffmpeg
if lsof "${nextfile}" | grep -1 ffmpeg; then
# Wait for file to finish writing
# If not finished in 45 seconds something is wrong, timeout
inotifywait -e close_write "${nextfile}" -t ${HLS_TIME}
fi
# Grab the timecode from the m3u8 file so we can add it to the log
timecode=$(grep -B1 "${nextfile}" "${what}.m3u8" | head -n1 | awk -F : '{print $2}' | tr -d ,)
attempts=5
until [[ "${timecode}" || ${attempts} -eq 0 ]]; do
# Wait and retry
sleep 0.5
timecode=$(grep -B1 "${nextfile}" "${what}.m3u8" | head -n1 | awk -F : '{print $2}' | tr -d ,)
attempts=$((attempts-1))
done
if ! [[ "${timecode}" ]]; then
# Set approximate timecode
timecode="${HLS_TIME}.000000"
fi
reset_stream=$(cat ~/stream-reset)
reset_stream_marker=''
if [[ ${reset_stream} -eq '1' ]]; then
reset_stream_marker=" #EXT-X-DISCONTINUITY"
fi
echo 0 > ~/stream-reset
# Current UTC date for the log
time=$(date "+%F-%H-%M-%S")
# Add ts file to IPFS
ret=$(ipfs add --pin=false "${nextfile}" 2>/dev/null > ~/tmp.txt; echo $?)
attempts=5
until [[ ${ret} -eq 0 || ${attempts} -eq 0 ]]; do
# Wait and retry
sleep 0.5
ret=$(ipfs add --pin=false "${nextfile}" 2>/dev/null > ~/tmp.txt; echo $?)
attempts=$((attempts-1))
done
if [[ ${ret} -eq 0 ]]; then
# Update the log with the future name (hash already there)
echo "$(cat ~/tmp.txt) ${time}.ts ${timecode}${reset_stream_marker}" >> ~/process-stream.log
# Remove nextfile and tmp.txt
rm -f "${nextfile}" ~/tmp.txt
# Write the m3u8 file with the new IPFS hashes from the log
totalLines="$(wc -l ~/process-stream.log | awk '{print $1}')"
sequence=0
if ((totalLines>M3U8_SIZE)); then
sequence=$((totalLines-M3U8_SIZE))
fi
{
echo "#EXTM3U"
echo "#EXT-X-VERSION:3"
echo "#EXT-X-TARGETDURATION:${HLS_TIME}"
echo "#EXT-X-MEDIA-SEQUENCE:${sequence}"
} > current.m3u8
tail -n ${M3U8_SIZE} ~/process-stream.log | awk '{print $6"#EXTINF:"$5",\n'${IPFS_GATEWAY}'/ipfs/"$2}' | sed 's/#EXT-X-DISCONTINUITY#/#EXT-X-DISCONTINUITY\n#/g' >> current.m3u8
# Add m3u8 file to IPFS and IPNS publish
m3u8hash=$(ipfs add current.m3u8 | awk '{print $2}')
ipfs name publish --timeout=5s "${m3u8hash}" &
# Copy files to web server
cp current.m3u8 /var/www/html/live.m3u8
cp ~/process-stream.log /var/www/html/live.log
fi
else
sleep 5
fi
done

View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -e
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
sudo systemctl stop process-stream
sudo systemctl disable process-stream
sudo rm -f /usr/bin/process-stream.sh
sudo rm -f /etc/systemd/system/process-stream.service
sudo systemctl daemon-reload
# Remove ffmpeg and supporting tools
sudo apt-get -y remove ffmpeg lsof inotify-tools
# Revert permissions
sudo chmod 755 /var/www/html
sed -i "/ipfs repo gc/d" | sudo tee --append /etc/crontab

View File

@ -1,7 +1,11 @@
# Install IPFS
ipfs() {
mkdir -p ~/.zen/fatlayer_install
cd ~/.zen/fatlayer_install
echo -e "${c_yellow}Onboarding IPFS...$c_"
[[ -f /usr/local/bin/ipfs ]] && sudo service ipfs stop
if [[ $ARM == "yes" ]]; then
wget https://dist.ipfs.io/ipfs-update/v1.5.2/ipfs-update_v1.5.2_linux-arm.tar.gz -O $MY_PATH/ipfs-update.tar.gz || err+="Download ipfs-update"
else
@ -23,7 +27,8 @@ ipfs() {
sudo cp -f $MY_PATH/templates/1/ipfs.service /etc/systemd/system/
sudo sed -i "s/_USER/$USER/g" /etc/systemd/system/ipfs.service
sudo systemctl daemon-reload || err+="Restart IPFS"
# sudo systemctl daemon-reload || err+="Restart IPFS"
# DO NOT START YET... Must get IPFS swarm.key from a G1SSB Pub !!
sudo systemctl enable ipfs || err+="Enable IPFS daemon"
}

107
.install/ipfs/install Executable file
View File

@ -0,0 +1,107 @@
#!/usr/bin/env bash
# shellcheck disable=SC1091
set -e
GO_IPFS_VERSION="v0.4.22"
ARCH="$(uname -m)"
case "$ARCH" in
x86_64)
ARCH="amd64"
;;
i386 | i586 | i686 )
ARCH="386"
;; armv7l)
ARCH="arm";
;;
armv6l)
ARCH="arm";
;;
aarch64)
ARCH="arm64";
;;
*)
echo "Unknown Arch"
exit 1
;;
esac
# Hyperborea connected peer used to bootstrap Hyperborea only ipfs nodes
# DarkDrgn2k's peer
IPFS_PEER_1="/ip6/fc6e:691e:dfaa:b992:a10a:7b49:5a1a:5e09/tcp/4001/ipfs/QmU6NeD2Uu34WKest1NZGvGmScLhN1zVo66K35GeE6Jft2"
# HeavyMetal's peer
IPFS_PEER_2="/ip6/fc6d:3961:6744:7d94:31ba:2bf3:30bf:ebab/tcp/4001/ipfs/QmRGk8DdMWy5P5xgUisnv7u4hV4WfgEhbxa6iGpviYGC7q"
# Yggdrasil connected peer used to bootstrap hyperborea only ipfs nodes
IPFS_PEER_3="/ip6/301:4541:2f84:1188:216:3eff:fed5:a2df/tcp/4001/ipfs/QmWZpTdfETtpjJphVE1YbxMkUcL84idkg44Cq1XWSBNm7P"
# DarkDrgn2k's peer
IPFS_PEER_4="/ip6/200:98bf:d6df:e49a:f525:40bf:18d:ac45/tcp/4001/ipfs/QmU6NeD2Uu34WKest1NZGvGmScLhN1zVo66K35GeE6Jft2"
# HeavyMetal's peer
IPFS_PEER_5="/ip6/201:3d73:dbf:da97:e008:2d29:3919:cdb1/tcp/4001/ipfs/QmRGk8DdMWy5P5xgUisnv7u4hV4WfgEhbxa6iGpviYGC7q"
# Yk3Music's Irvine-CA peer
IPFS_PEER_6="/ip6/fcbb:1db3:54fb:e519:d915:d7db:4893:4f30/tcp/4001/ipfs/QmZEiPvrfZHapq4uiyTDEcR2szCUhDnjdS4q3Uv2b1Uh88"
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Download and install IPFS
mkdir "$BASE_DIR/tmp"
wget "https://dist.ipfs.io/go-ipfs/${GO_IPFS_VERSION}/go-ipfs_${GO_IPFS_VERSION}_linux-${ARCH}.tar.gz" -O "$BASE_DIR/tmp/go-ipfs.tar.gz"
tar xvfz "$BASE_DIR/tmp/go-ipfs.tar.gz" -C "$BASE_DIR/tmp"
sudo cp "$BASE_DIR/tmp/go-ipfs/ipfs" /usr/local/bin/ipfs
sudo chown root:staff /usr/local/bin/ipfs
rm -rf "$BASE_DIR/tmp"
# Initialize IPFS if not already
if [ ! -d "$HOME/.ipfs" ]; then
ipfs init || true
fi
# Enable gossipsub routing
ipfs config Pubsub.Router gossipsub
# Enable Filestore for --nocopy capability
ipfs config --bool Experimental.FilestoreEnabled true
# Setup connection management - Reduce connections to stress the Pi less
# XXX: These values need to be tweaked and tested
ipfs config Swarm.ConnMgr.Type basic
ipfs config --json Swarm.ConnMgr.LowWater 100
ipfs config --json Swarm.ConnMgr.HighWater 200
ipfs config Swarm.ConnMgr.GracePeriod 60s
# Enable QUIC for better connections when possible
ipfs config --bool Experimental.QUIC true
# Configure HTTP reverse proxy to IPFS gateway
sudo cp "$BASE_DIR/ipfs-http-gateway.conf" /etc/nginx/site-path-enabled/ipfs-http-gateway.conf
sudo systemctl restart nginx.service
# shellcheck source=../shared/nodeinfo/install
source "$BASE_DIR/../shared/nodeinfo/install"
sudo cp "$BASE_DIR/nodeinfo-ipfs" /opt/tomesh/nodeinfo.d/ipfs
# Add bootstrap addresses
ipfs bootstrap add "$IPFS_PEER_1"
ipfs bootstrap add "$IPFS_PEER_2"
ipfs bootstrap add "$IPFS_PEER_3"
ipfs bootstrap add "$IPFS_PEER_4"
ipfs bootstrap add "$IPFS_PEER_5"
ipfs bootstrap add "$IPFS_PEER_6"
# Download dependencies
sudo apt-get install -y jq
# Copy file
sudo cp "$BASE_DIR/ipfs-swarm.sh" /usr/local/bin/
sudo chmod +x /usr/local/bin/ipfs-swarm.sh
# Configure systemd to start ipfs.service on system boot
sudo cp "$BASE_DIR/ipfs.service" /etc/systemd/system/ipfs.service
sudo sed -i "s|__USER_HOME__|${HOME}|" /etc/systemd/system/ipfs.service
sudo systemctl daemon-reload
sudo systemctl enable ipfs.service
sudo systemctl start ipfs.service
# Add entry into nginx home screen
APP="<div class='app'><h2>IPFS</h2>A peer-to-peer hypermedia protocol to make the web faster, safer, and more open. <br/><a href='/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme'>Go</a></div>"
sudo sed -i "s#<\!--APPLIST-->#$APP\n<\!--APPLIST-->#" "/var/www/html/index.html"

View File

@ -0,0 +1,18 @@
location /ipfs {
proxy_pass http://127.0.0.1:8080/ipfs;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /ipns {
proxy_pass http://127.0.0.1:8080/ipns;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Prevent Caching
expires 0;
add_header Cache-Control private;
}

View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# This script connects to local mesh peers,
# and it sets up connection filters based on what networks this node can access.
# It runs continually, to change IPFS settings as the environment around the node changes.
# Wait for IPFS to initalize
attempts=10
until [[ $(curl http://localhost:5001/api/v0/id -s 2>/dev/null) || ${attempts} -eq 0 ]]; do
sleep 3
attempts=$((attempts-1))
done
if [[ ${attempts} -eq 0 ]]; then
echo "Error: Failed to connect to local IPFS daemon. Is it running?"
exit 1
fi
function addPeer {
addr=$1
# See if they have IPFS enabled
res=$(curl http://["${addr}"]/nodeinfo.json -s)
if [ ! -x "${res}" ]; then
id=$(echo "${res}" | jq -r -M '.services.ipfs.ID')
# Value is found
if [[ ! ${id} == "null" ]] && [[ ! "${id}" == "" ]]; then
# Connect to neighbouring IPFS nodes
# Check for QUIC connections first
if [ "$(echo "${res}" | jq -r -M '.services.IPFS.quic_enabled')" == 'true' ]; then
# ID is not needed for QUIC connections
echo "Connecting to ${addr} with QUIC"
ipfs swarm connect "/ip6/${addr}/udp/4001/quic"
else
echo "Connecting to ${addr} over TCP"
ipfs swarm connect "/ip6/${addr}/tcp/4001/ipfs/${id}"
fi
fi
fi
}
# Add cjdns direct peers
while read -r cjdns_peer; do
cjdns_addr=$(sudo /opt/cjdns/publictoip6 "$cjdns_peer")
addPeer "${cjdns_addr}"
# Add all that node's peers to the bottom of the list to check further hop peers
# XXX: The below command hasn't been working -- so for now only 1-hop peers are checked
#peers+=$(cjdnstool query getpeers $peer | sed -e '1d;$d' |awk -F. '{ print $6".k" }')
done <<< "$(sudo nodejs /opt/cjdns/tools/peerStats 2>/dev/null | awk '{ if ($3 == "ESTABLISHED") print $2 }' | awk -F. '{ print $6".k" }' | xargs)"
# Add yggdrasil direct peers
if [ "$(command -v yggdrasil)" ]; then
while read -r ygg_peer; do
addPeer "${ygg_peer}"
done <<< "$(sudo yggdrasilctl getPeers | grep -v "(self)" | awk '{print $1}' | grep -v bytes_recvd | xargs)"
fi
# Update peers data since ipfs just started
sudo /usr/local/bin/nodeinfo-update.sh

View File

@ -0,0 +1,16 @@
[Unit]
Description=IPFS daemon
Wants=network.target
After=network.target
[Service]
Type=simple
Environment=IPFS_PATH=__USER_HOME__/.ipfs
ExecStart=/usr/local/bin/ipfs daemon --enable-namesys-pubsub --migrate=true
ExecStartPost=/usr/local/bin/ipfs-swarm.sh
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target

25
.install/ipfs/nodeinfo-ipfs Executable file
View File

@ -0,0 +1,25 @@
#!/bin/sh
ipfsinfo=$( curl -s http://localhost:5001/api/v0/id)
id=$(echo $ipfsinfo | jq ".ID")
version=$(echo $ipfsinfo | jq ".AgentVersion")
if [ -z "$id" ]; then
id='""'
fi
if [ -z "$version" ]; then
version='""'
fi
echo '"ipfs":{'
echo '"version":'${version}','
if [ quic_enabled = "$(ipfs config Experimental.QUIC)" ]; then
echo '"quic_enabled":"'${quic_enabled}'",'
else
echo '"quic_enabled":"false",'
fi
echo '"ID":'${id}
echo "},"

33
.install/ipfs/uninstall Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -e
# Remove script and service for ipfs bootstrap
sudo rm -r /usr/local/bin/ipfs-swarm.sh || true
# Uninstall dependencies
sudo apt-get remove -y jq
# Uninstall IPFS
sudo systemctl disable ipfs.service 2>/dev/null || true
sudo systemctl stop ipfs.service 2>/dev/null || true
sudo systemctl daemon-reload
sudo rm -f /usr/local/bin/ipfs
sudo rm -f /etc/systemd/system/ipfs.service
if [ -d "$HOME/.ipfs" ]; then
echo "Found ~/.ipfs"
read -p "Keep your IPFS data (Y/n)? " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Nn]$ ]]; then
echo -e "\e[1;31mRemoving ~/.ipfs\e[0m"
sudo rm -rf ~/.ipfs
else
echo -e "\e[1;32mKeeping ~/.ipfs\e[0m"
fi
fi
# Remove HTTP to IPFS gateway
sudo rm -f /etc/nginx/sites-enabled/ipfs-http-gateway
sudo rm -f /etc/nginx/sites-available/ipfs-http-gateway
sudo systemctl restart nginx.service

View File

@ -0,0 +1,7 @@
location /cgi-bin/ {
gzip off;
root /var/www/html;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

24
.install/nginx/common.css Normal file
View File

@ -0,0 +1,24 @@
body {
font-family: Arial, Helvetica, sans-serif;
}
h1 {
text-align:center;
}
.app h2 {
margin:0;
padding:0;
background:black;
color:white;
padding:5px;
margin-bottom:5px;
}
.app {
display:inline-block;
float:left;
width:calc( 33% - 20px );
vertical-align: top;
border:1px solid #cccccc;
margin:5px;
padding:5px;
min-width:400px;
}

58
.install/nginx/common.js Normal file
View File

@ -0,0 +1,58 @@
// CJDNS pubkey to IPv6
// BASE32 code form CJDNS library
var numForAscii = [
99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,99,99,99,99,99,99,
99,99,10,11,12,99,13,14,15,99,16,17,18,19,20,99,
21,22,23,24,25,26,27,28,29,30,31,99,99,99,99,99,
99,99,10,11,12,99,13,14,15,99,16,17,18,19,20,99,
21,22,23,24,25,26,27,28,29,30,31,99,99,99,99,99,
];
// see util/Base32.h
var Base32_decode = function (input) {
var output = [];
var outputIndex = 0;
var inputIndex = 0;
var nextByte = 0;
var bits = 0;
while (inputIndex < input.length) {
var o = input.charCodeAt(inputIndex);
if (o & 0x80) { throw new Error(); }
var b = numForAscii[o];
inputIndex++;
if (b > 31) { throw new Error("bad character " + input[inputIndex] + " in " + input); }
nextByte |= (b << bits);
bits += 5;
if (bits >= 8) {
output[outputIndex] = nextByte & 0xff;
outputIndex++;
bits -= 8;
nextByte >>= 8;
}
}
if (bits >= 5 || nextByte) {
throw new Error("bits is " + bits + " and nextByte is " + nextByte);
}
return output;
};
// Convert Public Key to IPv6
// TODO add :
var publicKeyCache = [];
function public2IPv6(PubKey) {
if (!publicKeyCache[PubKey]) {
var IPv6=Base32_decode(PubKey);
IPv6=sha512(sha512.array(IPv6));
IPv6=IPv6.substr(0,32);
publicKeyCache[PubKey]=IPv6;
}
return publicKeyCache[PubKey];
}

22
.install/nginx/index.html Normal file
View File

@ -0,0 +1,22 @@
<html>
<head>
<link href="/common.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Welcome to Node __NODENAME__</h1>
Services running on this node.<br/>
<div class="app"><h2>CJDNS Neighbours</h2><div id="networkcjdns" style="width:100%; height:300px"></div></div>
<div class="app"><h2>Yggdrasil Neighbours</h2><div id="networkyggdrasil" style="width:100%; height:300px"></div></div>
<br />
<!--APPLIST-->
</body>
<script type="text/javascript" src="/vis.min.js"></script>
<script type="text/javascript" src="/sha512.js"></script>
<script type="text/javascript" src="/map.js"></script>
<link href="/vis-network.min.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/common.js"></script>
<script>
LoadXMLDoc_cjdns();
LoadXMLDoc_ygg();
</script>
</html>

46
.install/nginx/install Executable file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env bash
set -e
if [ ! -x "$(command -v nginx)" ] || [ ! -d "/etc/nginx/site-path-enabled" ]; then
LAST_BASE="$BASE_DIR"
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
sudo apt-get install nginx fcgiwrap -y
sudo cp -f "$BASE_DIR/main.conf" /etc/nginx/sites-available/main.conf
sudo ln -s /etc/nginx/sites-available/main.conf /etc/nginx/sites-enabled/main.conf || true
sudo rm /etc/nginx/sites-enabled/default || true
sudo mkdir /etc/nginx/site-path-enabled || true
# Install welcome page
sudo cp "$BASE_DIR/index.html" "/var/www/html/index.html"
sudo sed -i "s/__NODENAME__/$NEWHOSTNAME/" "/var/www/html/index.html"
sudo cp "$BASE_DIR/sha512.js" "/var/www/html/sha512.js"
sudo cp "$BASE_DIR/vis.min.js" "/var/www/html/vis.min.js"
sudo cp "$BASE_DIR/vis-network.min.css" "/var/www/html/vis-network.min.css"
sudo cp "$BASE_DIR/map.js" "/var/www/html/map.js"
sudo cp "$BASE_DIR/common.css" "/var/www/html/common.css"
sudo cp "$BASE_DIR/common.js" "/var/www/html/common.js"
sudo cp "$BASE_DIR/cgi-bin.conf" "/etc/nginx/site-path-enabled/cgi-bin.conf"
# CJDNS peers
mkdir "$BASE_DIR/tmp"
git clone https://github.com/hamishcoleman/cjdns_tool.git "$BASE_DIR/tmp/cjdns_tool"
sudo mkdir -p "/var/www/html/cgi-bin/lib/" || true
sudo cp -r "$BASE_DIR/tmp/cjdns_tool/lib" "/var/www/html/cgi-bin/"
rm -rf "$BASE_DIR/tmp"
sudo cp "$BASE_DIR/peers-cjdns" "/var/www/html/cgi-bin/peers-cjdns"
# Yggdrasil peers
sudo cp "$BASE_DIR/peers-yggdrasil" "/var/www/html/cgi-bin/peers-yggdrasil"
sudo chmod +x "/var/www/html/cgi-bin/peers-cjdns"
sudo chmod +x "/var/www/html/cgi-bin/peers-yggdrasil"
sudo chown -R www-data.www-data /var/www/html
BASE_DIR="$LAST_BASE"
fi

6
.install/nginx/main.conf Normal file
View File

@ -0,0 +1,6 @@
server {
listen 80;
listen [::]:80;
include /etc/nginx/site-path-enabled/*.conf;
root /var/www/html;
}

121
.install/nginx/map.js Normal file
View File

@ -0,0 +1,121 @@
function LoadXMLDoc_cjdns() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
CJDNSMap(this);
}
};
xmlhttp.open("GET", "/cgi-bin/peers-cjdns", true);
xmlhttp.send();
}
function LoadXMLDoc_ygg() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
YggdrasilMap(this);
}
};
xmlhttp.open("GET", "/cgi-bin/peers-yggdrasil", true);
xmlhttp.send();
}
// Cleanup the json provided by the CJDNS
// Otherwise it will not parse properly
// ToDo - this is really hacking, there should be a better way of doing this
function ToJson(json) {
json=json.replace(new RegExp("}", "g"),"\"null\": \"\"}");
json=json.replace(new RegExp(" ","g")," ");
json=json.replace(new RegExp(" ","g")," ");
json=json.replace(new RegExp("\n","g")," ");
json=json.replace("}, ]","}]");
// Parse it
return JSON.parse(json);
}
function CJDNSMap(ajax) {
var Nodes;
var NodeExist=Array();
jsonDisplay=ajax.response.replace(new RegExp("'", "g"),"\"");
Nodes=ToJson(jsonDisplay);
for (var a=0; a< Nodes.peers.length; a++) {
var parts=Nodes.peers[a].addr.split(".");
UpdateNode(parts[5],public2IPv6(parts[5]),parts[4], Nodes.peers[a].recvKbps + "kpbs / " + Nodes.peers[a].sendKbps + " kbps","cjdns",NodeExist);
}
DeleteNodes("cjdns",NodeExist);
setTimeout("LoadXMLDoc_cjdns()",1000);
}
lastrx=[];
lasttx=[];
function YggdrasilMap(ajax) {
var Nodes;
var NodeExist=Array();
str=ajax.response;
Nodes=JSON.parse(str);
for (var i in Nodes.peers) {
var addr=i;
node=Nodes.peers[i];
if (node.port>0) { //not self
rx=node.bytes_recvd-lastrx[node.port];
tx=node.bytes_sent-lasttx[node.port];
lastrx[node.port]=node.bytes_recvd;
lasttx[node.port]=node.bytes_sent;
UpdateNode(addr,addr,node.port,rx + " bps /" + tx + " bps", "yggdrasil",NodeExist);
}
}
DeleteNodes("yggdrasil",NodeExist);
setTimeout("LoadXMLDoc_ygg()",1000);
}
// Update Map
// vis.js Initialization
var nodeIDs=[];
var edgeIDs=[];
var nodesArray=[];
var edgesArray=[];
var nodes=[];
var edges=[];
var network=[];
//var nodeIds,edgesIDs, nodesArray, nodes, edgesArray, edges, network;
function InitMap(name) {
nodeIDs[name]=[];
edgeIDs[name]=[];
nodesArray[name]=[{id: 0, label: 'Me'}];
nodes[name] = new vis.DataSet(nodesArray[name]);
edgesArray[name] = [];
edges[name] = new vis.DataSet(edgesArray[name]);
var container = document.getElementById('network' + name);
var data = {
nodes: nodes[name],
edges: edges[name]
};
var options = {};
network[name]= new vis.Network(container, data, options);
}
InitMap("cjdns");
InitMap("yggdrasil");
function UpdateNode(nodeID,name,edgeID,edgeLabel,map,NodeExist) {
NodeExist[nodeID]=1;
if (!nodeIDs[map][nodeID]) {
name=name.substr(name.length-4,4);
nodeIDs[map][nodeID]=nodes[map].add({id:nodeID, label:name});
}
if (!edgeIDs[map][edgeID]) {
edgeIDs[map][edgeID] = edges[map].add({id: edgeID, from: nodeID, to: 0});
console.debug(edgeID + "-" + nodeID);
}
edges[map].update({id: edgeID, label:edgeLabel });
}
function DeleteNodes(map,NodeExist) {
for (var key in nodeIDs[map]) {
if (NodeExist[key]!=1) {
nodes[map].remove(key);
nodeIDs[map][key]=undefined;
console.log("gatta delete " + key);
}
}
}

View File

@ -0,0 +1,54 @@
#!/usr/bin/env perl
use warnings;
use strict;
#
# Copyright (C) 2018 Hamish Coleman <hamish@zot.org>
#
# The simplest tool was the raw rpc tool
#
# The default options - should be set from commandline or rc file eventually
my $option = {
addr => "127.0.0.1",
port => "11234",
password => "NONE",
trace => 1,
};
BEGIN {
use File::Spec;
# allow the libs to be in the bin dir
unshift @INC, File::Spec->catdir((File::Spec->splitpath($0))[1],'lib');
print "Content-type: text/html\n\n";
}
use mini::Data;
use mini::Digest::SHA;
use Bencode_bork;
use Cjdns::RPC;
sub main() {
my $rpc = Cjdns::RPC->new(
$option->{addr},
$option->{port},
$option->{password},
) or die "cannot start rpc";
# $rpc->trace($option->{trace});
# print(mini::Data::Dumper($rpc->ping()));
mini::Data::Dumper($rpc->cookie());
mini::Data::Dumper($rpc->ping_auth());
#print(mini::Data::Dumper($rpc->Admin_availableFunctions()));
my $packet;
# $packet = $rpc->_build_query_auth('ETHInterface_listDevices');
# print(mini::Data::Dumper($rpc->_sync_call($packet)));
$packet = $rpc->_build_query_unauth('InterfaceController_peerStats');
print(mini::Data::Dumper($rpc->_sync_call($packet)));
}
unless (caller) {
# only run main if we are called as a CLI tool
main();
}

View File

@ -0,0 +1,15 @@
#!/usr/bin/env bash
echo -e "Content-type: text/html\n\n";
if [ -z "$(which yggdrasilctl)" ]; then
echo "{}"
exit 0
fi
res=$(yggdrasilctl --json getPeers 2>/dev/null)
if [[ $res == *"Fatal error"* ]]; then
echo "{}"
else
echo $res
fi

927
.install/nginx/sha512.js Normal file
View File

@ -0,0 +1,927 @@
/*
* [js-sha512]{@link https://github.com/emn178/js-sha512}
*
* @version 0.8.0
* @author Chen, Yi-Cyuan [emn178@gmail.com]
* @copyright Chen, Yi-Cyuan 2014-2018
* @license MIT
*/
/*jslint bitwise: true */
(function () {
'use strict';
var INPUT_ERROR = 'input is invalid type';
var FINALIZE_ERROR = 'finalize already called';
var WINDOW = typeof window === 'object';
var root = WINDOW ? window : {};
if (root.JS_SHA512_NO_WINDOW) {
WINDOW = false;
}
var WEB_WORKER = !WINDOW && typeof self === 'object';
var NODE_JS = !root.JS_SHA512_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;
if (NODE_JS) {
root = global;
} else if (WEB_WORKER) {
root = self;
}
var COMMON_JS = !root.JS_SHA512_NO_COMMON_JS && typeof module === 'object' && module.exports;
var AMD = typeof define === 'function' && define.amd;
var ARRAY_BUFFER = !root.JS_SHA512_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
var HEX_CHARS = '0123456789abcdef'.split('');
var EXTRA = [-2147483648, 8388608, 32768, 128];
var SHIFT = [24, 16, 8, 0];
var K = [
0x428A2F98, 0xD728AE22, 0x71374491, 0x23EF65CD,
0xB5C0FBCF, 0xEC4D3B2F, 0xE9B5DBA5, 0x8189DBBC,
0x3956C25B, 0xF348B538, 0x59F111F1, 0xB605D019,
0x923F82A4, 0xAF194F9B, 0xAB1C5ED5, 0xDA6D8118,
0xD807AA98, 0xA3030242, 0x12835B01, 0x45706FBE,
0x243185BE, 0x4EE4B28C, 0x550C7DC3, 0xD5FFB4E2,
0x72BE5D74, 0xF27B896F, 0x80DEB1FE, 0x3B1696B1,
0x9BDC06A7, 0x25C71235, 0xC19BF174, 0xCF692694,
0xE49B69C1, 0x9EF14AD2, 0xEFBE4786, 0x384F25E3,
0x0FC19DC6, 0x8B8CD5B5, 0x240CA1CC, 0x77AC9C65,
0x2DE92C6F, 0x592B0275, 0x4A7484AA, 0x6EA6E483,
0x5CB0A9DC, 0xBD41FBD4, 0x76F988DA, 0x831153B5,
0x983E5152, 0xEE66DFAB, 0xA831C66D, 0x2DB43210,
0xB00327C8, 0x98FB213F, 0xBF597FC7, 0xBEEF0EE4,
0xC6E00BF3, 0x3DA88FC2, 0xD5A79147, 0x930AA725,
0x06CA6351, 0xE003826F, 0x14292967, 0x0A0E6E70,
0x27B70A85, 0x46D22FFC, 0x2E1B2138, 0x5C26C926,
0x4D2C6DFC, 0x5AC42AED, 0x53380D13, 0x9D95B3DF,
0x650A7354, 0x8BAF63DE, 0x766A0ABB, 0x3C77B2A8,
0x81C2C92E, 0x47EDAEE6, 0x92722C85, 0x1482353B,
0xA2BFE8A1, 0x4CF10364, 0xA81A664B, 0xBC423001,
0xC24B8B70, 0xD0F89791, 0xC76C51A3, 0x0654BE30,
0xD192E819, 0xD6EF5218, 0xD6990624, 0x5565A910,
0xF40E3585, 0x5771202A, 0x106AA070, 0x32BBD1B8,
0x19A4C116, 0xB8D2D0C8, 0x1E376C08, 0x5141AB53,
0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8,
0x391C0CB3, 0xC5C95A63, 0x4ED8AA4A, 0xE3418ACB,
0x5B9CCA4F, 0x7763E373, 0x682E6FF3, 0xD6B2B8A3,
0x748F82EE, 0x5DEFB2FC, 0x78A5636F, 0x43172F60,
0x84C87814, 0xA1F0AB72, 0x8CC70208, 0x1A6439EC,
0x90BEFFFA, 0x23631E28, 0xA4506CEB, 0xDE82BDE9,
0xBEF9A3F7, 0xB2C67915, 0xC67178F2, 0xE372532B,
0xCA273ECE, 0xEA26619C, 0xD186B8C7, 0x21C0C207,
0xEADA7DD6, 0xCDE0EB1E, 0xF57D4F7F, 0xEE6ED178,
0x06F067AA, 0x72176FBA, 0x0A637DC5, 0xA2C898A6,
0x113F9804, 0xBEF90DAE, 0x1B710B35, 0x131C471B,
0x28DB77F5, 0x23047D84, 0x32CAAB7B, 0x40C72493,
0x3C9EBE0A, 0x15C9BEBC, 0x431D67C4, 0x9C100D4C,
0x4CC5D4BE, 0xCB3E42B6, 0x597F299C, 0xFC657E2A,
0x5FCB6FAB, 0x3AD6FAEC, 0x6C44198C, 0x4A475817
];
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
var blocks = [];
if (root.JS_SHA512_NO_NODE_JS || !Array.isArray) {
Array.isArray = function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
}
if (ARRAY_BUFFER && (root.JS_SHA512_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
ArrayBuffer.isView = function (obj) {
return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
};
}
var createOutputMethod = function (outputType, bits) {
return function (message) {
return new Sha512(bits, true).update(message)[outputType]();
};
};
var createMethod = function (bits) {
var method = createOutputMethod('hex', bits);
method.create = function () {
return new Sha512(bits);
};
method.update = function (message) {
return method.create().update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createOutputMethod(type, bits);
}
return method;
};
var createHmacOutputMethod = function (outputType, bits) {
return function (key, message) {
return new HmacSha512(key, bits, true).update(message)[outputType]();
};
};
var createHmacMethod = function (bits) {
var method = createHmacOutputMethod('hex', bits);
method.create = function (key) {
return new HmacSha512(key, bits);
};
method.update = function (key, message) {
return method.create(key).update(message);
};
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
var type = OUTPUT_TYPES[i];
method[type] = createHmacOutputMethod(type, bits);
}
return method;
};
function Sha512(bits, sharedMemory) {
if (sharedMemory) {
blocks[0] = blocks[1] = blocks[2] = blocks[3] = blocks[4] =
blocks[5] = blocks[6] = blocks[7] = blocks[8] =
blocks[9] = blocks[10] = blocks[11] = blocks[12] =
blocks[13] = blocks[14] = blocks[15] = blocks[16] =
blocks[17] = blocks[18] = blocks[19] = blocks[20] =
blocks[21] = blocks[22] = blocks[23] = blocks[24] =
blocks[25] = blocks[26] = blocks[27] = blocks[28] =
blocks[29] = blocks[30] = blocks[31] = blocks[32] = 0;
this.blocks = blocks;
} else {
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
}
if (bits == 384) {
this.h0h = 0xCBBB9D5D;
this.h0l = 0xC1059ED8;
this.h1h = 0x629A292A;
this.h1l = 0x367CD507;
this.h2h = 0x9159015A;
this.h2l = 0x3070DD17;
this.h3h = 0x152FECD8;
this.h3l = 0xF70E5939;
this.h4h = 0x67332667;
this.h4l = 0xFFC00B31;
this.h5h = 0x8EB44A87;
this.h5l = 0x68581511;
this.h6h = 0xDB0C2E0D;
this.h6l = 0x64F98FA7;
this.h7h = 0x47B5481D;
this.h7l = 0xBEFA4FA4;
} else if (bits == 256) {
this.h0h = 0x22312194;
this.h0l = 0xFC2BF72C;
this.h1h = 0x9F555FA3;
this.h1l = 0xC84C64C2;
this.h2h = 0x2393B86B;
this.h2l = 0x6F53B151;
this.h3h = 0x96387719;
this.h3l = 0x5940EABD;
this.h4h = 0x96283EE2;
this.h4l = 0xA88EFFE3;
this.h5h = 0xBE5E1E25;
this.h5l = 0x53863992;
this.h6h = 0x2B0199FC;
this.h6l = 0x2C85B8AA;
this.h7h = 0x0EB72DDC;
this.h7l = 0x81C52CA2;
} else if (bits == 224) {
this.h0h = 0x8C3D37C8;
this.h0l = 0x19544DA2;
this.h1h = 0x73E19966;
this.h1l = 0x89DCD4D6;
this.h2h = 0x1DFAB7AE;
this.h2l = 0x32FF9C82;
this.h3h = 0x679DD514;
this.h3l = 0x582F9FCF;
this.h4h = 0x0F6D2B69;
this.h4l = 0x7BD44DA8;
this.h5h = 0x77E36F73;
this.h5l = 0x04C48942;
this.h6h = 0x3F9D85A8;
this.h6l = 0x6A1D36C8;
this.h7h = 0x1112E6AD;
this.h7l = 0x91D692A1;
} else { // 512
this.h0h = 0x6A09E667;
this.h0l = 0xF3BCC908;
this.h1h = 0xBB67AE85;
this.h1l = 0x84CAA73B;
this.h2h = 0x3C6EF372;
this.h2l = 0xFE94F82B;
this.h3h = 0xA54FF53A;
this.h3l = 0x5F1D36F1;
this.h4h = 0x510E527F;
this.h4l = 0xADE682D1;
this.h5h = 0x9B05688C;
this.h5l = 0x2B3E6C1F;
this.h6h = 0x1F83D9AB;
this.h6l = 0xFB41BD6B;
this.h7h = 0x5BE0CD19;
this.h7l = 0x137E2179;
}
this.bits = bits;
this.block = this.start = this.bytes = this.hBytes = 0;
this.finalized = this.hashed = false;
}
Sha512.prototype.update = function (message) {
if (this.finalized) {
throw new Error(FINALIZE_ERROR);
}
var notString, type = typeof message;
if (type !== 'string') {
if (type === 'object') {
if (message === null) {
throw new Error(INPUT_ERROR);
} else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
message = new Uint8Array(message);
} else if (!Array.isArray(message)) {
if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
throw new Error(INPUT_ERROR);
}
}
} else {
throw new Error(INPUT_ERROR);
}
notString = true;
}
var code, index = 0, i, length = message.length, blocks = this.blocks;
while (index < length) {
if (this.hashed) {
this.hashed = false;
blocks[0] = this.block;
blocks[1] = blocks[2] = blocks[3] = blocks[4] =
blocks[5] = blocks[6] = blocks[7] = blocks[8] =
blocks[9] = blocks[10] = blocks[11] = blocks[12] =
blocks[13] = blocks[14] = blocks[15] = blocks[16] =
blocks[17] = blocks[18] = blocks[19] = blocks[20] =
blocks[21] = blocks[22] = blocks[23] = blocks[24] =
blocks[25] = blocks[26] = blocks[27] = blocks[28] =
blocks[29] = blocks[30] = blocks[31] = blocks[32] = 0;
}
if(notString) {
for (i = this.start; index < length && i < 128; ++index) {
blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];
}
} else {
for (i = this.start; index < length && i < 128; ++index) {
code = message.charCodeAt(index);
if (code < 0x80) {
blocks[i >> 2] |= code << SHIFT[i++ & 3];
} else if (code < 0x800) {
blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else if (code < 0xd800 || code >= 0xe000) {
blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];
blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
}
}
}
this.lastByteIndex = i;
this.bytes += i - this.start;
if (i >= 128) {
this.block = blocks[32];
this.start = i - 128;
this.hash();
this.hashed = true;
} else {
this.start = i;
}
}
if (this.bytes > 4294967295) {
this.hBytes += this.bytes / 4294967296 << 0;
this.bytes = this.bytes % 4294967296;
}
return this;
};
Sha512.prototype.finalize = function () {
if (this.finalized) {
return;
}
this.finalized = true;
var blocks = this.blocks, i = this.lastByteIndex;
blocks[32] = this.block;
blocks[i >> 2] |= EXTRA[i & 3];
this.block = blocks[32];
if (i >= 112) {
if (!this.hashed) {
this.hash();
}
blocks[0] = this.block;
blocks[1] = blocks[2] = blocks[3] = blocks[4] =
blocks[5] = blocks[6] = blocks[7] = blocks[8] =
blocks[9] = blocks[10] = blocks[11] = blocks[12] =
blocks[13] = blocks[14] = blocks[15] = blocks[16] =
blocks[17] = blocks[18] = blocks[19] = blocks[20] =
blocks[21] = blocks[22] = blocks[23] = blocks[24] =
blocks[25] = blocks[26] = blocks[27] = blocks[28] =
blocks[29] = blocks[30] = blocks[31] = blocks[32] = 0;
}
blocks[30] = this.hBytes << 3 | this.bytes >>> 29;
blocks[31] = this.bytes << 3;
this.hash();
};
Sha512.prototype.hash = function () {
var h0h = this.h0h, h0l = this.h0l, h1h = this.h1h, h1l = this.h1l,
h2h = this.h2h, h2l = this.h2l, h3h = this.h3h, h3l = this.h3l,
h4h = this.h4h, h4l = this.h4l, h5h = this.h5h, h5l = this.h5l,
h6h = this.h6h, h6l = this.h6l, h7h = this.h7h, h7l = this.h7l,
blocks = this.blocks, j, s0h, s0l, s1h, s1l, c1, c2, c3, c4,
abh, abl, dah, dal, cdh, cdl, bch, bcl,
majh, majl, t1h, t1l, t2h, t2l, chh, chl;
for (j = 32; j < 160; j += 2) {
t1h = blocks[j - 30];
t1l = blocks[j - 29];
s0h = ((t1h >>> 1) | (t1l << 31)) ^ ((t1h >>> 8) | (t1l << 24)) ^ (t1h >>> 7);
s0l = ((t1l >>> 1) | (t1h << 31)) ^ ((t1l >>> 8) | (t1h << 24)) ^ ((t1l >>> 7) | t1h << 25);
t1h = blocks[j - 4];
t1l = blocks[j - 3];
s1h = ((t1h >>> 19) | (t1l << 13)) ^ ((t1l >>> 29) | (t1h << 3)) ^ (t1h >>> 6);
s1l = ((t1l >>> 19) | (t1h << 13)) ^ ((t1h >>> 29) | (t1l << 3)) ^ ((t1l >>> 6) | t1h << 26);
t1h = blocks[j - 32];
t1l = blocks[j - 31];
t2h = blocks[j - 14];
t2l = blocks[j - 13];
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF) + (s0l & 0xFFFF) + (s1l & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (s0l >>> 16) + (s1l >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (s0h & 0xFFFF) + (s1h & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (s0h >>> 16) + (s1h >>> 16) + (c3 >>> 16);
blocks[j] = (c4 << 16) | (c3 & 0xFFFF);
blocks[j + 1] = (c2 << 16) | (c1 & 0xFFFF);
}
var ah = h0h, al = h0l, bh = h1h, bl = h1l, ch = h2h, cl = h2l, dh = h3h, dl = h3l, eh = h4h, el = h4l, fh = h5h, fl = h5l, gh = h6h, gl = h6l, hh = h7h, hl = h7l;
bch = bh & ch;
bcl = bl & cl;
for (j = 0; j < 160; j += 8) {
s0h = ((ah >>> 28) | (al << 4)) ^ ((al >>> 2) | (ah << 30)) ^ ((al >>> 7) | (ah << 25));
s0l = ((al >>> 28) | (ah << 4)) ^ ((ah >>> 2) | (al << 30)) ^ ((ah >>> 7) | (al << 25));
s1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((el >>> 9) | (eh << 23));
s1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((eh >>> 9) | (el << 23));
abh = ah & bh;
abl = al & bl;
majh = abh ^ (ah & ch) ^ bch;
majl = abl ^ (al & cl) ^ bcl;
chh = (eh & fh) ^ (~eh & gh);
chl = (el & fl) ^ (~el & gl);
t1h = blocks[j];
t1l = blocks[j + 1];
t2h = K[j];
t2l = K[j + 1];
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF) + (chl & 0xFFFF) + (s1l & 0xFFFF) + (hl & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (hl >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (chh & 0xFFFF) + (s1h & 0xFFFF) + (hh & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (hh >>> 16) + (c3 >>> 16);
t1h = (c4 << 16) | (c3 & 0xFFFF);
t1l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (majl & 0xFFFF) + (s0l & 0xFFFF);
c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16);
c3 = (majh & 0xFFFF) + (s0h & 0xFFFF) + (c2 >>> 16);
c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16);
t2h = (c4 << 16) | (c3 & 0xFFFF);
t2l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (dl & 0xFFFF) + (t1l & 0xFFFF);
c2 = (dl >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (dh & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (dh >>> 16) + (t1h >>> 16) + (c3 >>> 16);
hh = (c4 << 16) | (c3 & 0xFFFF);
hl = (c2 << 16) | (c1 & 0xFFFF);
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16);
dh = (c4 << 16) | (c3 & 0xFFFF);
dl = (c2 << 16) | (c1 & 0xFFFF);
s0h = ((dh >>> 28) | (dl << 4)) ^ ((dl >>> 2) | (dh << 30)) ^ ((dl >>> 7) | (dh << 25));
s0l = ((dl >>> 28) | (dh << 4)) ^ ((dh >>> 2) | (dl << 30)) ^ ((dh >>> 7) | (dl << 25));
s1h = ((hh >>> 14) | (hl << 18)) ^ ((hh >>> 18) | (hl << 14)) ^ ((hl >>> 9) | (hh << 23));
s1l = ((hl >>> 14) | (hh << 18)) ^ ((hl >>> 18) | (hh << 14)) ^ ((hh >>> 9) | (hl << 23));
dah = dh & ah;
dal = dl & al;
majh = dah ^ (dh & bh) ^ abh;
majl = dal ^ (dl & bl) ^ abl;
chh = (hh & eh) ^ (~hh & fh);
chl = (hl & el) ^ (~hl & fl);
t1h = blocks[j + 2];
t1l = blocks[j + 3];
t2h = K[j + 2];
t2l = K[j + 3];
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF) + (chl & 0xFFFF) + (s1l & 0xFFFF) + (gl & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (gl >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (chh & 0xFFFF) + (s1h & 0xFFFF) + (gh & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (gh >>> 16) + (c3 >>> 16);
t1h = (c4 << 16) | (c3 & 0xFFFF);
t1l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (majl & 0xFFFF) + (s0l & 0xFFFF);
c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16);
c3 = (majh & 0xFFFF) + (s0h & 0xFFFF) + (c2 >>> 16);
c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16);
t2h = (c4 << 16) | (c3 & 0xFFFF);
t2l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (cl & 0xFFFF) + (t1l & 0xFFFF);
c2 = (cl >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (ch & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (ch >>> 16) + (t1h >>> 16) + (c3 >>> 16);
gh = (c4 << 16) | (c3 & 0xFFFF);
gl = (c2 << 16) | (c1 & 0xFFFF);
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16);
ch = (c4 << 16) | (c3 & 0xFFFF);
cl = (c2 << 16) | (c1 & 0xFFFF);
s0h = ((ch >>> 28) | (cl << 4)) ^ ((cl >>> 2) | (ch << 30)) ^ ((cl >>> 7) | (ch << 25));
s0l = ((cl >>> 28) | (ch << 4)) ^ ((ch >>> 2) | (cl << 30)) ^ ((ch >>> 7) | (cl << 25));
s1h = ((gh >>> 14) | (gl << 18)) ^ ((gh >>> 18) | (gl << 14)) ^ ((gl >>> 9) | (gh << 23));
s1l = ((gl >>> 14) | (gh << 18)) ^ ((gl >>> 18) | (gh << 14)) ^ ((gh >>> 9) | (gl << 23));
cdh = ch & dh;
cdl = cl & dl;
majh = cdh ^ (ch & ah) ^ dah;
majl = cdl ^ (cl & al) ^ dal;
chh = (gh & hh) ^ (~gh & eh);
chl = (gl & hl) ^ (~gl & el);
t1h = blocks[j + 4];
t1l = blocks[j + 5];
t2h = K[j + 4];
t2l = K[j + 5];
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF) + (chl & 0xFFFF) + (s1l & 0xFFFF) + (fl & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (fl >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (chh & 0xFFFF) + (s1h & 0xFFFF) + (fh & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (fh >>> 16) + (c3 >>> 16);
t1h = (c4 << 16) | (c3 & 0xFFFF);
t1l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (majl & 0xFFFF) + (s0l & 0xFFFF);
c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16);
c3 = (majh & 0xFFFF) + (s0h & 0xFFFF) + (c2 >>> 16);
c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16);
t2h = (c4 << 16) | (c3 & 0xFFFF);
t2l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (bl & 0xFFFF) + (t1l & 0xFFFF);
c2 = (bl >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (bh & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (bh >>> 16) + (t1h >>> 16) + (c3 >>> 16);
fh = (c4 << 16) | (c3 & 0xFFFF);
fl = (c2 << 16) | (c1 & 0xFFFF);
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16);
bh = (c4 << 16) | (c3 & 0xFFFF);
bl = (c2 << 16) | (c1 & 0xFFFF);
s0h = ((bh >>> 28) | (bl << 4)) ^ ((bl >>> 2) | (bh << 30)) ^ ((bl >>> 7) | (bh << 25));
s0l = ((bl >>> 28) | (bh << 4)) ^ ((bh >>> 2) | (bl << 30)) ^ ((bh >>> 7) | (bl << 25));
s1h = ((fh >>> 14) | (fl << 18)) ^ ((fh >>> 18) | (fl << 14)) ^ ((fl >>> 9) | (fh << 23));
s1l = ((fl >>> 14) | (fh << 18)) ^ ((fl >>> 18) | (fh << 14)) ^ ((fh >>> 9) | (fl << 23));
bch = bh & ch;
bcl = bl & cl;
majh = bch ^ (bh & dh) ^ cdh;
majl = bcl ^ (bl & dl) ^ cdl;
chh = (fh & gh) ^ (~fh & hh);
chl = (fl & gl) ^ (~fl & hl);
t1h = blocks[j + 6];
t1l = blocks[j + 7];
t2h = K[j + 6];
t2l = K[j + 7];
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF) + (chl & 0xFFFF) + (s1l & 0xFFFF) + (el & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (chl >>> 16) + (s1l >>> 16) + (el >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (chh & 0xFFFF) + (s1h & 0xFFFF) + (eh & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (chh >>> 16) + (s1h >>> 16) + (eh >>> 16) + (c3 >>> 16);
t1h = (c4 << 16) | (c3 & 0xFFFF);
t1l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (majl & 0xFFFF) + (s0l & 0xFFFF);
c2 = (majl >>> 16) + (s0l >>> 16) + (c1 >>> 16);
c3 = (majh & 0xFFFF) + (s0h & 0xFFFF) + (c2 >>> 16);
c4 = (majh >>> 16) + (s0h >>> 16) + (c3 >>> 16);
t2h = (c4 << 16) | (c3 & 0xFFFF);
t2l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (al & 0xFFFF) + (t1l & 0xFFFF);
c2 = (al >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (ah & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (ah >>> 16) + (t1h >>> 16) + (c3 >>> 16);
eh = (c4 << 16) | (c3 & 0xFFFF);
el = (c2 << 16) | (c1 & 0xFFFF);
c1 = (t2l & 0xFFFF) + (t1l & 0xFFFF);
c2 = (t2l >>> 16) + (t1l >>> 16) + (c1 >>> 16);
c3 = (t2h & 0xFFFF) + (t1h & 0xFFFF) + (c2 >>> 16);
c4 = (t2h >>> 16) + (t1h >>> 16) + (c3 >>> 16);
ah = (c4 << 16) | (c3 & 0xFFFF);
al = (c2 << 16) | (c1 & 0xFFFF);
}
c1 = (h0l & 0xFFFF) + (al & 0xFFFF);
c2 = (h0l >>> 16) + (al >>> 16) + (c1 >>> 16);
c3 = (h0h & 0xFFFF) + (ah & 0xFFFF) + (c2 >>> 16);
c4 = (h0h >>> 16) + (ah >>> 16) + (c3 >>> 16);
this.h0h = (c4 << 16) | (c3 & 0xFFFF);
this.h0l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (h1l & 0xFFFF) + (bl & 0xFFFF);
c2 = (h1l >>> 16) + (bl >>> 16) + (c1 >>> 16);
c3 = (h1h & 0xFFFF) + (bh & 0xFFFF) + (c2 >>> 16);
c4 = (h1h >>> 16) + (bh >>> 16) + (c3 >>> 16);
this.h1h = (c4 << 16) | (c3 & 0xFFFF);
this.h1l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (h2l & 0xFFFF) + (cl & 0xFFFF);
c2 = (h2l >>> 16) + (cl >>> 16) + (c1 >>> 16);
c3 = (h2h & 0xFFFF) + (ch & 0xFFFF) + (c2 >>> 16);
c4 = (h2h >>> 16) + (ch >>> 16) + (c3 >>> 16);
this.h2h = (c4 << 16) | (c3 & 0xFFFF);
this.h2l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (h3l & 0xFFFF) + (dl & 0xFFFF);
c2 = (h3l >>> 16) + (dl >>> 16) + (c1 >>> 16);
c3 = (h3h & 0xFFFF) + (dh & 0xFFFF) + (c2 >>> 16);
c4 = (h3h >>> 16) + (dh >>> 16) + (c3 >>> 16);
this.h3h = (c4 << 16) | (c3 & 0xFFFF);
this.h3l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (h4l & 0xFFFF) + (el & 0xFFFF);
c2 = (h4l >>> 16) + (el >>> 16) + (c1 >>> 16);
c3 = (h4h & 0xFFFF) + (eh & 0xFFFF) + (c2 >>> 16);
c4 = (h4h >>> 16) + (eh >>> 16) + (c3 >>> 16);
this.h4h = (c4 << 16) | (c3 & 0xFFFF);
this.h4l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (h5l & 0xFFFF) + (fl & 0xFFFF);
c2 = (h5l >>> 16) + (fl >>> 16) + (c1 >>> 16);
c3 = (h5h & 0xFFFF) + (fh & 0xFFFF) + (c2 >>> 16);
c4 = (h5h >>> 16) + (fh >>> 16) + (c3 >>> 16);
this.h5h = (c4 << 16) | (c3 & 0xFFFF);
this.h5l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (h6l & 0xFFFF) + (gl & 0xFFFF);
c2 = (h6l >>> 16) + (gl >>> 16) + (c1 >>> 16);
c3 = (h6h & 0xFFFF) + (gh & 0xFFFF) + (c2 >>> 16);
c4 = (h6h >>> 16) + (gh >>> 16) + (c3 >>> 16);
this.h6h = (c4 << 16) | (c3 & 0xFFFF);
this.h6l = (c2 << 16) | (c1 & 0xFFFF);
c1 = (h7l & 0xFFFF) + (hl & 0xFFFF);
c2 = (h7l >>> 16) + (hl >>> 16) + (c1 >>> 16);
c3 = (h7h & 0xFFFF) + (hh & 0xFFFF) + (c2 >>> 16);
c4 = (h7h >>> 16) + (hh >>> 16) + (c3 >>> 16);
this.h7h = (c4 << 16) | (c3 & 0xFFFF);
this.h7l = (c2 << 16) | (c1 & 0xFFFF);
};
Sha512.prototype.hex = function () {
this.finalize();
var h0h = this.h0h, h0l = this.h0l, h1h = this.h1h, h1l = this.h1l,
h2h = this.h2h, h2l = this.h2l, h3h = this.h3h, h3l = this.h3l,
h4h = this.h4h, h4l = this.h4l, h5h = this.h5h, h5l = this.h5l,
h6h = this.h6h, h6l = this.h6l, h7h = this.h7h, h7l = this.h7l,
bits = this.bits;
var hex = HEX_CHARS[(h0h >> 28) & 0x0F] + HEX_CHARS[(h0h >> 24) & 0x0F] +
HEX_CHARS[(h0h >> 20) & 0x0F] + HEX_CHARS[(h0h >> 16) & 0x0F] +
HEX_CHARS[(h0h >> 12) & 0x0F] + HEX_CHARS[(h0h >> 8) & 0x0F] +
HEX_CHARS[(h0h >> 4) & 0x0F] + HEX_CHARS[h0h & 0x0F] +
HEX_CHARS[(h0l >> 28) & 0x0F] + HEX_CHARS[(h0l >> 24) & 0x0F] +
HEX_CHARS[(h0l >> 20) & 0x0F] + HEX_CHARS[(h0l >> 16) & 0x0F] +
HEX_CHARS[(h0l >> 12) & 0x0F] + HEX_CHARS[(h0l >> 8) & 0x0F] +
HEX_CHARS[(h0l >> 4) & 0x0F] + HEX_CHARS[h0l & 0x0F] +
HEX_CHARS[(h1h >> 28) & 0x0F] + HEX_CHARS[(h1h >> 24) & 0x0F] +
HEX_CHARS[(h1h >> 20) & 0x0F] + HEX_CHARS[(h1h >> 16) & 0x0F] +
HEX_CHARS[(h1h >> 12) & 0x0F] + HEX_CHARS[(h1h >> 8) & 0x0F] +
HEX_CHARS[(h1h >> 4) & 0x0F] + HEX_CHARS[h1h & 0x0F] +
HEX_CHARS[(h1l >> 28) & 0x0F] + HEX_CHARS[(h1l >> 24) & 0x0F] +
HEX_CHARS[(h1l >> 20) & 0x0F] + HEX_CHARS[(h1l >> 16) & 0x0F] +
HEX_CHARS[(h1l >> 12) & 0x0F] + HEX_CHARS[(h1l >> 8) & 0x0F] +
HEX_CHARS[(h1l >> 4) & 0x0F] + HEX_CHARS[h1l & 0x0F] +
HEX_CHARS[(h2h >> 28) & 0x0F] + HEX_CHARS[(h2h >> 24) & 0x0F] +
HEX_CHARS[(h2h >> 20) & 0x0F] + HEX_CHARS[(h2h >> 16) & 0x0F] +
HEX_CHARS[(h2h >> 12) & 0x0F] + HEX_CHARS[(h2h >> 8) & 0x0F] +
HEX_CHARS[(h2h >> 4) & 0x0F] + HEX_CHARS[h2h & 0x0F] +
HEX_CHARS[(h2l >> 28) & 0x0F] + HEX_CHARS[(h2l >> 24) & 0x0F] +
HEX_CHARS[(h2l >> 20) & 0x0F] + HEX_CHARS[(h2l >> 16) & 0x0F] +
HEX_CHARS[(h2l >> 12) & 0x0F] + HEX_CHARS[(h2l >> 8) & 0x0F] +
HEX_CHARS[(h2l >> 4) & 0x0F] + HEX_CHARS[h2l & 0x0F] +
HEX_CHARS[(h3h >> 28) & 0x0F] + HEX_CHARS[(h3h >> 24) & 0x0F] +
HEX_CHARS[(h3h >> 20) & 0x0F] + HEX_CHARS[(h3h >> 16) & 0x0F] +
HEX_CHARS[(h3h >> 12) & 0x0F] + HEX_CHARS[(h3h >> 8) & 0x0F] +
HEX_CHARS[(h3h >> 4) & 0x0F] + HEX_CHARS[h3h & 0x0F];
if (bits >= 256) {
hex += HEX_CHARS[(h3l >> 28) & 0x0F] + HEX_CHARS[(h3l >> 24) & 0x0F] +
HEX_CHARS[(h3l >> 20) & 0x0F] + HEX_CHARS[(h3l >> 16) & 0x0F] +
HEX_CHARS[(h3l >> 12) & 0x0F] + HEX_CHARS[(h3l >> 8) & 0x0F] +
HEX_CHARS[(h3l >> 4) & 0x0F] + HEX_CHARS[h3l & 0x0F];
}
if (bits >= 384) {
hex += HEX_CHARS[(h4h >> 28) & 0x0F] + HEX_CHARS[(h4h >> 24) & 0x0F] +
HEX_CHARS[(h4h >> 20) & 0x0F] + HEX_CHARS[(h4h >> 16) & 0x0F] +
HEX_CHARS[(h4h >> 12) & 0x0F] + HEX_CHARS[(h4h >> 8) & 0x0F] +
HEX_CHARS[(h4h >> 4) & 0x0F] + HEX_CHARS[h4h & 0x0F] +
HEX_CHARS[(h4l >> 28) & 0x0F] + HEX_CHARS[(h4l >> 24) & 0x0F] +
HEX_CHARS[(h4l >> 20) & 0x0F] + HEX_CHARS[(h4l >> 16) & 0x0F] +
HEX_CHARS[(h4l >> 12) & 0x0F] + HEX_CHARS[(h4l >> 8) & 0x0F] +
HEX_CHARS[(h4l >> 4) & 0x0F] + HEX_CHARS[h4l & 0x0F] +
HEX_CHARS[(h5h >> 28) & 0x0F] + HEX_CHARS[(h5h >> 24) & 0x0F] +
HEX_CHARS[(h5h >> 20) & 0x0F] + HEX_CHARS[(h5h >> 16) & 0x0F] +
HEX_CHARS[(h5h >> 12) & 0x0F] + HEX_CHARS[(h5h >> 8) & 0x0F] +
HEX_CHARS[(h5h >> 4) & 0x0F] + HEX_CHARS[h5h & 0x0F] +
HEX_CHARS[(h5l >> 28) & 0x0F] + HEX_CHARS[(h5l >> 24) & 0x0F] +
HEX_CHARS[(h5l >> 20) & 0x0F] + HEX_CHARS[(h5l >> 16) & 0x0F] +
HEX_CHARS[(h5l >> 12) & 0x0F] + HEX_CHARS[(h5l >> 8) & 0x0F] +
HEX_CHARS[(h5l >> 4) & 0x0F] + HEX_CHARS[h5l & 0x0F];
}
if (bits == 512) {
hex += HEX_CHARS[(h6h >> 28) & 0x0F] + HEX_CHARS[(h6h >> 24) & 0x0F] +
HEX_CHARS[(h6h >> 20) & 0x0F] + HEX_CHARS[(h6h >> 16) & 0x0F] +
HEX_CHARS[(h6h >> 12) & 0x0F] + HEX_CHARS[(h6h >> 8) & 0x0F] +
HEX_CHARS[(h6h >> 4) & 0x0F] + HEX_CHARS[h6h & 0x0F] +
HEX_CHARS[(h6l >> 28) & 0x0F] + HEX_CHARS[(h6l >> 24) & 0x0F] +
HEX_CHARS[(h6l >> 20) & 0x0F] + HEX_CHARS[(h6l >> 16) & 0x0F] +
HEX_CHARS[(h6l >> 12) & 0x0F] + HEX_CHARS[(h6l >> 8) & 0x0F] +
HEX_CHARS[(h6l >> 4) & 0x0F] + HEX_CHARS[h6l & 0x0F] +
HEX_CHARS[(h7h >> 28) & 0x0F] + HEX_CHARS[(h7h >> 24) & 0x0F] +
HEX_CHARS[(h7h >> 20) & 0x0F] + HEX_CHARS[(h7h >> 16) & 0x0F] +
HEX_CHARS[(h7h >> 12) & 0x0F] + HEX_CHARS[(h7h >> 8) & 0x0F] +
HEX_CHARS[(h7h >> 4) & 0x0F] + HEX_CHARS[h7h & 0x0F] +
HEX_CHARS[(h7l >> 28) & 0x0F] + HEX_CHARS[(h7l >> 24) & 0x0F] +
HEX_CHARS[(h7l >> 20) & 0x0F] + HEX_CHARS[(h7l >> 16) & 0x0F] +
HEX_CHARS[(h7l >> 12) & 0x0F] + HEX_CHARS[(h7l >> 8) & 0x0F] +
HEX_CHARS[(h7l >> 4) & 0x0F] + HEX_CHARS[h7l & 0x0F];
}
return hex;
};
Sha512.prototype.toString = Sha512.prototype.hex;
Sha512.prototype.digest = function () {
this.finalize();
var h0h = this.h0h, h0l = this.h0l, h1h = this.h1h, h1l = this.h1l,
h2h = this.h2h, h2l = this.h2l, h3h = this.h3h, h3l = this.h3l,
h4h = this.h4h, h4l = this.h4l, h5h = this.h5h, h5l = this.h5l,
h6h = this.h6h, h6l = this.h6l, h7h = this.h7h, h7l = this.h7l,
bits = this.bits;
var arr = [
(h0h >> 24) & 0xFF, (h0h >> 16) & 0xFF, (h0h >> 8) & 0xFF, h0h & 0xFF,
(h0l >> 24) & 0xFF, (h0l >> 16) & 0xFF, (h0l >> 8) & 0xFF, h0l & 0xFF,
(h1h >> 24) & 0xFF, (h1h >> 16) & 0xFF, (h1h >> 8) & 0xFF, h1h & 0xFF,
(h1l >> 24) & 0xFF, (h1l >> 16) & 0xFF, (h1l >> 8) & 0xFF, h1l & 0xFF,
(h2h >> 24) & 0xFF, (h2h >> 16) & 0xFF, (h2h >> 8) & 0xFF, h2h & 0xFF,
(h2l >> 24) & 0xFF, (h2l >> 16) & 0xFF, (h2l >> 8) & 0xFF, h2l & 0xFF,
(h3h >> 24) & 0xFF, (h3h >> 16) & 0xFF, (h3h >> 8) & 0xFF, h3h & 0xFF
];
if (bits >= 256) {
arr.push((h3l >> 24) & 0xFF, (h3l >> 16) & 0xFF, (h3l >> 8) & 0xFF, h3l & 0xFF);
}
if (bits >= 384) {
arr.push(
(h4h >> 24) & 0xFF, (h4h >> 16) & 0xFF, (h4h >> 8) & 0xFF, h4h & 0xFF,
(h4l >> 24) & 0xFF, (h4l >> 16) & 0xFF, (h4l >> 8) & 0xFF, h4l & 0xFF,
(h5h >> 24) & 0xFF, (h5h >> 16) & 0xFF, (h5h >> 8) & 0xFF, h5h & 0xFF,
(h5l >> 24) & 0xFF, (h5l >> 16) & 0xFF, (h5l >> 8) & 0xFF, h5l & 0xFF
);
}
if (bits == 512) {
arr.push(
(h6h >> 24) & 0xFF, (h6h >> 16) & 0xFF, (h6h >> 8) & 0xFF, h6h & 0xFF,
(h6l >> 24) & 0xFF, (h6l >> 16) & 0xFF, (h6l >> 8) & 0xFF, h6l & 0xFF,
(h7h >> 24) & 0xFF, (h7h >> 16) & 0xFF, (h7h >> 8) & 0xFF, h7h & 0xFF,
(h7l >> 24) & 0xFF, (h7l >> 16) & 0xFF, (h7l >> 8) & 0xFF, h7l & 0xFF
);
}
return arr;
};
Sha512.prototype.array = Sha512.prototype.digest;
Sha512.prototype.arrayBuffer = function () {
this.finalize();
var bits = this.bits;
var buffer = new ArrayBuffer(bits / 8);
var dataView = new DataView(buffer);
dataView.setUint32(0, this.h0h);
dataView.setUint32(4, this.h0l);
dataView.setUint32(8, this.h1h);
dataView.setUint32(12, this.h1l);
dataView.setUint32(16, this.h2h);
dataView.setUint32(20, this.h2l);
dataView.setUint32(24, this.h3h);
if (bits >= 256) {
dataView.setUint32(28, this.h3l);
}
if (bits >= 384) {
dataView.setUint32(32, this.h4h);
dataView.setUint32(36, this.h4l);
dataView.setUint32(40, this.h5h);
dataView.setUint32(44, this.h5l);
}
if (bits == 512) {
dataView.setUint32(48, this.h6h);
dataView.setUint32(52, this.h6l);
dataView.setUint32(56, this.h7h);
dataView.setUint32(60, this.h7l);
}
return buffer;
};
Sha512.prototype.clone = function () {
var hash = new Sha512(this.bits, false);
this.copyTo(hash);
return hash;
};
Sha512.prototype.copyTo = function (hash) {
var i = 0, attrs = [
'h0h', 'h0l', 'h1h', 'h1l', 'h2h', 'h2l', 'h3h', 'h3l', 'h4h', 'h4l', 'h5h', 'h5l', 'h6h', 'h6l', 'h7h', 'h7l',
'start', 'bytes', 'hBytes', 'finalized', 'hashed', 'lastByteIndex'
];
for (i = 0; i < attrs.length; ++i) {
hash[attrs[i]] = this[attrs[i]];
}
for (i = 0; i < this.blocks.length; ++i) {
hash.blocks[i] = this.blocks[i];
}
};
function HmacSha512(key, bits, sharedMemory) {
var notString, type = typeof key;
if (type !== 'string') {
if (type === 'object') {
if (key === null) {
throw new Error(INPUT_ERROR);
} else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) {
key = new Uint8Array(key);
} else if (!Array.isArray(key)) {
if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) {
throw new Error(INPUT_ERROR);
}
}
} else {
throw new Error(INPUT_ERROR);
}
notString = true;
}
var length = key.length;
if (!notString) {
var bytes = [], length = key.length, index = 0, code;
for (var i = 0; i < length; ++i) {
code = key.charCodeAt(i);
if (code < 0x80) {
bytes[index++] = code;
} else if (code < 0x800) {
bytes[index++] = (0xc0 | (code >> 6));
bytes[index++] = (0x80 | (code & 0x3f));
} else if (code < 0xd800 || code >= 0xe000) {
bytes[index++] = (0xe0 | (code >> 12));
bytes[index++] = (0x80 | ((code >> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f));
} else {
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
bytes[index++] = (0xf0 | (code >> 18));
bytes[index++] = (0x80 | ((code >> 12) & 0x3f));
bytes[index++] = (0x80 | ((code >> 6) & 0x3f));
bytes[index++] = (0x80 | (code & 0x3f));
}
}
key = bytes;
}
if (key.length > 128) {
key = (new Sha512(bits, true)).update(key).array();
}
var oKeyPad = [], iKeyPad = [];
for (var i = 0; i < 128; ++i) {
var b = key[i] || 0;
oKeyPad[i] = 0x5c ^ b;
iKeyPad[i] = 0x36 ^ b;
}
Sha512.call(this, bits, sharedMemory);
this.update(iKeyPad);
this.oKeyPad = oKeyPad;
this.inner = true;
this.sharedMemory = sharedMemory;
}
HmacSha512.prototype = new Sha512();
HmacSha512.prototype.finalize = function () {
Sha512.prototype.finalize.call(this);
if (this.inner) {
this.inner = false;
var innerHash = this.array();
Sha512.call(this, this.bits, this.sharedMemory);
this.update(this.oKeyPad);
this.update(innerHash);
Sha512.prototype.finalize.call(this);
}
};
HmacSha512.prototype.clone = function () {
var hash = new HmacSha512([], this.bits, false);
this.copyTo(hash);
hash.inner = this.inner;
for (var i = 0; i < this.oKeyPad.length; ++i) {
hash.oKeyPad[i] = this.oKeyPad[i];
}
return hash;
};
var exports = createMethod(512);
exports.sha512 = exports;
exports.sha384 = createMethod(384);
exports.sha512_256 = createMethod(256);
exports.sha512_224 = createMethod(224);
exports.sha512.hmac = createHmacMethod(512);
exports.sha384.hmac = createHmacMethod(384);
exports.sha512_256.hmac = createHmacMethod(256);
exports.sha512_224.hmac = createHmacMethod(224);
if (COMMON_JS) {
module.exports = exports;
} else {
root.sha512 = exports.sha512;
root.sha384 = exports.sha384;
root.sha512_256 = exports.sha512_256;
root.sha512_224 = exports.sha512_224;
if (AMD) {
define(function () {
return exports;
});
}
}
})();

9
.install/nginx/uninstall Normal file
View File

@ -0,0 +1,9 @@
#!/bin/sh
sudo rm -rf /etc/nginx/sites-available/main.conf || true
sudo rm -rf /etc/nginx/sites-enabled/main.conf || true
sudo rm /etc/nginx/sites-enabled/default || true
sudo rm -rf /etc/nginx/site-path-enabled || true
sudo apt-get purge nginx -y
sudo apt-get purge nginx-* libnginx-* -y
sudo rm -rf /var/www/html

1
.install/nginx/vis-network.min.css vendored Normal file

File diff suppressed because one or more lines are too long

47
.install/nginx/vis.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,101 @@
#!/bin/bash
# https://pad.p2p.legal/scuttlebot?both#Social-Layer-ScuttleBut-server
scuttlebutt() {
echo "TODO"
echo -e "${c_yellow}Onboarding SCUTTLEBUTT...$c_"
where_is_ssb_installed=$(which ssb-server)
# Install npm_modules in ~/.zen/fatlayer_install
mkdir -p ~/.zen/fatlayer_install
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ $where_is_ssb_installed == "" ]]; then
cd ~/.zen/fatlayer_install
# Install dependencies
sudo apt-get install -y socat python3-dev libtool python3-setuptools autoconf automake
# Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
source ~/.bashrc
nvm install --lts
# Install sbot-server
npm install sodium-native ssb-backlinks ssb-ws ssb-links ssb-query
npm install -g ssb-server
fi
# test Install
ssbSERVER=$(which ssb-server)
[[ $ssbSERVER == "" ]] && echo "Check your ssb-server install... Cannot find it !!" && exit 1
# BACKUP OLD SSB
[[ -d ~/.ssb ]] && mv ~/.ssb ~/.ssb.$USER # BACKUP OLD SSB
# MAKE A LINK ~/.ssb.astroport to ~/.ssb
mkdir ~/.ssb.astroport
ln -s ~/.ssb.astroport ~/.ssb
# Create config (TODO: adapt if public Pub or Local Node)
nodename=$(cat /etc/hostname)
extension=$($(echo $nodename | cut -d '.' -f 2))
if [[ $extension == "" ]]; then
nodename=$(echo $nodename).home
# LOCAL
cat > ~/.ssb/config <<EOF
{
"incoming": {
"net": [{ "port": 8008, "scope": "public", "transform": "shs" }]
},
"outgoing": {
"net": [{ "transform": "shs" }]
}
}
EOF
else
# PUB
cat > ~/.ssb/config <<EOF
{
"connections": {
"incoming": {
"net": [
{
"scope": "public", "external": ["$nodename"], "transform": "shs", "port": 8008
},
{ "scope": "private", "host": "127.0.0.1", "transform": "shs", "port": 8008 }
]
},
"outgoing": {
"net": [
{
"transform": "shs"
}
]
}
}
}
EOF
fi
# Store current user as sudo will change it
currentUser=$USER
# Copy SYSTEMD service to correct location
sudo cp "$BASE_DIR/ssb.service" /tmp/ssb.service
# Copy repplace __USER__ place holder to current user
sudo sed -i "s|__USER__|${currentUser}|g" /tmp/ssb.service
sudo sed -i "s|__SSBSERVER__|${ssbSERVER}|g" /tmp/ssb.service
sudo mv /tmp/ssb.service /etc/systemd/system/ssb.service
# Reload, Enable and start SSB Service
sudo systemctl daemon-reload
sudo systemctl enable ssb.service
sudo systemctl start ssb.service
}
$@

View File

@ -0,0 +1,7 @@
{
"plugins": {
"ssb-private": true,
"ssb-backlinks": true,
"patchfoo": true
}
}

65
.install/ssb-patchfoo/install Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# shellcheck disable=SC1091
true
VERSION="TO-V0.5"
BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CURRENT_DIR="$(pwd)"
# Install node.js shared module
# shellcheck source=../shared/node.js/install
source "$BASE_DIR/../shared/node.js/install"
# Make folder if service did not
mkdir -p ~/.ssb/node_modules || true
# shellcheck disable=SC2164
cd ~/.ssb/node_modules
# Install dependencies
npm install --unsafe-perm asyncmemo hashlru pull-stream pull-cat multicb hyperscript pull-paramap ssb-contact ssb-sort stream-to-pull-stream emoji-server pull-paginate ssb-mentions busboy mime-types pull-identify-filetype human-time pull-hyperscript jpeg-autorotate pull-catch diff pull-split pull-utf8-decoder ssb-web-resolver highlight.js pull-box-stream base64-url ssb-backlinks ssb-private
# Install patchfoo and enable plugin
git clone https://github.com/tomeshnet/patchfoo.git patchfoo
(
# shellcheck disable=SC2164
cd patchfoo
git checkout ${VERSION}
)
# Replace ssb-server plugins.install with a static config file
# This will prevent the installation of these modules a second time
# and compiling downlevel for a 3rd time
cp "$BASE_DIR/config" ~/.ssb
#ssb-server plugins.install ssb-private
#ssb-server plugins.install ssb-backlinks
#ssb-server plugins.enable patchfoo
# Stop ssb service to process plugin
sudo systemctl stop ssb
# Disable the git-ssb and npm-ssb prerequisite
# Comment out two lines in patchwork that create a prerequisite for git-ssb and npm-ssb
# but don't seem to serve any purpose. git-ssb and and npm-ssbis not available on npm
sed -i 's#var Git#//var Git#' patchfoo/lib/app.js patchfoo/lib/app.js
sed -i 's#this.git = new Git(this.sbot, this.config)#//this.git = new Git(this.sbot, this.config)#' patchfoo/lib/app.js
sed -i 's#var SsbNpmRegistry#//var SsbNpmRegistry#' patchfoo/lib/app.js patchfoo/lib/app.js
sed -i 's#this.serveSsbNpmRegistry = SsbNpmRegistry.respond(this.sbot, this.config)#//this.serveSsbNpmRegistry = SsbNpmRegistry.respond(this.sbot, this.config)#' patchfoo/lib/app.js
# Comment out line that breaks things
sed -i "s#h('input', {type: 'file', name: 'upload'})#//h('input', {type: 'file', name: 'upload'})#" patchfoo/lib/serve.js
# Start service again to start patchfoo
sudo systemctl start ssb
# Install nginx reverse proxy file
sudo cp "$BASE_DIR/ssb-patchfoo.conf" /etc/nginx/site-path-enabled/ssb-patchfoo.conf
# Add entry into nginx home screen
APP="<div class='app'><h2>Patch Foo</h2>Plain SSB web UI. <br/><a href='/patchfoo'>Go</a></div>"
sudo sed -i "s#<\!--APPLIST-->#$APP\n<\!--APPLIST-->#" "/var/www/html/index.html"
# shellcheck disable=SC2164
cd "$CURRENT_DIR"

View File

@ -0,0 +1,9 @@
location /patchfoo {
proxy_pass http://127.0.0.1:8027/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
sub_filter "=\"/" "=\"/patchfoo/";
sub_filter_once off;
}

16
.install/ssb.service Normal file
View File

@ -0,0 +1,16 @@
[Unit]
Description=Scuttlebot (SSB) daemon
Wants=network.target
After=network.target
[Service]
User=__USER__
Group=__USER__
Type=simple
ExecStart=__SSBSERVER__ start
ExecStop=/bin/kill -s QUIT $MAINPID
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -47,7 +47,7 @@ sed -i 's/_GPATH/$MY_PATH/g' $MY_PATH/.profile
chmod u+x $MY_PATH/.install/*.sh
$MY_PATH/.install/export_colors.sh
[[ -f ~/.bash_aliases ]] && source ~/.bash_aliases
[[ -f ~/.bash_aliases ]] && source ~/.bash_aliases # POKA ?
# --------------------------------------------

@ -1 +1 @@
Subproject commit ea94ab06ea044c025bf583153c3f6e02beaac49b
Subproject commit 6b586eb2839246a4139fe3dde94293aefd05a6c3

View File

@ -0,0 +1,71 @@
<!Doctype HTML>
<head>
<title>Patchwork Invite</title>
<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/source-code-pro" type="text/css"/>
<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/fantasque-sans-mono" type="text/css"/>
<link rel="stylesheet" href="stylesheet.css" title="Stylesheet" type="text/css" media="screen" charset="utf-8">
</head>
<body>
<div class="container">
<img src="https://solarpunk.cool/images/invite-letterhead.jpg" class="logo">
<div>
<h2>Hi, {recipient}!</h2>
<h2> Come talk to me on Scuttlebutt! It's a decentralized social network with a radically different experience from Facebook or Twitter. It's unique, supportive, cool, and reminds me of what the web must have felt like at the very beginning.</h2>
<h2>Because it's so radically different (like, it's not actually <em>on the web</em>) it takes a few steps to get started, which i've helpfully included below!</h2>
<h2 class="steps-title">How to Join Scuttlebutt, and How to Find Me on The Network:</h2>
<ol>
<li class="steps">Download Patchwork, a client for navigating Scuttlebutt.</li>
<p>Scuttlebutt is a <em>method</em> for decentralized communication, but there are different clients to choose from for navigating this scuttleverse(sort of like choosing between chrome and firefox for the web). Patchwork is my preferred client, and you can download it below:</p>
<div class="link-box">
<div class="link-button"><a href="http://dinosaur.is/patchwork-downloader/" target="_blank" >Download Patchwork</a></div>
<p class="caption">(opens in new window)</p>
</div>
<li class="steps">Install and start up The Patchwork application.</li>
<img class="gif" src="https://solarpunk.cool/images/installing-patchwork.gif">
<li class="steps">Paste in a pub invite code.</li>
<p>Pubs are like happy, always-on robot friends that are great at relaying messages for us. The pub helps us talk to one another when we're not on the same local network.</p>
<p><em>You can find me on this pub: <span class="accent-text">{pub}</span></em></p>
<p><<em>And you can join by clicking 'join pub' and pasting in this invite code:</em></p>
<p><strong class="invite-code accent-text">{invite-code}</strong></p>
<img class="gif" src="https://solarpunk.cool/images/pub-invite.gif">
<li class="steps">Hang out for a sec as you are synced up with the network.</li>
<img class="gif" src="https://solarpunk.cool/images/download.gif" style="max-width: 800px; margin-top: 30px;">
<p>With Scuttlebutt, you own and hold your own data, which is your social network. But this means that when you first join the pub, all the messages in your network are downloaded to your computer. This keeps the entire network decentralized and not reliant on any server (unlike facebook or twitter). It also means you can browse the entire network while being offline!</p>
<p>Since it's made up of mostly text, the network will take up about 500mb on yr computer, and the downloading should take less than 5 minutes.</p>
<p>While you wait, check out this video that better explains how Scuttlebutt works, through the context of a <span class="accent-text">*~*~</span>love story<span class="accent-text">*~*~</span>:</p>
<div class="link-box">
<div class="link-button"><a href="https://vimeo.com/236358264" target="_blank">Scuttlebutt: a Love Story</a></div>
<p class="caption">(opens in new window)</p>
</div>
<li class="steps">Find Me and Friend Me.</li>
<p>My name on here is <span class="accent-text">{username}.</span></p>
<p>But you should find me using my public key, which is:</p>
<p class="invite-code accent-text">{public-key}</p>
<p>The public key is sort of like my techno-signature, so you know that the person you are friending is actually me.</p>
<p>You can find me by pasting my public key into the search bar. This'll bring you to my profile, where you can follow me.</p>
<img class="gif" src="https://solarpunk.cool/images/search-for-me.gif">
<li class="steps">Say Hi!</li>
<p>You can write either public or private messages. The private ones are end-to-end encrypted, meaning it's impossible for anyone who isn't me to read them.</p>
</br>
<p class="caption">To send me a private message, click private, then add my @name and say hi!</p>
<img class="gif closer" src="https://solarpunk.cool/images/writing-private-message.gif">
<p class="caption">To send a public message, either just post in the public thread (and maybe @mention me) or post in the #new-people channel (which is what I'd recommend)</p>
<img class="gif closer" src="https://solarpunk.cool/images/writing-public-message.gif">
<li class="steps">Check out these other channels.</li>
<p>There's a lot of good conversations happening on this network. Here are three channels I think you'd like. Just paste them into patchwork's search bar to check them out!</p>
<ul class="accent-text" style="line-height: 1.6em;">
<li>{channel-one}</li>
<li>{channel-two}</li>
<li>{channel-three}</li>
</ul>
</ol>
<div class="closing-remarks">
<p> I'm excited to talk to you through Scuttlebutt! Let me know if you have any problems starting up!</p>
<h2><em> - {sender}</em></h2>
</div>
</div>
</div>
</body>

View File

@ -0,0 +1,92 @@
body{
font-family: 'SourceCodeProRegular';
font-weight: normal;
font-style: normal;
font-size: 16px;
margin: 20px; }
.title{
margin: auto;
font-size: 3em; }
h2{
font-size: 1.35em;
color; #202329;
font-weight: lighter; }
.container{
max-width: 960px;
margin: auto; }
.logo{
max-width: 100%;
display: block;
margin: auto; }
a{
color: inherit;
text-decoration: none; }
.letterhead-title{
margin-top: auto;
margin-bottom: auto; }
.steps-title{
font-weight: bold;
margin-top: 60px;
margin-bottom: 40px;
font-style: normal;
color: #015249; }
.steps{
color: #48a47d;
font-size: 1.1em;
font-weight: bold;
margin-top: 60px;
margin-bottom: 10px; }
.link-box{
max-width: 300px;
text-align: center;
margin: auto; }
.link-button{
background-color: #015249;
color: white;
padding: 10px; }
.caption{
font-size: 0.8em;
margin-top: 1px;
margin-bottom: 1px;
font-style: italic; }
.accent-text{
color: #77c9d4;
font-weight: bold;
font-style: normal; }
.invite-code{
font-family: 'FantasqueSansMonoRegular';
font-style: normal;
font-weight: lighter;
font-size: 1.1em;
line-height: 1.3em; }
.gif{
max-width: 600px;
display: block;
margin: auto;
margin-top: 40px;
margin-bottom: 40px;
-webkit-filter: drop-shadow(2px 2px 2px #a5a5af);
filter: drop-shadow(2px 2px 2px #a5a5af); }
.closer{
margin-top: 10px;
}
.closing-remarks{
margin-top: 60px;
margin-bottom: 60px; }

View File

@ -14,7 +14,7 @@ echo '
############# '$MY_PATH/$ME'
########################################################################
# ex: ./'$ME'
# Initialize G1SSB account + IPFS Publish
# Initialize SSB + G1SSB about + IPFS Node publish
########################################################################
o__ __o __o o__ __o o__ __o o__ __o
/v v\ __|> /v v\ /v v\ <| v\
@ -30,32 +30,32 @@ echo '
# [ASTROPORT](https://astroport.com)
########################################################################
'
##############################################
# NODE ENVIRONEMENT DETECTION
##############################################
########################################################################
# ENVIRONEMENT DETECTION + IPFS ~/.zen/ipfs/.$IPFSNODEID/G1SSB/_info
########################################################################
IPFSNODEID=$(ipfs id -f='<id>\n')
# CREATE ~/.zen/ipfs/.$IPFSNODEID/G1SSB
##############################################
[[ $IPFSNODEID == "" ]] && echo "ERROR missing IPFSNODEID" && exit 1
mkdir -p ~/.zen/ipfs/.$IPFSNODEID/G1SSB
########################################################################
# TODO: Create unique hostname in swarm !! uidna
EXTERNAL=$(cat /etc/hostname).local
[[ "$1" == "KILL" ]] && rm -f ~/.ssb/config && kill -9 $(cat ~/.zen/ssb.pid.bash) && killall node && echo "
[[ "$1" == "KILL" ]] && cp -f ~/.ssb/config.save && kill -9 $(cat ~/.zen/ssb.pid.bash) && killall node && echo "
_ _ _ _
| | (_) | |
| | ___| | |
| |/ / | | |
| <| | | |
|_|\_\_|_|_|
|_|\_\_|_|_|ed
"
ssbpub=$(sbotc whoami 2>/dev/null | jq -r .id)
if [[ $ssbpub == "" ]]; then
# ssb-server not running
[[ "$1" == "RESET" ]] && rm -Rf ~/.ssb.$USER
[[ -d ~/.ssb.$USER ]] && echo "Backup already exists $USER. RESET autoremove... MANUAL : rm -Rf ~/.ssb.$USER " && exit 1
[[ "$1" == "RESET" ]] && rm ~/.ssb # REMOVE BACKUP
[[ -d ~/.ssb.$USER ]] && echo "Backup already exists for $USER. MANUAL CHECK : rm -Rf ~/.ssb.$USER " && exit 1
[[ -d ~/.ssb ]] && mv ~/.ssb ~/.ssb.$USER && rm -Rf ~/.ssb # BACKUP ~/.ssb
mkdir -p ~/.ssb
echo "
@ -69,22 +69,11 @@ $EXTERNAL
[[ -f ~/.ssb/config ]] && cp -f ~/.ssb/config ~/.ssb/config.bkp
cat > ~/.ssb/config <<EOF
{
"connections": {
"incoming": {
"net": [
{
"scope": "public", "external": ["$EXTERNAL"], "transform": "shs", "port": 8008
},
{ "scope": "private", "transform": "shs", "port": 8008, "host": "127.0.0.1" }
]
},
"outgoing": {
"net": [
{
"transform": "shs"
}
]
}
"incoming": {
"net": [{ "port": 8008, "scope": "public", "transform": "shs" }]
},
"outgoing": {
"net": [{ "transform": "shs" }]
}
}
EOF
@ -110,7 +99,7 @@ chmod 755 ~/.zen/run-ssb-PUB_$EXTERNAL.sh
~/.zen/run-ssb-PUB_$EXTERNAL.sh &
sleep 5
[[ -f ~/.ssb/secret.dunikey ]] && cp ~/.ssb/secret.dunikey ~/.ssb/secret.dunikey.$(date -u +%s%N | cut -b1-13)
[[ -f ~/.ssb/secret.dunikey ]] && cp ~/.ssb/secret.dunikey ~/.zen/secret.dunikey.$(date -u +%s%N | cut -b1-13)
ssbpub=$(sbotc whoami 2>/dev/null | jq -r .id)
fi

View File

@ -167,7 +167,7 @@ echo "
"
# ADD PASSENGER TO IPFS
IPASSENGER=$(ipfs add -q $PASSENGER -w | tail -n 1)
IPASSENGER=$(ipfs add -q "$PASSENGER" -w | tail -n 1)
echo "$IPASSENGER" > ~/.zen/tag/${AAH}/_passenger.ipfs
# GET FILE NAME
PASSENGERNAME=$(basename -- "$PASSENGER")
@ -198,7 +198,7 @@ _passenger.ipfs : $IPASSENGER
# Decode _passenger.ipfs with BB Passphrase
##################################################################
openssl aes-256-cbc -pbkdf2 -k \"$BB\" -d -salt -in ~/.zen/tag/${AAH}/_passenger.ipfs.BB.aes -out /tmp/_passenger.ipfs
ipfs get -o /tmp /ipfs/$IPASSENGER/$PASSENGERNAME && vlc /tmp/$PASSENGERNAME 2>/dev/null
ipfs get -o /tmp \"/ipfs/$IPASSENGER/$PASSENGERNAME\" && vlc \"/tmp/$PASSENGERNAME\" 2>/dev/null
READ : $READ Zen
PARK : $PARK Zen