diff --git a/GoogleWiFiClient.pro b/GoogleWiFiClient.pro index 320f63b..6c401c4 100644 --- a/GoogleWiFiClient.pro +++ b/GoogleWiFiClient.pro @@ -16,6 +16,7 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + Encryption/qaesencryption.cpp \ OAuthClient/AuthenticationUtilities.cpp \ OAuthClient/authdialog.cpp \ apiauthenticator.cpp \ @@ -26,6 +27,7 @@ SOURCES += \ wifiapi.cpp HEADERS += \ + Encryption/qaesencryption.h \ OAuthClient/AuthenticationUtilities.h \ OAuthClient/authdialog.h \ apiauthenticator.h \ diff --git a/OAuthClient/AuthenticationUtilities.h b/OAuthClient/AuthenticationUtilities.h index 690b47d..f795c76 100644 --- a/OAuthClient/AuthenticationUtilities.h +++ b/OAuthClient/AuthenticationUtilities.h @@ -5,7 +5,7 @@ #ifndef ONHUBDESKTOP_AUTHENTICATIONUTILITIES_H #define ONHUBDESKTOP_AUTHENTICATIONUTILITIES_H - +#include class AuthenticationUtilities { public: static QString generateClientState(); diff --git a/OAuthClient/authdialog.cpp b/OAuthClient/authdialog.cpp index eafd3d6..43fc5f7 100644 --- a/OAuthClient/authdialog.cpp +++ b/OAuthClient/authdialog.cpp @@ -3,9 +3,8 @@ #include AuthDialog::AuthDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::AuthDialog) -{ + QDialog(parent), + ui(new Ui::AuthDialog) { ui->setupUi(this); @@ -17,14 +16,130 @@ AuthDialog::~AuthDialog() { void AuthDialog::doLoginPageRequest() { // Gets the URI for the login page. - QString data = ""; QNetworkRequest request(QUrl("https://oauthaccountmanager.googleapis.com/v1/authadvice")); - QNetworkAccessManager *manager; -// manager->post(request, nullptr); -// request.setMethod(QWebEngineHttpRequest::Post); + QJsonObject dataObject; - // Because we're using the safarivc endpoint... -// request.setHeader("User-Agent","User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko)"); + dataObject.insert("external_browser", true); + dataObject.insert("report_user_id", true); + dataObject.insert("system_version", "13.4"); + dataObject.insert("app_version", "2.16.4"); + dataObject.insert("user_id", QJsonArray()); + dataObject.insert("safari_authentication_session", true); + dataObject.insert("supported_service", QJsonArray()); + dataObject.insert("request_trigger", "ADD_ACCOUNT"); + dataObject.insert("lib_ver", "3.3"); + dataObject.insert("package_name", "com.google.OnHub"); + dataObject.insert("redirect_uri", "com.google.sso.586698244315-vc96jg3mn4nap78iir799fc2ll3rk18s:/authCallback"); + dataObject.insert("device_name", deviceName); + dataObject.insert("client_id", "586698244315-vc96jg3mn4nap78iir799fc2ll3rk18s.apps.googleusercontent.com"); + dataObject.insert("mediator_client_id", "936475272427.apps.googleusercontent.com"); + dataObject.insert("device_id", deviceId); + dataObject.insert("hl", "en-US"); + dataObject.insert("device_challenge_request", deviceChallenge); + dataObject.insert("client_state", clientState); + QString data = QJsonDocument(dataObject).toJson(); + + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + QNetworkAccessManager manager; + + connect(&manager, &QNetworkAccessManager::finished, this, &AuthDialog::loginPageRequestComplete); + + manager.post(request, data.toUtf8()); + manager.deleteLater(); +} + +void AuthDialog::loginPageRequestComplete(QNetworkReply *reply) { + QByteArray body = reply->readAll(); + QJsonObject obj = QJsonDocument::fromJson(body).object(); + + if (obj.contains("uri")) { + + // save random data from request. + QString path = "./gacc"; + QDir directory; + + // Create folder + if (!directory.exists(path)) + directory.mkpath(path); + + QFile deviceInfo(path + "/device.bin"); + deviceInfo.open(QIODevice::WriteOnly); + deviceInfo.write(deviceId.toUtf8()); + deviceInfo.close(); + launchWebEngine(obj["uri"].toString()); + } +} + + +void AuthDialog::launchWebEngine(QString authUri) { + ui->progressBar->hide(); + QWebEngineHttpRequest authRequest; + + // Disguise as Apple product... + authRequest.setHeader("User-Agent", + "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko)"); + + authRequest.setUrl(QUrl(authUri)); + ui->gridLayout->addWidget(view); + view->load(authRequest); + QWebEngineCookieStore *store = view->page()->profile()->cookieStore(); + store->loadAllCookies(); + connect(store, &QWebEngineCookieStore::cookieAdded, this, &AuthDialog::cookieAdded); +} + +void AuthDialog::cookieAdded(QNetworkCookie cookie) { + if (cookie.name() == "oauth_code") { + view->setDisabled(true); + ui->progressBar->show(); + + QString oauthCode = cookie.value(); + + QNetworkRequest request; + QString data = "client_id=936475272427.apps.googleusercontent.com&code=" + oauthCode + + "&grant_type=authorization_code&scope=https%3A%2F%2Fwww.google.com%2Faccounts%2FOAuthLogin"; + request.setUrl(QUrl("https://www.googleapis.com/oauth2/v4/token")); + QNetworkAccessManager manager; + connect(&manager, &QNetworkAccessManager::finished, this, &AuthDialog::saveRefreshToken); + manager.post(request, data.toUtf8()); + + + } } + +void AuthDialog::saveRefreshToken(QNetworkReply *reply) { + QByteArray body = reply->readAll(); + QJsonObject obj = QJsonDocument::fromJson(body).object(); + if (obj.contains("refresh_token")) { + // Victory! + + QString refreshTkn = obj["refresh_token"].toString(); + + QString path = "./gacc"; + QDir directory; + + if (!directory.exists(path)) + directory.mkpath(path); + + // Perform encryption. + QAESEncryption *aes = new QAESEncryption(QAESEncryption::AES_256, QAESEncryption::CFB, QAESEncryption::PKCS7); + QString key = QSysInfo::machineUniqueId() + + QCryptographicHash::hash(QSysInfo::currentCpuArchitecture().toUtf8(), QCryptographicHash::Sha512); + QRandomGenerator64 random = QRandomGenerator64::securelySeeded(); + int iv = random.bounded(999999999); + + QByteArray enc = aes->encode(refreshTkn.toUtf8(), key.toUtf8(), QByteArray::number(iv)); + + enc = enc.toBase64(); + QJsonObject file; + file.insert("IV", iv); + file.insert("dat", QString(enc)); + // Create the new file. + QFile credentials(path + "/auth.bin"); + credentials.open(QIODevice::WriteOnly); + credentials.write(QJsonDocument(file).toJson()); + credentials.close(); + } +} \ No newline at end of file diff --git a/OAuthClient/authdialog.h b/OAuthClient/authdialog.h index d4f7bce..c415a4d 100644 --- a/OAuthClient/authdialog.h +++ b/OAuthClient/authdialog.h @@ -6,7 +6,9 @@ //#include "HTTP/requestmanager.h" #include //#include - +#include +#include "AuthenticationUtilities.h" +#include "Encryption/qaesencryption.h" namespace Ui { class AuthDialog; @@ -22,14 +24,22 @@ Q_OBJECT void doLoginPageRequest(); - void loginPageRequestComplete(QString reply); - private: - + QString deviceName = QSysInfo::machineHostName(); + QString deviceId = AuthenticationUtilities::generateDeviceId(); + QString deviceChallenge = AuthenticationUtilities::generateChallenge(); + QString clientState = AuthenticationUtilities::generateClientState(); Ui::AuthDialog *ui; QWebEngineView *view = new QWebEngineView(); + void launchWebEngine(QString authUri); + + void loginPageRequestComplete(QNetworkReply *reply); + + void cookieAdded(QNetworkCookie cookie); + + void saveRefreshToken(QNetworkReply *reply); }; #endif // AUTHDIALOG_H diff --git a/OAuthClient/authdialog.ui b/OAuthClient/authdialog.ui index da459db..b4f3fba 100644 --- a/OAuthClient/authdialog.ui +++ b/OAuthClient/authdialog.ui @@ -6,23 +6,25 @@ 0 0 - 745 - 605 + 602 + 553 Dialog - - - - 320 - 170 - 120 - 80 - - - + + + + + 0 + + + 0 + + + + diff --git a/main.cpp b/main.cpp index 6dcee73..373a383 100644 --- a/main.cpp +++ b/main.cpp @@ -14,10 +14,11 @@ QT_CHARTS_USE_NAMESPACE int main(int argc, char *argv[]) { + QtWebEngine::initialize(); QApplication a(argc, argv); MainWindow w; w.show(); - QtWebEngine::initialize(); + return a.exec(); }