static void inf_test_mass_join_browser_notify_status_cb(GObject* object, const GParamSpec* pspec, gpointer user_data) { InfBrowser* browser; InfBrowserStatus status; InfBrowserIter iter; InfTestMassJoin* massjoin; InfTestMassJoiner* joiner; GSList* item; browser = INF_BROWSER(object); massjoin = (InfTestMassJoin*)user_data; joiner = NULL; for(item = massjoin->joiners; item != NULL; item = item->next) { joiner = (InfTestMassJoiner*)item->data; if(INF_BROWSER(joiner->browser) == browser) break; } g_assert(joiner != NULL); g_object_get(G_OBJECT(browser), "status", &status, NULL); switch(status) { case INF_BROWSER_OPENING: /* nothing to do */ break; case INF_BROWSER_OPEN: fprintf(stdout, "Joiner %s: Connected\n", joiner->username); inf_browser_get_root(browser, &iter); inf_browser_explore( browser, &iter, inf_test_mass_join_explore_finished_cb, joiner ); break; case INF_BROWSER_CLOSED: fprintf(stdout, "Joiner %s: Disconnected\n", joiner->username); massjoin->joiners = g_slist_remove(massjoin->joiners, joiner); if(massjoin->joiners == NULL) inf_standalone_io_loop_quit(INF_STANDALONE_IO(massjoin->io)); break; default: g_assert_not_reached(); break; } }
static void infinoted_plugin_manager_walk_directory( InfinotedPluginManager* manager, const InfBrowserIter* iter, InfinotedPluginInstance* instance, InfinotedPluginManagerWalkDirectoryFunc func) { /* This function walks the whole directory tree recursively and * registers running sessions with the given plugin instance. */ InfBrowser* browser; InfBrowserIter child; InfSessionProxy* proxy; browser = INF_BROWSER(manager->directory); if(inf_browser_is_subdirectory(browser, iter) == TRUE) { if(inf_browser_get_explored(browser, iter) == TRUE) { child = *iter; inf_browser_get_child(browser, &child); do { infinoted_plugin_manager_walk_directory(manager, &child, instance, func); } while(inf_browser_get_next(browser, &child)); } } else { proxy = inf_browser_get_session(browser, iter); if(proxy != NULL) { func(manager, instance, iter, proxy); } } }
static void inf_test_mass_join_explore_finished_cb(InfRequest* request, const InfRequestResult* result, const GError* error, gpointer user_data) { InfTestMassJoiner* joiner; InfBrowser* browser; InfBrowserIter iter; const char* name; gboolean document_exists; joiner = (InfTestMassJoiner*)user_data; browser = INF_BROWSER(joiner->browser); inf_browser_get_root(browser, &iter); if(inf_browser_get_child(browser, &iter) == FALSE) { fprintf( stderr, "Joiner %s: Document %s does not exist\n", joiner->username, joiner->document ); inf_xml_connection_close(infc_browser_get_connection(joiner->browser)); } document_exists = FALSE; do { name = inf_browser_get_node_name(browser, &iter); if(strcmp(name, joiner->document) == 0) { document_exists = TRUE; inf_browser_subscribe( browser, &iter, inf_test_mass_join_subscribe_finished_cb, joiner ); break; } } while(inf_browser_get_next(browser, &iter) == TRUE); if(!document_exists) { fprintf( stderr, "Joiner %s: Document %s does not exist\n", joiner->username, joiner->document ); inf_xml_connection_close(infc_browser_get_connection(joiner->browser)); } }
static void inf_test_mass_join_subscribe_finished_cb(InfRequest* request, const InfRequestResult* result, const GError* error, gpointer user_data) { InfTestMassJoiner* joiner; const InfBrowserIter* iter; InfSession* session; joiner = (InfTestMassJoiner*)user_data; inf_request_result_get_subscribe_session(result, NULL, &iter, NULL); joiner->session = INFC_SESSION_PROXY( inf_browser_get_session( INF_BROWSER(joiner->browser), iter ) ); g_assert(joiner->session != NULL); g_object_get(G_OBJECT(joiner->session), "session", &session, NULL); switch(inf_session_get_status(session)) { case INF_SESSION_PRESYNC: case INF_SESSION_SYNCHRONIZING: g_signal_connect_after( G_OBJECT(session), "synchronization-failed", G_CALLBACK(inf_test_mass_join_session_synchronization_failed_cb), joiner ); g_signal_connect_after( G_OBJECT(session), "synchronization-complete", G_CALLBACK(inf_test_mass_join_session_synchronization_complete_cb), joiner ); break; case INF_SESSION_RUNNING: inf_test_mass_join_join_user(joiner); break; case INF_SESSION_CLOSED: fprintf( stderr, "Joiner %s: Session closed after subscription\n", joiner->username ); inf_xml_connection_close(infc_browser_get_connection(joiner->browser)); break; } g_object_unref(session); }
static gboolean infinoted_plugin_document_stream_process_get_document( InfinotedPluginDocumentStreamStream* stream, const gchar** data, gsize* len) { guint16 user_len; const gchar* user_name; guint16 doc_len; const gchar* doc_name; /* get size of user name string */ if(*len < 2) return FALSE; user_len = *(guint16*)(*data); *data += 2; *len -= 2; /* get user name string */ if(*len < user_len) return FALSE; user_name = *data; *data += user_len; *len -= user_len; /* get size of document string */ if(*len < 2) return FALSE; doc_len = *(guint16*)(*data); *data += 2; *len -= 2; /* get document string */ if(*len < doc_len) return FALSE; doc_name = *data; *data += doc_len; *len -= doc_len; /* quit connection if we already have a buffer */ if(stream->buffer != NULL) { infinoted_plugin_document_stream_send_error( stream, "Stream is already open" ); } else { stream->username = g_strndup(user_name, user_len); stream->navigate_handle = infinoted_plugin_util_navigate_to( INF_BROWSER( infinoted_plugin_manager_get_directory(stream->plugin->manager) ), doc_name, doc_len, FALSE, infinoted_plugin_document_stream_navigate_func, stream ); } return TRUE; }
ExploreRequest* BrowserIter::explore() { if( m_infBrowser ) { InfRequest* req = inf_browser_get_pending_request( INF_BROWSER(m_infBrowser), &m_infBrowserIter, "explore-node" ); if ( req ) { return ExploreRequest::wrap(req, 0, false); } else { return ExploreRequest::wrap( inf_browser_explore( INF_BROWSER(m_infBrowser), &m_infBrowserIter, 0, 0 ) ); } } return 0; }
ExploreRequest* BrowserIter::exploreRequest() const { if( m_infBrowser ) { InfRequest* req = inf_browser_get_pending_request( INF_BROWSER(m_infBrowser), &m_infBrowserIter, "explore-node" ); return ExploreRequest::wrap(req, 0, false); } return 0; }
static void infinoted_plugin_manager_unload_plugin(InfinotedPluginManager* manager, InfinotedPluginInstance* instance) { InfinotedPluginManagerPrivate* priv; InfinotedPluginManagerForeachConnectionData data; InfBrowserIter root; priv = INFINOTED_PLUGIN_MANAGER_PRIVATE(manager); priv->plugins = g_slist_remove(priv->plugins, instance); /* Unregister all sessions with the plugin */ inf_browser_get_root(INF_BROWSER(priv->directory), &root); infinoted_plugin_manager_walk_directory( manager, &root, instance, infinoted_plugin_manager_remove_session ); /* Unregister all connections with the plugin */ data.manager = manager; data.instance = instance; infd_directory_foreach_connection( priv->directory, infinoted_plugin_manager_unload_plugin_foreach_connection_func, &data ); if(instance->plugin->on_deinitialize != NULL) instance->plugin->on_deinitialize(instance+1); infinoted_log_info( priv->log, _("Unloaded plugin \"%s\" from \"%s\""), instance->plugin->name, g_module_name(instance->module) ); g_module_close(instance->module); g_free(instance); }
static void infinoted_plugin_record_session_added(const InfBrowserIter* iter, InfSessionProxy* proxy, gpointer plugin_info, gpointer session_info) { InfinotedPluginRecord* plugin; InfinotedPluginRecordSessionInfo* info; InfSession* session; gchar* title; gchar* pos; InfAdoptedSessionRecord* record; plugin = (InfinotedPluginRecord*)plugin_info; info = (InfinotedPluginRecordSessionInfo*)session_info; g_object_get(G_OBJECT(proxy), "session", &session, NULL); g_assert(INF_ADOPTED_IS_SESSION(session)); title = inf_browser_get_path( INF_BROWSER(infinoted_plugin_manager_get_directory(plugin->manager)), iter ); for(pos = title + 1; *pos != '\0'; ++pos) if(*pos == '/') *pos = '_'; info->plugin = plugin; info->record = infinoted_plugin_record_start( plugin, INF_ADOPTED_SESSION(session), title + 1 ); g_object_set_data(G_OBJECT(session), "infinoted-record", info->record); g_object_unref(session); g_free(title); }
bool BrowserIter::parent() { if( m_infBrowser ) return inf_browser_get_parent( INF_BROWSER(m_infBrowser), &m_infBrowserIter ) != 0; return 0; }
bool BrowserIter::child() { if( m_infBrowser ) return inf_browser_get_child( INF_BROWSER(m_infBrowser), &m_infBrowserIter ) != 0; return 0; }
BrowserIter::BrowserIter( const Browser &browser ) : m_infBrowser( INFC_BROWSER(browser.gobject()) ) { Q_ASSERT(browser.connectionStatus() == INF_BROWSER_OPEN); inf_browser_get_root(INF_BROWSER(m_infBrowser), &m_infBrowserIter); }
QString BrowserIter::noteType() { if( m_infBrowser ) return inf_browser_get_node_type( INF_BROWSER(m_infBrowser), &m_infBrowserIter ); return ""; }
QString BrowserIter::path() const { if( m_infBrowser ) return inf_browser_get_path( INF_BROWSER(m_infBrowser), &m_infBrowserIter ); return ""; }
QString BrowserIter::name() const { if( m_infBrowser ) return inf_browser_get_node_name( INF_BROWSER(m_infBrowser), &m_infBrowserIter ); return ""; }
static void infinoted_plugin_certificate_auth_deinitialize(gpointer plugin_info) { InfinotedPluginCertificateAuth* plugin; InfRequest* remove_acl_account_request; InfCertificateCredentials* creds; guint i; plugin = (InfinotedPluginCertificateAuth*)plugin_info; /* Remove super user account. Note that this is not strictly necessary, * since the acocunt is transient and therefore is not written to disk, * so will not be re-created at the next server start. However, to be sure, * we explicitly remove the account at this point. */ if(plugin->super_id != 0) { remove_acl_account_request = inf_browser_remove_acl_account( INF_BROWSER(infinoted_plugin_manager_get_directory(plugin->manager)), plugin->super_id, infinoted_plugin_certificate_auth_remove_acl_account_cb, plugin ); /* This should be instantaneous: if we are not called back within the call * to inf_browser_remove_acl_account(), then we don't care about the * result, since we are being deinitialized. */ if(remove_acl_account_request != NULL) { inf_signal_handlers_disconnect_by_func( plugin->set_acl_request, G_CALLBACK(infinoted_plugin_certificate_auth_remove_acl_account_cb), plugin ); } } if(plugin->set_acl_request != NULL) { inf_signal_handlers_disconnect_by_func( plugin->set_acl_request, G_CALLBACK(infinoted_plugin_certificate_auth_set_acl_cb), plugin ); g_object_unref(plugin->set_acl_request); } creds = infinoted_plugin_manager_get_credentials(plugin->manager); if(creds != NULL) gnutls_certificate_free_cas(inf_certificate_credentials_get(creds)); infd_directory_set_certificate( infinoted_plugin_manager_get_directory(plugin->manager), NULL, NULL ); /* If we have a ca_key set, the certificate that belongs to the key had * its ownership transferred to the directory, so make sure not to free * it twice here. */ for(i = 0; i < plugin->n_cas; ++i) if(plugin->ca_key == NULL || i != plugin->ca_key_index) gnutls_x509_crt_deinit(plugin->cas[i]); g_free(plugin->cas); if(plugin->ca_key != NULL) gnutls_x509_privkey_deinit(plugin->ca_key); g_free(plugin->ca_list_file); g_free(plugin->ca_key_file); g_free(plugin->super_user); }
static void infinoted_plugin_dbus_main_invocation(gpointer user_data) { /* Main thread invocation handler */ InfinotedPluginDbusInvocation* invocation; const gchar* path; gsize len; InfinotedPluginUtilNavigateData* navigate; invocation = (InfinotedPluginDbusInvocation*)user_data; invocation->plugin->invocations = g_slist_prepend(invocation->plugin->invocations, invocation); g_atomic_int_inc(&invocation->ref_count); /* These commands take a path as the first parameter and do not * require that path to be explored. */ if(strcmp(invocation->method_name, "remove_node") == 0 || strcmp(invocation->method_name, "query_acl") == 0 || strcmp(invocation->method_name, "set_acl") == 0 || strcmp(invocation->method_name, "check_acl") == 0) { path = g_variant_get_string( g_variant_get_child_value(invocation->parameters, 0), &len ); navigate = infinoted_plugin_util_navigate_to( INF_BROWSER(infinoted_plugin_manager_get_directory(invocation->plugin->manager)), path, len, FALSE, infinoted_plugin_dbus_navigate_done, invocation ); if(navigate != NULL) invocation->navigate = navigate; } /* These commands take a path as the first parameter and DO require that * path to be explored. */ else if(strcmp(invocation->method_name, "explore_node") == 0 || strcmp(invocation->method_name, "add_node") == 0) { path = g_variant_get_string( g_variant_get_child_value(invocation->parameters, 0), &len ); navigate = infinoted_plugin_util_navigate_to( INF_BROWSER(infinoted_plugin_manager_get_directory(invocation->plugin->manager)), path, len, TRUE, infinoted_plugin_dbus_navigate_done, invocation ); if(navigate != NULL) invocation->navigate = navigate; } else { g_dbus_method_invocation_return_error_literal( invocation->invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Not implemented" ); infinoted_plugin_dbus_invocation_free(invocation->plugin, invocation); } }
static void inf_test_certificate_request_notify_status_cb(GObject* object, GParamSpec* pspec, gpointer user_data) { InfTestCertificateRequest* test; InfBrowserStatus status; gnutls_x509_crq_t crq; InfRequest* request; GError* error; int res; test = (InfTestCertificateRequest*)user_data; g_object_get(G_OBJECT(test->browser), "status", &status, NULL); if(status == INF_BROWSER_OPEN) { fprintf(stderr, "Connection established, creating key... (4096 bit)\n"); /* TODO: Some error checking here */ gnutls_x509_privkey_init(&test->key); gnutls_x509_privkey_generate(test->key, GNUTLS_PK_RSA, 4096, 0); fprintf(stderr, "Done, sending the certificate request\n"); gnutls_x509_crq_init(&crq); gnutls_x509_crq_set_key(crq, test->key); gnutls_x509_crq_set_key_usage(crq, GNUTLS_KEY_DIGITAL_SIGNATURE); gnutls_x509_crq_set_version(crq, 3); gnutls_x509_crq_set_dn_by_oid( crq, GNUTLS_OID_X520_COMMON_NAME, 0, "Armin Burgmeier", strlen("Armin Burgmeier") ); /* TODO: gnutls_x509_crq_sign2 is deprecated in favour of * gnutls_x509_crq_privkey_sign, but the latter returns the error code * GNUTLS_E_UNIMPLEMENTED_FEATURE, so we keep using the deprecated * version here. */ /*gnutls_x509_crq_privkey_sign(crq, key, GNUTLS_DIG_SHA1, 0);*/ gnutls_x509_crq_sign2(crq, test->key, GNUTLS_DIG_SHA1, 0); error = NULL; request = inf_browser_create_acl_account( INF_BROWSER(object), crq, inf_test_certificate_request_finished_cb, test ); gnutls_x509_crq_deinit(crq); } if(status == INF_BROWSER_CLOSED) { if(inf_standalone_io_loop_running(test->io)) inf_standalone_io_loop_quit(test->io); } }
int main(int argc, char* argv[]) { InfTestBrowser test; InfIpAddress* address; InfCommunicationManager* manager; InfTcpConnection* tcp_conn; GError* error; gnutls_global_init(); g_type_init(); test.io = inf_standalone_io_new(); #ifndef G_OS_WIN32 test.input_fd = STDIN_FILENO; #endif address = inf_ip_address_new_loopback4(); error = NULL; tcp_conn = inf_tcp_connection_new_and_open(INF_IO(test.io), address, inf_protocol_get_default_port(), &error); inf_ip_address_free(address); if(tcp_conn == NULL) { fprintf(stderr, "Could not open TCP connection: %s\n", error->message); g_error_free(error); } else { test.conn = inf_xmpp_connection_new( tcp_conn, INF_XMPP_CONNECTION_CLIENT, NULL, "localhost", INF_XMPP_CONNECTION_SECURITY_BOTH_PREFER_TLS, NULL, NULL, NULL ); g_object_unref(G_OBJECT(tcp_conn)); manager = inf_communication_manager_new(); test.browser = INF_BROWSER( infc_browser_new( INF_IO(test.io), manager, INF_XML_CONNECTION(test.conn) ) ); g_signal_connect_after( G_OBJECT(test.browser), "notify::status", G_CALLBACK(inf_test_browser_notify_status_cb), &test ); g_signal_connect( G_OBJECT(test.browser), "error", G_CALLBACK(inf_test_browser_error_cb), &test ); inf_standalone_io_loop(test.io); g_object_unref(G_OBJECT(manager)); g_object_unref(G_OBJECT(test.browser)); /* TODO: Wait until the XMPP connection is in status closed */ g_object_unref(G_OBJECT(test.conn)); } g_object_unref(G_OBJECT(test.io)); return 0; }
static gboolean infinoted_plugin_certificate_auth_initialize(InfinotedPluginManager* manager, gpointer plugin_info, GError** error) { InfinotedPluginCertificateAuth* plugin; InfCertificateCredentials* creds; GPtrArray* read_certs; int res; guint i; gnutls_x509_crt_t* sign_certs; InfCertificateChain* sign_chain; gnutls_x509_privkey_t super_key; InfCertUtilDescription desc; gnutls_x509_crt_t super_cert; InfAclAccountId super_id; gnutls_x509_crt_t chain[2]; gboolean written; InfdDirectory* directory; InfBrowserIter iter; InfAclSheetSet sheet_set; InfAclSheet sheet; InfRequest* request; plugin = (InfinotedPluginCertificateAuth*)plugin_info; plugin->manager = manager; creds = infinoted_plugin_manager_get_credentials(manager); if(creds == NULL) { g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CREDENTIALS, "%s", _("The certificate-auth plugin can only be used when TLS is enabled " "and a server certificate has been set.") ); return FALSE; } read_certs = inf_cert_util_read_certificate(plugin->ca_list_file, NULL, error); if(read_certs == NULL) return FALSE; if(read_certs->len == 0) { g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CAS, _("File \"%s\" does not contain any CA certificates"), plugin->ca_list_file ); g_ptr_array_free(read_certs, TRUE); return FALSE; } plugin->n_cas = read_certs->len; plugin->cas = (gnutls_x509_crt_t*)g_ptr_array_free(read_certs, FALSE); res = gnutls_certificate_set_x509_trust( inf_certificate_credentials_get(creds), plugin->cas, plugin->n_cas ); if(res < 0) { inf_gnutls_set_error(error, res); return FALSE; } if(plugin->ca_key_file != NULL) { plugin->ca_key = inf_cert_util_read_private_key(plugin->ca_key_file, error); if(plugin->ca_key == NULL) return FALSE; /* Walk through certificates and find the certificate that the key * belongs to. */ for(i = 0; i < plugin->n_cas; ++i) if(inf_cert_util_check_certificate_key(plugin->cas[i], plugin->ca_key)) break; if(i == plugin->n_cas) { gnutls_x509_privkey_deinit(plugin->ca_key); plugin->ca_key = NULL; g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CA_FOR_KEY, "%s", _("The given CA key does not match with any of the CA certificates") ); return FALSE; } plugin->ca_key_index = i; /* Set the signing certificate of the directory, so that it can handle * account creation requests. Note that this takes ownership of the * certificate, so we take special care in the cleanup code in * infinoted_plugin_certificate_auth_deinitialize(). */ sign_certs = g_malloc(sizeof(gnutls_x509_crt_t)); sign_certs[0] = plugin->cas[plugin->ca_key_index]; sign_chain = inf_certificate_chain_new(sign_certs, 1); infd_directory_set_certificate( infinoted_plugin_manager_get_directory(plugin->manager), plugin->ca_key, sign_chain ); inf_certificate_chain_unref(sign_chain); } if(plugin->super_user != NULL) { if(plugin->ca_key == NULL) { g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CA_KEY, "%s", _("Cannot generate a superuser certificate without CA key") ); return FALSE; } /* Create a private key and certificate for the super user. */ infinoted_log_info( infinoted_plugin_manager_get_log(plugin->manager), _("Creating 4096-bit RSA private key for the super user account...") ); super_key = inf_cert_util_create_private_key(GNUTLS_PK_RSA, 4096, error); if(super_key == NULL) return FALSE; desc.validity = 12 * 3600; /* 12 hours */ desc.dn_common_name = "Super User"; desc.san_dnsname = NULL; super_cert = inf_cert_util_create_signed_certificate( super_key, &desc, plugin->cas[plugin->ca_key_index], plugin->ca_key, error ); if(super_cert == NULL) { gnutls_x509_privkey_deinit(super_key); return FALSE; } super_id = infd_directory_create_acl_account( infinoted_plugin_manager_get_directory(plugin->manager), _("Super User"), TRUE, /* transient */ &super_cert, 1, error ); if(super_id == 0) { gnutls_x509_crt_deinit(super_cert); gnutls_x509_privkey_deinit(super_key); return FALSE; } plugin->super_id = super_id; chain[0] = super_cert; chain[1] = plugin->cas[plugin->ca_key_index]; written = inf_cert_util_write_certificate_with_key( super_key, chain, 2, plugin->super_user, error ); gnutls_x509_crt_deinit(super_cert); gnutls_x509_privkey_deinit(super_key); if(written == FALSE) return FALSE; inf_browser_get_root( INF_BROWSER(infinoted_plugin_manager_get_directory(plugin->manager)), &iter ); directory = infinoted_plugin_manager_get_directory(plugin->manager); sheet.account = super_id; sheet.mask = INF_ACL_MASK_ALL; infd_directory_get_support_mask(directory, &sheet.perms); sheet_set.n_sheets = 1; sheet_set.own_sheets = NULL; sheet_set.sheets = &sheet; request = inf_browser_set_acl( INF_BROWSER(directory), &iter, &sheet_set, infinoted_plugin_certificate_auth_set_acl_cb, plugin ); if(request != NULL) { plugin->set_acl_request = request; g_object_ref(plugin->set_acl_request); } } return TRUE; }
static void infinoted_plugin_autosave_save(InfinotedPluginAutosaveSessionInfo* info) { InfdDirectory* directory; InfBrowserIter* iter; GError* error; gchar* path; InfSession* session; InfBuffer* buffer; gchar* root_directory; gchar* argv[4]; directory = infinoted_plugin_manager_get_directory(info->plugin->manager); iter = &info->iter; error = NULL; if(info->timeout != NULL) { inf_io_remove_timeout(infd_directory_get_io(directory), info->timeout); info->timeout = NULL; } g_object_get(G_OBJECT(info->proxy), "session", &session, NULL); buffer = inf_session_get_buffer(session); inf_signal_handlers_block_by_func( G_OBJECT(buffer), G_CALLBACK(infinoted_plugin_autosave_buffer_notify_modified_cb), info ); if(infd_directory_iter_save_session(directory, iter, &error) == FALSE) { path = inf_browser_get_path(INF_BROWSER(directory), iter); infinoted_log_warning( infinoted_plugin_manager_get_log(info->plugin->manager), _("Failed to auto-save session \"%s\": %s\n\n" "Will retry in %u seconds."), path, error->message, info->plugin->interval ); g_free(path); g_error_free(error); error = NULL; infinoted_plugin_autosave_start(info); } else { /* TODO: Remove this as soon as directory itself unsets modified flag * on session_write */ inf_buffer_set_modified(INF_BUFFER(buffer), FALSE); if(info->plugin->hook != NULL) { path = inf_browser_get_path(INF_BROWSER(directory), iter); g_object_get( G_OBJECT(infd_directory_get_storage(directory)), "root-directory", &root_directory, NULL ); argv[0] = info->plugin->hook; argv[1] = root_directory; argv[2] = path; argv[3] = NULL; if(!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) { infinoted_log_warning( infinoted_plugin_manager_get_log(info->plugin->manager), _("Could not execute autosave hook: \"%s\""), error->message ); g_error_free(error); error = NULL; } g_free(path); g_free(root_directory); } } inf_signal_handlers_unblock_by_func( G_OBJECT(buffer), G_CALLBACK(infinoted_plugin_autosave_buffer_notify_modified_cb), info ); g_object_unref(session); }
bool BrowserIter::isDirectory() { if( m_infBrowser ) return inf_browser_is_subdirectory( INF_BROWSER(m_infBrowser), &m_infBrowserIter ) != 0; return 0; }
bool BrowserIter::isExplored() { if( m_infBrowser ) return inf_browser_get_explored( INF_BROWSER(m_infBrowser), &m_infBrowserIter ) != 0; return 0; }
static gboolean infinoted_plugin_manager_load_plugin(InfinotedPluginManager* manager, const gchar* plugin_path, const gchar* plugin_name, GKeyFile* key_file, GError** error) { gchar* plugin_basename; gchar* plugin_filename; GModule* module; const InfinotedPlugin* plugin; InfinotedPluginInstance* instance; gboolean result; GError* local_error; InfBrowserIter root; InfinotedPluginManagerForeachConnectionData data; plugin_basename = g_strdup_printf( "libinfinoted-plugin-%s.%s", plugin_name, G_MODULE_SUFFIX ); plugin_filename = g_build_filename(plugin_path, plugin_basename, NULL); g_free(plugin_basename); module = g_module_open(plugin_filename, G_MODULE_BIND_LOCAL); g_free(plugin_filename); if(module == NULL) { g_set_error( error, infinoted_plugin_manager_error_quark(), INFINOTED_PLUGIN_MANAGER_ERROR_OPEN_FAILED, "%s", g_module_error() ); return FALSE; } if(g_module_symbol(module, "INFINOTED_PLUGIN", (gpointer*)&plugin) == FALSE) { g_set_error( error, infinoted_plugin_manager_error_quark(), INFINOTED_PLUGIN_MANAGER_ERROR_NO_ENTRY_POINT, "%s", g_module_error() ); g_module_close(module); return FALSE; } instance = g_malloc(sizeof(InfinotedPluginInstance) + plugin->info_size); instance->module = module; instance->plugin = plugin; /* Call on_info_initialize, allowing the plugin to set default values */ if(plugin->on_info_initialize != NULL) plugin->on_info_initialize(instance+1); /* Next, parse options from keyfile */ if(plugin->options != NULL) { local_error = NULL; result = infinoted_parameter_load_from_key_file( plugin->options, key_file, plugin->name, instance+1, &local_error ); if(result == FALSE) { g_free(instance); g_module_close(module); g_propagate_prefixed_error( error, local_error, "Failed to initialize plugin \"%s\": ", plugin_name ); return FALSE; } } /* Finally, call on_initialize, which allows the plugin to initialize * itself with the plugin options. */ if(plugin->on_initialize != NULL) { local_error = NULL; result = plugin->on_initialize(manager, instance+1, &local_error); if(local_error != NULL) { if(instance->plugin->on_deinitialize != NULL) instance->plugin->on_deinitialize(instance+1); g_free(instance); g_module_close(module); g_propagate_prefixed_error( error, local_error, "Failed to initialize plugin \"%s\": ", plugin_name ); return FALSE; } } /* Register initial connections with plugin */ data.manager = manager; data.instance = instance; infd_directory_foreach_connection( manager->directory, infinoted_plugin_manager_load_plugin_foreach_connection_func, &data ); /* Register initial sessions with plugin */ inf_browser_get_root(INF_BROWSER(manager->directory), &root); infinoted_plugin_manager_walk_directory( manager, &root, instance, infinoted_plugin_manager_add_session ); infinoted_log_info( manager->log, _("Loaded plugin \"%s\" from \"%s\""), plugin_name, g_module_name(module) ); manager->plugins = g_slist_prepend(manager->plugins, instance); return TRUE; }
static gboolean infinoted_plugin_transformation_protection_check_request_cb(InfAdoptedSession* session, InfAdoptedRequest* request, InfAdoptedUser* user, gpointer user_data) { InfinotedPluginTransformationProtectionSessionInfo* info; guint vdiff; InfXmlConnection* connection; gchar* request_str; gchar* current_str; gchar* remote_id; gchar* path; info = (InfinotedPluginTransformationProtectionSessionInfo*)user_data; vdiff = inf_adopted_state_vector_vdiff( inf_adopted_request_get_vector(request), inf_adopted_algorithm_get_current( inf_adopted_session_get_algorithm(session) ) ); if(vdiff > info->plugin->max_vdiff) { connection = inf_user_get_connection(INF_USER(user)); /* Local requests do not need to be transformed, so always have a * zero vdiff. */ g_assert(connection != NULL); /* Kill the connection */ infd_session_proxy_unsubscribe( INFD_SESSION_PROXY(info->proxy), connection ); /* Write a log message */ path = inf_browser_get_path( INF_BROWSER( infinoted_plugin_manager_get_directory(info->plugin->manager) ), &info->iter ); request_str = inf_adopted_state_vector_to_string( inf_adopted_request_get_vector(request) ); current_str = inf_adopted_state_vector_to_string( inf_adopted_algorithm_get_current( inf_adopted_session_get_algorithm(session) ) ); g_object_get(G_OBJECT(connection), "remote-id", &remote_id, NULL); infinoted_log_warning( infinoted_plugin_manager_get_log(info->plugin->manager), _("In document \"%s\": Attempt to transform request \"%s\" to current state \"%s\" " "(vdiff=%u) by user \"%s\" (id=%u, conn=%s). Maximum allowed is %u; the " "connection has been unsubscribed."), path, request_str, current_str, vdiff, inf_user_get_name(INF_USER(user)), inf_user_get_id(INF_USER(user)), remote_id, info->plugin->max_vdiff ); g_free(path); g_free(request_str); g_free(current_str); g_free(remote_id); /* Prevent the request from being transformed */ return TRUE; } return FALSE; }