mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
Add qtox update-server tools
qtox-updater-sign takes data from stdin or as argument, signs it with the updater's private key, and output the signature + the data qtox-updater-genflist generates a flist, a serialized list of AutoUpdater::UpdateFileMeta for the qTox updater
This commit is contained in:
parent
965254d151
commit
1350fbbaf9
97
tools/update-server/qtox-updater-genflist/main.cpp
Normal file
97
tools/update-server/qtox-updater-genflist/main.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include <iostream>
|
||||
#include <QFile>
|
||||
#include <QByteArray>
|
||||
#include <QDir>
|
||||
#include <QCryptographicHash>
|
||||
#include <sodium.h>
|
||||
#include "serialize.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/// Pass the target folder as first argument, no spaces allowed. We'll call that dir $TARGET
|
||||
/// Update the content of $TARGET/files/ before calling this tool
|
||||
/// We'll generate $TARGET/flist and exit
|
||||
/// We need qtox-updater-skey in our working directory to sign the flist
|
||||
///
|
||||
/// The generated flist is very simple and just installs everything in the working directory ...
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
cout << "qTox updater flist generator" << endl;
|
||||
|
||||
/// First some basic error handling, prepare our handles, ...
|
||||
if (argc != 2)
|
||||
{
|
||||
cout << "ERROR: qtox-updater-genflist takes the target path in argument" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
QFile skeyFile("qtox-updater-skey");
|
||||
if (!skeyFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
cout << "ERROR: qtox-updater-genflist can't open the secret (private) key file" << endl;
|
||||
return 1;
|
||||
}
|
||||
QByteArray skeyData = skeyFile.readAll();
|
||||
skeyData = QByteArray::fromHex(skeyData);
|
||||
skeyFile.close();
|
||||
|
||||
QString target(argv[1]);
|
||||
|
||||
QFile flistFile(target+"/flist");
|
||||
if (!flistFile.open(QIODevice::Truncate | QIODevice::WriteOnly))
|
||||
{
|
||||
cout << "ERROR: qtox-updater-genflist can't open the target flist" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
QDir fdir(target+"/files/");
|
||||
if (!fdir.isReadable())
|
||||
{
|
||||
cout << "ERROR: qtox-updater-genflist can't open the target files directory" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
QStringList filesListStr = fdir.entryList(QDir::Files);
|
||||
|
||||
/// Serialize the flist data
|
||||
QByteArray flistData;
|
||||
for (QString fileStr : filesListStr)
|
||||
{
|
||||
cout << "Adding "<<fileStr.toStdString()<<"..."<<endl;
|
||||
|
||||
QFile file(target+"/files/"+fileStr);
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
cout << "ERROR: qtox-updater-genflist couldn't open a target file to sign it" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
QByteArray fileData = file.readAll();
|
||||
|
||||
unsigned char sig[crypto_sign_BYTES];
|
||||
crypto_sign_detached(sig, nullptr, (unsigned char*)fileData.data(), fileData.size(), (unsigned char*)skeyData.data());
|
||||
|
||||
flistData += QByteArray::fromRawData((char*)sig, crypto_sign_BYTES);
|
||||
flistData += stringToData(QCryptographicHash::hash(fileStr.toUtf8(), QCryptographicHash::Sha3_224).toHex());
|
||||
flistData += stringToData("./"+fileStr); ///< Always install in the working directory for now
|
||||
flistData += uint64ToData(fileData.size());
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
cout << "Signing and writing the flist..."<<endl;
|
||||
|
||||
/// Sign our flist
|
||||
unsigned char sig[crypto_sign_BYTES];
|
||||
crypto_sign_detached(sig, nullptr, (unsigned char*)flistData.data(), flistData.size(), (unsigned char*)skeyData.data());
|
||||
|
||||
/// Write the flist
|
||||
flistFile.write("1");
|
||||
flistFile.write((char*)sig, crypto_sign_BYTES);
|
||||
flistFile.write(flistData);
|
||||
|
||||
flistFile.close();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += console c++11
|
||||
QT += core
|
||||
LIBS += -lsodium
|
||||
|
||||
SOURCES += main.cpp \
|
||||
serialize.cpp
|
||||
|
||||
HEADERS += \
|
||||
serialize.h
|
254
tools/update-server/qtox-updater-genflist/serialize.cpp
Normal file
254
tools/update-server/qtox-updater-genflist/serialize.cpp
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
Copyright (C) 2014 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "serialize.h"
|
||||
|
||||
QByteArray doubleToData(double num)
|
||||
{
|
||||
union
|
||||
{
|
||||
char tab[8];
|
||||
double n;
|
||||
} castUnion;
|
||||
//char n[8];
|
||||
//*((double*) n) = num;
|
||||
|
||||
castUnion.n=num;
|
||||
return QByteArray(castUnion.tab,8);
|
||||
}
|
||||
|
||||
QByteArray floatToData(float num)
|
||||
{
|
||||
union
|
||||
{
|
||||
char tab[4];
|
||||
float n;
|
||||
} castUnion;
|
||||
|
||||
castUnion.n=num;
|
||||
return QByteArray(castUnion.tab,4);
|
||||
}
|
||||
|
||||
float dataToFloat(QByteArray data)
|
||||
{
|
||||
union
|
||||
{
|
||||
char tab[4];
|
||||
float n;
|
||||
} castUnion;
|
||||
|
||||
castUnion.tab[0]=data.data()[0];
|
||||
castUnion.tab[1]=data.data()[1];
|
||||
castUnion.tab[2]=data.data()[2];
|
||||
castUnion.tab[3]=data.data()[3];
|
||||
return castUnion.n;
|
||||
}
|
||||
|
||||
// Converts a string into PNet string data
|
||||
QByteArray stringToData(QString str)
|
||||
{
|
||||
QByteArray data(4,0);
|
||||
// Write the size in a Uint of variable lenght (8-32 bits)
|
||||
int i=0;
|
||||
uint num1 = (uint)str.toUtf8().size();
|
||||
while (num1 >= 0x80)
|
||||
{
|
||||
data[i] = (unsigned char)(num1 | 0x80); i++;
|
||||
num1 = num1 >> 7;
|
||||
}
|
||||
data[i]=num1;
|
||||
data.resize(i+1);
|
||||
data+=str.toUtf8();
|
||||
return data;
|
||||
}
|
||||
|
||||
QString dataToString(QByteArray data)
|
||||
{
|
||||
// Variable UInt32
|
||||
unsigned char num3;
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
int i=0;
|
||||
do
|
||||
{
|
||||
num3 = data[i]; i++;
|
||||
num |= (num3 & 0x7f) << num2;
|
||||
num2 += 7;
|
||||
} while ((num3 & 0x80) != 0);
|
||||
unsigned int strlen = (uint) num;
|
||||
|
||||
if (!strlen)
|
||||
return QString();
|
||||
|
||||
data = data.right(data.size()-i); // Remove the strlen
|
||||
data.truncate(strlen);
|
||||
return QString(data);
|
||||
}
|
||||
|
||||
float dataToRangedSingle(float min, float max, int numberOfBits, QByteArray data)
|
||||
{
|
||||
uint endvalue=0;
|
||||
uint value=0;
|
||||
if (numberOfBits <= 8)
|
||||
{
|
||||
endvalue = (uchar)data[0];
|
||||
goto done;
|
||||
}
|
||||
value = (uchar)data[0];
|
||||
numberOfBits -= 8;
|
||||
if (numberOfBits <= 8)
|
||||
{
|
||||
endvalue = (value | ((uint) ((uchar)data[1]) << 8));
|
||||
goto done;
|
||||
}
|
||||
value |= (uint) (((uchar)data[1]) << 8);
|
||||
numberOfBits -= 8;
|
||||
if (numberOfBits <= 8)
|
||||
{
|
||||
uint num2 = (uint) (((uchar)data[2]) << 0x10);
|
||||
endvalue = (value | num2);
|
||||
goto done;
|
||||
}
|
||||
value |= (uint) (((uchar)data[2]) << 0x10);
|
||||
numberOfBits -= 8;
|
||||
endvalue = (value | ((uint) (((uchar)data[3]) << 0x18)));
|
||||
goto done;
|
||||
|
||||
done:
|
||||
|
||||
float num = max - min;
|
||||
int num2 = (((int) 1) << numberOfBits) - 1;
|
||||
float num3 = endvalue;
|
||||
float num4 = num3 / ((float) num2);
|
||||
return (min + (num4 * num));
|
||||
}
|
||||
|
||||
QByteArray rangedSingleToData(float value, float min, float max, int numberOfBits)
|
||||
{
|
||||
QByteArray data;
|
||||
float num = max - min;
|
||||
float num2 = (value - min) / num;
|
||||
int num3 = (((int) 1) << numberOfBits) - 1;
|
||||
uint source = num3 * num2;
|
||||
|
||||
if (numberOfBits <= 8)
|
||||
{
|
||||
data += (unsigned char)source;
|
||||
return data;
|
||||
}
|
||||
data += (unsigned char)source;
|
||||
numberOfBits -= 8;
|
||||
if (numberOfBits <= 8)
|
||||
{
|
||||
data += (unsigned char)source>>8;
|
||||
return data;
|
||||
}
|
||||
data += (unsigned char)source>>8;
|
||||
numberOfBits -= 8;
|
||||
if (numberOfBits <= 8)
|
||||
{
|
||||
data += (unsigned char)source>>16;
|
||||
return data;
|
||||
}
|
||||
data += (unsigned char)source>>16;
|
||||
data += (unsigned char)source>>24;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
uint8_t dataToUint8(QByteArray data)
|
||||
{
|
||||
return (uint8_t)data[0];
|
||||
}
|
||||
|
||||
uint16_t dataToUint16(QByteArray data)
|
||||
{
|
||||
return ((uint16_t)(uint8_t)data[0])
|
||||
+(((uint16_t)(uint8_t)data[1])<<8);
|
||||
}
|
||||
|
||||
uint32_t dataToUint32(QByteArray data)
|
||||
{
|
||||
return ((uint32_t)(uint8_t)data[0])
|
||||
+(((uint32_t)(uint8_t)data[1])<<8)
|
||||
+(((uint32_t)(uint8_t)data[2])<<16)
|
||||
+(((uint32_t)(uint8_t)data[3])<<24);
|
||||
}
|
||||
|
||||
uint64_t dataToUint64(QByteArray data)
|
||||
{
|
||||
return ((uint64_t)(uint8_t)data[0])
|
||||
+(((uint64_t)(uint8_t)data[1])<<8)
|
||||
+(((uint64_t)(uint8_t)data[2])<<16)
|
||||
+(((uint64_t)(uint8_t)data[3])<<24)
|
||||
+(((uint64_t)(uint8_t)data[4])<<32)
|
||||
+(((uint64_t)(uint8_t)data[5])<<40)
|
||||
+(((uint64_t)(uint8_t)data[6])<<48)
|
||||
+(((uint64_t)(uint8_t)data[7])<<56);
|
||||
}
|
||||
|
||||
unsigned getVUint32Size(QByteArray data)
|
||||
{
|
||||
unsigned lensize=0;
|
||||
{
|
||||
unsigned char num3;
|
||||
do {
|
||||
num3 = data[lensize];
|
||||
lensize++;
|
||||
} while ((num3 & 0x80) != 0);
|
||||
}
|
||||
return lensize;
|
||||
}
|
||||
|
||||
QByteArray uint8ToData(uint8_t num)
|
||||
{
|
||||
QByteArray data(1,0);
|
||||
data[0] = (uint8_t)num;
|
||||
return data;
|
||||
}
|
||||
|
||||
QByteArray uint16ToData(uint16_t num)
|
||||
{
|
||||
QByteArray data(2,0);
|
||||
data[0] = (uint8_t)(num & 0xFF);
|
||||
data[1] = (uint8_t)((num>>8) & 0xFF);
|
||||
return data;
|
||||
}
|
||||
|
||||
QByteArray uint32ToData(uint32_t num)
|
||||
{
|
||||
QByteArray data(4,0);
|
||||
data[0] = (uint8_t)(num & 0xFF);
|
||||
data[1] = (uint8_t)((num>>8) & 0xFF);
|
||||
data[2] = (uint8_t)((num>>16) & 0xFF);
|
||||
data[3] = (uint8_t)((num>>24) & 0xFF);
|
||||
return data;
|
||||
}
|
||||
|
||||
QByteArray uint64ToData(uint64_t num)
|
||||
{
|
||||
QByteArray data(8,0);
|
||||
data[0] = (uint8_t)(num & 0xFF);
|
||||
data[1] = (uint8_t)((num>>8) & 0xFF);
|
||||
data[2] = (uint8_t)((num>>16) & 0xFF);
|
||||
data[3] = (uint8_t)((num>>24) & 0xFF);
|
||||
data[4] = (uint8_t)((num>>32) & 0xFF);
|
||||
data[5] = (uint8_t)((num>>40) & 0xFF);
|
||||
data[6] = (uint8_t)((num>>48) & 0xFF);
|
||||
data[7] = (uint8_t)((num>>56) & 0xFF);
|
||||
return data;
|
||||
}
|
45
tools/update-server/qtox-updater-genflist/serialize.h
Normal file
45
tools/update-server/qtox-updater-genflist/serialize.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright (C) 2014 by Project Tox <https://tox.im>
|
||||
|
||||
This file is part of qTox, a Qt-based graphical interface for Tox.
|
||||
|
||||
This program is libre software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SERIALIZE_H
|
||||
#define SERIALIZE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
/// Most of those functions are unsafe unless otherwise specified
|
||||
/// Do not use them on untrusted data (e.g. check a signature first)
|
||||
|
||||
QByteArray doubleToData(double num);
|
||||
QByteArray floatToData(float num);
|
||||
float dataToFloat(QByteArray data);
|
||||
QByteArray stringToData(QString str);
|
||||
QString dataToString(QByteArray data);
|
||||
float dataToRangedSingle(float min, float max, int numberOfBits, QByteArray data);
|
||||
QByteArray rangedSingleToData(float value, float min, float max, int numberOfBits);
|
||||
uint8_t dataToUint8(QByteArray data);
|
||||
uint16_t dataToUint16(QByteArray data);
|
||||
uint32_t dataToUint32(QByteArray data);
|
||||
uint64_t dataToUint64(QByteArray data);
|
||||
unsigned getVUint32Size(QByteArray data);
|
||||
QByteArray uint8ToData(uint8_t num);
|
||||
QByteArray uint16ToData(uint16_t num);
|
||||
QByteArray uint32ToData(uint32_t num);
|
||||
QByteArray uint64ToData(uint64_t num);
|
||||
|
||||
#endif // SERIALIZE_H
|
43
tools/update-server/qtox-updater-sign/main.cpp
Normal file
43
tools/update-server/qtox-updater-sign/main.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <sodium.h>
|
||||
#include <QByteArray>
|
||||
#include <QFile>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QFile io;
|
||||
QByteArray msg;
|
||||
if (argc > 1)
|
||||
{
|
||||
msg = QByteArray(argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
io.open(stdin, QIODevice::ReadOnly);
|
||||
msg = io.readAll();
|
||||
io.close();
|
||||
}
|
||||
io.open(stdout, QIODevice::WriteOnly);
|
||||
|
||||
QFile skeyFile("qtox-updater-skey");
|
||||
if (!skeyFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
io.write("ERROR: qtox-updater-sign can't open the secret (private) key file\n");
|
||||
io.close();
|
||||
return 1;
|
||||
}
|
||||
QByteArray skeyData = skeyFile.readAll();
|
||||
skeyData = QByteArray::fromHex(skeyData);
|
||||
skeyFile.close();
|
||||
|
||||
unsigned char sig[crypto_sign_BYTES];
|
||||
crypto_sign_detached(sig, nullptr, (unsigned char*)msg.data(), msg.size(), (unsigned char*)skeyData.data());
|
||||
|
||||
io.write((char*)sig, crypto_sign_BYTES);
|
||||
io.write(msg);
|
||||
io.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
TEMPLATE = app
|
||||
CONFIG += console c++11
|
||||
QT += core
|
||||
|
||||
SOURCES += main.cpp
|
||||
|
||||
LIBS += -lsodium
|
Loading…
Reference in New Issue
Block a user