소스 검색

Move auth params retrieval

Matthias Vogelgesang 7 년 전
부모
커밋
1c5e64d3ec
2개의 변경된 파일249개의 추가작업 그리고 0개의 파일을 삭제
  1. 206 0
      src/iridium-remote.c
  2. 43 0
      src/iridium-remote.h

+ 206 - 0
src/iridium-remote.c

@@ -0,0 +1,206 @@
+/* iridium-remote.c
+ *
+ * Copyright 2018 Matthias Vogelgesang
+ *
+ * This program is free 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <json-glib/json-glib.h>
+#include <libsoup/soup.h>
+#include "iridium-remote.h"
+
+struct _IridiumRemote {
+  GObject parent_instance;
+
+  SoupSession       *session;
+  SoupURI           *base_uri;
+  gchar             *password;
+  IridiumAuthParams  params;
+};
+
+G_DEFINE_TYPE (IridiumRemote, iridium_remote, G_TYPE_OBJECT)
+
+IridiumRemote *
+iridium_remote_new (void)
+{
+  return g_object_new (IRIDIUM_TYPE_REMOTE, NULL);
+}
+
+static void
+on_auth_params_response_parsed (GObject *object,
+                                GAsyncResult *result,
+                                gpointer user_data)
+{
+  GTask *task;
+  IridiumRemote *self;
+  JsonParser *parser;
+  JsonObject *root;
+  const gchar *version;
+  GError *error = NULL;
+
+  task = user_data;
+  self = g_task_get_task_data (task);
+  parser = JSON_PARSER (object);
+
+  if (!json_parser_load_from_stream_finish (parser, result, &error)) {
+    g_task_return_error (task, error);
+    return;
+  }
+
+  root = json_node_get_object (json_parser_get_root (parser));
+
+  self->params.func = IRIDIUM_CRYPTO_SF_FUNC_PBKDF2;
+  self->params.hash = IRIDIUM_CRYPTO_SF_HASH_SHA512;
+  self->params.cost = json_object_get_int_member (root, "pw_cost");
+  self->params.key_size = json_object_get_int_member (root, "pw_key_size");
+  self->params.salt = g_strdup (json_object_get_string_member (root, "pw_salt"));
+
+  if (g_strcmp0 (json_object_get_string_member (root, "pw_alg"), "sha512")) {
+    g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                         "Hash algorithm other than sha512 is not supported");
+    g_task_return_error (task, error);
+    return;
+  }
+
+  if (g_strcmp0 (json_object_get_string_member (root, "pw_func"), "pbkdf2")) {
+    g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                         "Password derivative function other than PBKDF2 is not supported");
+    g_task_return_error (task, error);
+    return;
+  }
+
+  version = json_object_get_string_member (root, "version");
+
+  if (!g_strcmp0 (version, "001"))
+    self->params.version = IRIDIUM_CRYPTO_SF_VERSION_001;
+  else if (!g_strcmp0 (version, "002"))
+    self->params.version = IRIDIUM_CRYPTO_SF_VERSION_002;
+  else {
+    g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                         "StandardFile protocols other than 001 and 002 are not supported");
+    g_task_return_error (task, error);
+    return;
+  }
+
+  iridium_crypto_derive_keys (&self->params, self->password);
+
+  g_debug ("StandardFile parameters: version=%i func=%i hash=%i key_size=%u iterations=%u",
+           self->params.version,
+           self->params.func,
+           self->params.hash,
+           self->params.key_size,
+           self->params.cost);
+
+  g_object_unref (parser);
+}
+
+static void
+on_send_auth_params_message (GObject *object,
+                             GAsyncResult *result,
+                             gpointer user_data)
+{
+  GInputStream *stream;
+  GTask *task;
+  JsonParser *parser;
+  GError *error = NULL;
+
+  task = user_data;
+  stream = soup_request_send_finish (SOUP_REQUEST (object), result, &error);
+
+  if (stream == NULL) {
+    g_task_return_error (task, error);
+    return;
+  }
+
+  parser = json_parser_new ();
+  json_parser_load_from_stream_async (parser, stream, g_task_get_cancellable (task),
+                                      on_auth_params_response_parsed, task);
+  /* g_object_unref (object); */
+  g_object_unref (stream);
+}
+
+void
+iridium_remote_get_auth_params_async (IridiumRemote *remote,
+                                      const gchar *server,
+                                      const gchar *email,
+                                      const gchar *password,
+                                      GCancellable *cancellable,
+                                      GAsyncReadyCallback callback,
+                                      gpointer user_data)
+{
+  SoupURI *uri;
+  SoupRequestHTTP *request;
+  GTask *task;
+  GError *error = NULL;
+
+  if (remote->base_uri)
+    soup_uri_free (remote->base_uri);
+
+  remote->base_uri = soup_uri_new (server);
+  remote->password = g_strdup (password);
+
+  uri = soup_uri_new_with_base (remote->base_uri, "api/auth/params");
+  soup_uri_set_query_from_fields (uri, "email", email, NULL);
+  task = g_task_new (remote, cancellable, callback, user_data);
+  /* TODO: what happens to request? */
+  request = soup_session_request_http_uri (remote->session, "GET", uri, &error);
+
+  if (request == NULL) {
+    g_task_return_error (task, error);
+    return;
+  }
+
+  g_task_set_task_data (task, remote, NULL);
+  soup_request_send_async (SOUP_REQUEST (request), cancellable, on_send_auth_params_message, task);
+  soup_uri_free (uri);
+}
+
+const IridiumAuthParams *
+iridium_remote_get_auth_params_finish (IridiumRemote *remote,
+                                       GAsyncResult *result,
+                                       GError **error)
+{
+  g_return_val_if_fail (g_task_is_valid (result, remote), NULL);
+  return &remote->params;
+}
+
+static void
+iridium_remote_dispose (GObject *object)
+{
+  IridiumRemote *self;
+
+  self = IRIDIUM_REMOTE (object);
+  g_object_unref (self->session);
+
+  if (self->base_uri)
+    soup_uri_free (self->base_uri);
+
+  G_OBJECT_CLASS (iridium_remote_parent_class)->dispose (object);
+}
+
+static void
+iridium_remote_class_init (IridiumRemoteClass *klass)
+{
+  GObjectClass *oclass;
+
+  oclass = G_OBJECT_CLASS (klass);
+  oclass->dispose = iridium_remote_dispose;
+}
+
+static void
+iridium_remote_init (IridiumRemote *self)
+{
+  self->base_uri = NULL;
+  self->session = soup_session_new ();
+}

+ 43 - 0
src/iridium-remote.h

@@ -0,0 +1,43 @@
+/* iridium-remote.h
+ *
+ * Copyright 2018 Matthias Vogelgesang
+ *
+ * This program is free 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
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include "iridium-crypto.h"
+
+G_BEGIN_DECLS
+
+#define IRIDIUM_TYPE_REMOTE (iridium_remote_get_type())
+
+G_DECLARE_FINAL_TYPE (IridiumRemote, iridium_remote, IRIDIUM, REMOTE, GObject)
+
+IridiumRemote *iridium_remote_new                     (void);
+void           iridium_remote_get_auth_params_async   (IridiumRemote        *remote,
+                                                       const gchar          *server,
+                                                       const gchar          *email,
+                                                       const gchar          *password,
+                                                       GCancellable         *cancellable,
+                                                       GAsyncReadyCallback   callback,
+                                                       gpointer              user_data);
+const IridiumAuthParams
+              *iridium_remote_get_auth_params_finish  (IridiumRemote        *remote,
+                                                       GAsyncResult         *result,
+                                                       GError              **error);
+
+G_END_DECLS