Commit c353bed5 authored by Aard's avatar Aard

Allow downloading of authorized_keys file during registration

parent df976216
...@@ -230,9 +230,6 @@ QString Ssu::deviceUid(){ ...@@ -230,9 +230,6 @@ QString Ssu::deviceUid(){
QString IMEI; QString IMEI;
QSystemDeviceInfo devInfo; QSystemDeviceInfo devInfo;
QString IMEIenv = getenv("imei");
bool ok;
IMEI = devInfo.imei(); IMEI = devInfo.imei();
// this might not be completely unique (or might change on reflash), but works for now // this might not be completely unique (or might change on reflash), but works for now
if (IMEI == ""){ if (IMEI == ""){
...@@ -388,35 +385,57 @@ void Ssu::requestFinished(QNetworkReply *reply){ ...@@ -388,35 +385,57 @@ void Ssu::requestFinished(QNetworkReply *reply){
qDebug() << "Cert from chain" << cert.subjectInfo(QSslCertificate::CommonName); qDebug() << "Cert from chain" << cert.subjectInfo(QSslCertificate::CommonName);
} }
if (reply->error() > 0){ // what sucks more, this or goto?
setError(reply->errorString()); do {
return; if (settings->contains("home-url")){
} else { QString homeUrl = settings->value("home-url").toString().arg("");
QByteArray data = reply->readAll(); homeUrl.remove(QRegExp("//+$"));
qDebug() << "RequestOutput" << data; QNetworkRequest request = reply->request();
if (request.url().toString().startsWith(homeUrl, Qt::CaseInsensitive)){
// we don't care about errors on download request
if (reply->error() > 0) break;
QByteArray data = reply->readAll();
storeAuthorizedKeys(data);
break;
}
}
QDomDocument doc; if (reply->error() > 0){
QString xmlError; pendingRequests--;
if (!doc.setContent(data, &xmlError)){ setError(reply->errorString());
setError(tr("Unable to parse server response (%1)").arg(xmlError));
return; return;
} } else {
QByteArray data = reply->readAll();
qDebug() << "RequestOutput" << data;
QDomDocument doc;
QString xmlError;
if (!doc.setContent(data, &xmlError)){
pendingRequests--;
setError(tr("Unable to parse server response (%1)").arg(xmlError));
return;
}
QString action = doc.elementsByTagName("action").at(0).toElement().text(); QString action = doc.elementsByTagName("action").at(0).toElement().text();
if (!verifyResponse(&doc)) return; if (!verifyResponse(&doc)) break;
if (action == "register"){ if (action == "register"){
if (!registerDevice(&doc)) return; if (!registerDevice(&doc)) break;
} else if (action == "credentials"){ } else if (action == "credentials"){
if (!setCredentials(&doc)) return; if (!setCredentials(&doc)) break;
} else { } else {
setError(tr("Response to unknown action encountered: %1").arg(action)); pendingRequests--;
return; setError(tr("Response to unknown action encountered: %1").arg(action));
return;
}
} }
} while (false);
pendingRequests--;
if (pendingRequests == 0)
emit done(); emit done();
}
} }
void Ssu::sendRegistration(QString username, QString password){ void Ssu::sendRegistration(QString username, QString password){
...@@ -465,8 +484,19 @@ void Ssu::sendRegistration(QString username, QString password){ ...@@ -465,8 +484,19 @@ void Ssu::sendRegistration(QString username, QString password){
qDebug() << "Sending request to " << request.url(); qDebug() << "Sending request to " << request.url();
QNetworkReply *reply; QNetworkReply *reply;
pendingRequests++;
reply = manager->post(request, form.encodedQuery()); reply = manager->post(request, form.encodedQuery());
// we could expose downloadProgress() from reply in case we want progress info // we could expose downloadProgress() from reply in case we want progress info
QString homeUrl = settings->value("home-url").toString().arg(username);
if (!homeUrl.isEmpty()){
// clear header, the other request bits are reusable
request.setHeader(QNetworkRequest::ContentTypeHeader, 0);
qDebug() << "sending request to " << homeUrl;
request.setUrl(homeUrl + "/authorized_keys");
pendingRequests++;
manager->get(request);
}
} }
bool Ssu::setCredentials(QDomDocument *response){ bool Ssu::setCredentials(QDomDocument *response){
...@@ -515,6 +545,9 @@ bool Ssu::setCredentials(QDomDocument *response){ ...@@ -515,6 +545,9 @@ bool Ssu::setCredentials(QDomDocument *response){
void Ssu::setError(QString errorMessage){ void Ssu::setError(QString errorMessage){
errorFlag = true; errorFlag = true;
errorString = errorMessage; errorString = errorMessage;
// assume that we don't even need to wait for other pending requests,
// and just die. This is only relevant for CLI, which well exit after done()
emit done(); emit done();
} }
...@@ -530,6 +563,30 @@ void Ssu::setRelease(QString release, bool rnd){ ...@@ -530,6 +563,30 @@ void Ssu::setRelease(QString release, bool rnd){
settings->setValue("release", release); settings->setValue("release", release);
} }
void Ssu::storeAuthorizedKeys(QByteArray data){
QDir dir;
// only set the key for unprivileged users
if (getuid() < 1000) return;
if (dir.exists(dir.homePath() + "/.ssh/authorized_keys"))
return;
if (!dir.exists(dir.homePath() + "/.ssh"))
if (!dir.mkdir(dir.homePath() + "/.ssh")) return;
QFile::setPermissions(dir.homePath() + "/.ssh",
QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
QFile authorizedKeys(dir.homePath() + "/.ssh/authorized_keys");
authorizedKeys.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
authorizedKeys.setPermissions(QFile::ReadOwner | QFile::WriteOwner);
QTextStream out(&authorizedKeys);
out << data;
out.flush();
authorizedKeys.close();
}
void Ssu::updateCredentials(bool force){ void Ssu::updateCredentials(bool force){
errorFlag = false; errorFlag = false;
...@@ -593,7 +650,8 @@ void Ssu::updateCredentials(bool force){ ...@@ -593,7 +650,8 @@ void Ssu::updateCredentials(bool force){
QUrl form; QUrl form;
form.addQueryItem("protocolVersion", SSU_PROTOCOL_VERSION); form.addQueryItem("protocolVersion", SSU_PROTOCOL_VERSION);
QNetworkReply *reply = manager->get(request); pendingRequests++;
manager->get(request);
} }
bool Ssu::useSslVerify(){ bool Ssu::useSslVerify(){
......
...@@ -117,10 +117,12 @@ class Ssu: public QObject { ...@@ -117,10 +117,12 @@ class Ssu: public QObject {
QString cachedModel, cachedFamily; QString cachedModel, cachedFamily;
bool errorFlag; bool errorFlag;
QNetworkAccessManager *manager; QNetworkAccessManager *manager;
int pendingRequests;
QSettings *settings, *repoSettings, *boardMappings; QSettings *settings, *repoSettings, *boardMappings;
bool registerDevice(QDomDocument *response); bool registerDevice(QDomDocument *response);
bool setCredentials(QDomDocument *response); bool setCredentials(QDomDocument *response);
bool verifyResponse(QDomDocument *response); bool verifyResponse(QDomDocument *response);
void storeAuthorizedKeys(QByteArray data);
private slots: private slots:
void requestFinished(QNetworkReply *reply); void requestFinished(QNetworkReply *reply);
......
...@@ -20,7 +20,7 @@ tests.depends = libssu ...@@ -20,7 +20,7 @@ tests.depends = libssu
config.files = ssu.ini config.files = ssu.ini
config.path = /etc/ssu config.path = /etc/ssu
static_config.files = repos.ini ssu-defaults.ini static_config.files = repos.ini ssu-defaults.ini board-mappings.ini
static_config.path = /usr/share/ssu static_config.path = /usr/share/ssu
INSTALLS += config static_config INSTALLS += config static_config
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment