END_TEST START_TEST (test_empathy_irc_network_manager_find_network_by_address) { EmpathyIrcNetworkManager *mgr; EmpathyIrcNetwork *network; struct server_t freenode_servers[] = { { "irc.freenode.net", 6667, FALSE }, { "irc.eu.freenode.net", 6667, FALSE }}; gchar *global_file_orig; global_file_orig = get_xml_file (GLOBAL_SAMPLE); mgr = empathy_irc_network_manager_new (global_file_orig, NULL); g_free (global_file_orig); network = empathy_irc_network_manager_find_network_by_address (mgr, "irc.freenode.net"); fail_if (network == NULL); check_network (network, "Freenode", "UTF-8", freenode_servers, 2); network = empathy_irc_network_manager_find_network_by_address (mgr, "irc.eu.freenode.net"); fail_if (network == NULL); check_network (network, "Freenode", "UTF-8", freenode_servers, 2); network = empathy_irc_network_manager_find_network_by_address (mgr, "unknown"); fail_if (network != NULL); g_object_unref (mgr); }
/* pull in packs for base and any subscription */ int download_subscribed_packs(int oldversion, int UNUSED_PARAM newversion, bool required) { struct list *iter; struct sub *sub = NULL; int err; if (!check_network()) { return -ENOSWUPDSERVER; } iter = list_head(subs); while (iter) { sub = iter->data; iter = iter->next; if (sub->oldversion == sub->version) { // pack didn't change in this release continue; } if (oldversion != 0) { oldversion = sub->oldversion; } err = download_pack(oldversion, sub->version, sub->component); if (err < 0) { if (required) { return err; } else { continue; } } } return 0; }
static void grab_hidden_ssid(const unsigned char *bssid, struct ieee80211_frame *wh, int len, const int off) { struct network *n; unsigned char *p = ((unsigned char *) (wh + 1)) + off; int l; n = find_net(bssid); if (n && n->n_ssid[0]) return; len -= sizeof(*wh) + off + 2; if (len < 0) goto __bad; if (*p++ != IEEE80211_ELEMID_SSID) goto __bad; l = *p++; if (l > len) goto __bad; if (l == 0) return; if (!n) n = net_add(bssid); memcpy(n->n_ssid, p, l); n->n_ssid[l] = 0; check_network(n); return; __bad: printf("bad grab_hidden_ssid\n"); return; }
int search_main(int argc, char **argv) { int ret = 0; int lock_fd = 0; struct manifest *MoM = NULL; if (!parse_options(argc, argv)) { return EXIT_FAILURE; } ret = swupd_init(&lock_fd); if (ret != 0) { printf("Failed swupd initialization, exiting now.\n"); goto clean_exit; } if (!check_network()) { printf("Error: Network issue, unable to proceed with update\n"); ret = EXIT_FAILURE; goto clean_exit; } if (!init) { printf("Searching for '%s'\n\n", search_string); } ret = download_manifests(&MoM); if (ret != 0) { printf("Error: Failed to download manifests\n"); goto clean_exit; } if (init) { printf("Successfully retreived manifests. Exiting\n"); ret = 0; goto clean_exit; } /* Arbitrary upper limit to ensure we aren't getting handed garbage */ if (!display_files && ((strlen(search_string) <= 0) || (strlen(search_string) > NAME_MAX))) { printf("Error - search string invalid\n"); ret = EXIT_FAILURE; goto clean_exit; } do_search(MoM, search_type, search_string); clean_exit: free_manifest(MoM); free_globals(); swupd_curl_cleanup(); v_lockfile(lock_fd); return ret; }
/* * list_installable_bundles() * Parse the full manifest for the current version of the OS and print * all available bundles. */ int list_installable_bundles() { struct list *list; struct file *file; struct manifest *MoM = NULL; int current_version; int lock_fd; int ret; if (!init_globals()) { return EINIT_GLOBALS; } current_version = read_version_from_subvol_file(path_prefix); if (swupd_init(&lock_fd) != 0) { printf("Error: Failed updater initialization. Exiting now\n"); return ECURL_INIT; } ret = create_required_dirs(); if (ret != 0) { printf("State directory %s cannot be recreated, aborting removal\n", STATE_DIR); v_lockfile(lock_fd); return EXIT_FAILURE; } get_mounted_directories(); if (!check_network()) { printf("Error: Network issue, unable to download manifest\n"); v_lockfile(lock_fd); return EXIT_FAILURE; } swupd_curl_set_current_version(current_version); ret = load_manifests(current_version, current_version, "MoM", NULL, &MoM); if (ret != 0) { v_lockfile(lock_fd); return ret; } list = MoM->manifests; while (list) { file = list->data; list = list->next; printf("%s\n", file->filename); } free_manifest(MoM); v_lockfile(lock_fd); return 0; }
static DBusHandlerResult filter_func (DBusConnection *connection, DBusMessage *message, void *user_data) { if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "StateChanged")) { check_network (connection, user_data); return DBUS_HANDLER_RESULT_HANDLED; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; }
/* * list_installable_bundles() * Parse the full manifest for the current version of the OS and print * all available bundles. */ int list_installable_bundles() { struct list *list; struct file *file; struct manifest *MoM = NULL; int current_version; int lock_fd; int ret; ret = swupd_init(&lock_fd); if (ret != 0) { printf("Error: Failed updater initialization. Exiting now\n"); return ret; } if (!check_network()) { printf("Error: Network issue, unable to download manifest\n"); v_lockfile(lock_fd); return EXIT_FAILURE; } current_version = get_current_version(path_prefix); if (current_version < 0) { printf("Error: Unable to determine current OS version\n"); v_lockfile(lock_fd); return ECURRENT_VERSION; } swupd_curl_set_current_version(current_version); MoM = load_mom(current_version); if (!MoM) { v_lockfile(lock_fd); return ret; } list = MoM->manifests; while (list) { file = list->data; list = list->next; printf("%s\n", file->filename); } free_manifest(MoM); v_lockfile(lock_fd); return 0; }
/* * list_installable_bundles() * Parse the full manifest for the current version of the OS and print * all available bundles. */ int list_installable_bundles() { struct list *list; struct file *file; struct manifest *MoM = NULL; int current_version; int lock_fd; int ret; ret = swupd_init(&lock_fd); if (ret != 0) { printf("Error: Failed updater initialization. Exiting now\n"); return ret; } if (!check_network()) { printf("Error: Network issue, unable to download manifest\n"); v_lockfile(lock_fd); return EXIT_FAILURE; } current_version = read_version_from_subvol_file(path_prefix); swupd_curl_set_current_version(current_version); ret = load_manifests(current_version, current_version, "MoM", NULL, &MoM); if (ret != 0) { v_lockfile(lock_fd); return ret; } list = MoM->manifests; while (list) { file = list->data; list = list->next; printf("%s\n", file->filename); } free_manifest(MoM); v_lockfile(lock_fd); return 0; }
END_TEST START_TEST (test_load_global_file) { EmpathyIrcNetworkManager *mgr; gchar *global_file, *user_file; GSList *networks, *l; struct server_t freenode_servers[] = { { "irc.freenode.net", 6667, FALSE }, { "irc.eu.freenode.net", 6667, FALSE }}; struct server_t gimpnet_servers[] = { { "irc.gimp.org", 6667, FALSE }, { "irc.us.gimp.org", 6667, FALSE }}; struct server_t test_servers[] = { { "irc.test.org", 6669, TRUE }}; struct server_t undernet_servers[] = { { "eu.undernet.org", 6667, FALSE }}; gboolean network_checked[4]; gchar *global_file_orig; global_file_orig = get_xml_file (GLOBAL_SAMPLE); mgr = empathy_irc_network_manager_new (global_file_orig, NULL); g_object_get (mgr, "global-file", &global_file, "user-file", &user_file, NULL); fail_if (global_file == NULL || strcmp (global_file, global_file_orig) != 0); fail_if (user_file != NULL); g_free (global_file); g_free (global_file_orig); g_free (user_file); networks = empathy_irc_network_manager_get_networks (mgr); fail_if (g_slist_length (networks) != 4); network_checked[0] = network_checked[1] = network_checked[2] = network_checked[3] = FALSE; /* check networks and servers */ for (l = networks; l != NULL; l = g_slist_next (l)) { gchar *name; g_object_get (l->data, "name", &name, NULL); fail_if (name == NULL); if (strcmp (name, "Freenode") == 0) { check_network (l->data, "Freenode", "UTF-8", freenode_servers, 2); network_checked[0] = TRUE; } else if (strcmp (name, "GIMPNet") == 0) { check_network (l->data, "GIMPNet", "UTF-8", gimpnet_servers, 2); network_checked[1] = TRUE; } else if (strcmp (name, "Test Server") == 0) { check_network (l->data, "Test Server", "ISO-8859-1", test_servers, 1); network_checked[2] = TRUE; } else if (strcmp (name, "Undernet") == 0) { check_network (l->data, "Undernet", "UTF-8", undernet_servers, 1); network_checked[3] = TRUE; } else { fail_if (TRUE); } g_free (name); } fail_if (!network_checked[0] || !network_checked[1] || !network_checked[2] || !network_checked[3]); g_slist_foreach (networks, (GFunc) g_object_unref, NULL); g_slist_free (networks); g_object_unref (mgr); }
END_TEST START_TEST (test_modify_both_files) { EmpathyIrcNetworkManager *mgr; EmpathyIrcNetwork *network; EmpathyIrcServer *server; gchar *global_file, *user_file; GSList *networks, *l; struct server_t gimpnet_servers[] = { { "irc.gimp.org", 6667, TRUE }, { "irc.us.gimp.org", 6668, FALSE }}; struct server_t great_server[] = { { "irc.greatserver.com", 7873, TRUE }}; struct server_t another_server[] = { { "irc.anothersrv.be", 6660, FALSE }}; struct server_t undernet_servers[] = { { "eu.undernet.org", 6667, FALSE }, { "us.undernet.org", 6667, FALSE }}; gboolean network_modified[4]; gboolean network_checked[4]; gchar *global_file_orig, *user_file_orig; copy_xml_file (USER_SAMPLE, USER_FILE); global_file_orig = get_xml_file (GLOBAL_SAMPLE); user_file_orig = get_user_xml_file (USER_FILE); mgr = empathy_irc_network_manager_new (global_file_orig, user_file_orig); g_object_get (mgr, "global-file", &global_file, "user-file", &user_file, NULL); fail_if (global_file == NULL || strcmp (global_file, global_file_orig) != 0); fail_if (user_file == NULL || strcmp (user_file, user_file_orig) != 0); g_free (global_file); g_free (global_file_orig); g_free (user_file); g_free (user_file_orig); networks = empathy_irc_network_manager_get_networks (mgr); fail_if (g_slist_length (networks) != 5); network_modified[0] = network_modified[1] = network_modified[2] = network_modified[3] = FALSE; /* check networks and servers */ for (l = networks; l != NULL; l = g_slist_next (l)) { EmpathyIrcNetwork *network; gchar *name; network = l->data; g_object_get (network, "name", &name, NULL); fail_if (name == NULL); if (strcmp (name, "GIMPNet") == 0) { /* Modify user network */ GSList *servers, *ll; servers = empathy_irc_network_get_servers (network); for (ll = servers; ll != NULL; ll = g_slist_next (ll)) { EmpathyIrcServer *server; gchar *address; server = ll->data; g_object_get (server, "address", &address, NULL); if (strcmp (address, "irc.gimp.org") == 0) { /* change SSL */ g_object_set (server, "ssl", TRUE, NULL); } else if (strcmp (address, "irc.us.gimp.org") == 0) { /* change port */ g_object_set (server, "port", 6668, NULL); } else if (strcmp (address, "irc.au.gimp.org") == 0) { /* remove this server */ empathy_irc_network_remove_server (network, server); } else { fail_if (TRUE); } g_free (address); } network_modified[0] = TRUE; g_slist_foreach (servers, (GFunc) g_object_unref, NULL); g_slist_free (servers); } else if (strcmp (name, "My Server") == 0) { /* remove user network */ empathy_irc_network_manager_remove (mgr, network); network_modified[1] = TRUE; } else if (strcmp (name, "Freenode") == 0) { /* remove global network */ empathy_irc_network_manager_remove (mgr, network); network_modified[2] = TRUE; } else if (strcmp (name, "Undernet") == 0) { /* modify global network */ EmpathyIrcServer *server; server = empathy_irc_server_new ("us.undernet.org", 6667, FALSE); empathy_irc_network_append_server (network, server); g_object_unref (server); network_modified[3] = TRUE; } else if (strcmp (name, "Another Server") == 0) { /* Don't change this one */ } else { fail_if (TRUE); } g_free (name); } fail_if (!network_modified[0] || !network_modified[1] || !network_modified[2] || !network_modified[3]); /* Add a new network */ network = empathy_irc_network_new ("Great Server"); server = empathy_irc_server_new ("irc.greatserver.com", 7873, TRUE); empathy_irc_network_append_server (network, server); empathy_irc_network_manager_add (mgr, network); g_object_unref (server); g_object_unref (network); g_slist_foreach (networks, (GFunc) g_object_unref, NULL); g_slist_free (networks); g_object_unref (mgr); /* Now let's reload the file and check its contain */ global_file_orig = get_xml_file (GLOBAL_SAMPLE); user_file_orig = get_user_xml_file (USER_FILE); mgr = empathy_irc_network_manager_new (global_file_orig, user_file_orig); g_free (global_file_orig); g_free (user_file_orig); networks = empathy_irc_network_manager_get_networks (mgr); fail_if (g_slist_length (networks) != 4); network_checked[0] = network_checked[1] = network_checked[2] = network_checked[3] = FALSE; /* check networks and servers */ for (l = networks; l != NULL; l = g_slist_next (l)) { gchar *name; g_object_get (l->data, "name", &name, NULL); fail_if (name == NULL); if (strcmp (name, "GIMPNet") == 0) { check_network (l->data, "GIMPNet", "UTF-8", gimpnet_servers, 2); network_checked[0] = TRUE; } else if (strcmp (name, "Great Server") == 0) { check_network (l->data, "Great Server", "UTF-8", great_server, 1); network_checked[1] = TRUE; } else if (strcmp (name, "Another Server") == 0) { check_network (l->data, "Another Server", "UTF-8", another_server, 1); network_checked[2] = TRUE; } else if (strcmp (name, "Undernet") == 0) { check_network (l->data, "Undernet", "UTF-8", undernet_servers, 2); network_checked[3] = TRUE; } else { fail_if (TRUE); } g_free (name); } fail_if (!network_checked[0] || !network_checked[1] || !network_checked[2] || !network_checked[3]); g_slist_foreach (networks, (GFunc) g_object_unref, NULL); g_slist_free (networks); g_object_unref (mgr); }
END_TEST START_TEST (test_load_user_file) { EmpathyIrcNetworkManager *mgr; gchar *global_file, *user_file; GSList *networks, *l; struct server_t gimpnet_servers[] = { { "irc.gimp.org", 6667, FALSE }, { "irc.us.gimp.org", 6667, FALSE }, { "irc.au.gimp.org", 6667, FALSE }}; struct server_t my_server[] = { { "irc.mysrv.net", 7495, TRUE }}; struct server_t another_server[] = { { "irc.anothersrv.be", 6660, FALSE }}; gboolean network_checked[3]; gchar *user_file_orig; copy_xml_file (USER_SAMPLE, USER_FILE); user_file_orig = get_user_xml_file (USER_FILE); mgr = empathy_irc_network_manager_new (NULL, user_file_orig); g_object_get (mgr, "global-file", &global_file, "user-file", &user_file, NULL); fail_if (global_file != NULL); fail_if (user_file == NULL || strcmp (user_file, user_file_orig) != 0); g_free (global_file); g_free (user_file); g_free (user_file_orig); networks = empathy_irc_network_manager_get_networks (mgr); fail_if (g_slist_length (networks) != 3); network_checked[0] = network_checked[1] = network_checked[2] = FALSE; /* check networks and servers */ for (l = networks; l != NULL; l = g_slist_next (l)) { gchar *name; g_object_get (l->data, "name", &name, NULL); fail_if (name == NULL); if (strcmp (name, "GIMPNet") == 0) { check_network (l->data, "GIMPNet", "UTF-8", gimpnet_servers, 3); network_checked[0] = TRUE; } else if (strcmp (name, "My Server") == 0) { check_network (l->data, "My Server", "UTF-8", my_server, 1); network_checked[1] = TRUE; } else if (strcmp (name, "Another Server") == 0) { check_network (l->data, "Another Server", "UTF-8", another_server, 1); network_checked[2] = TRUE; } else { fail_if (TRUE); } g_free (name); } fail_if (!network_checked[0] || !network_checked[1] || !network_checked[2]); g_slist_foreach (networks, (GFunc) g_object_unref, NULL); g_slist_free (networks); g_object_unref (mgr); }
int main_update() { int current_version = -1, server_version = -1; struct manifest *current_manifest = NULL, *server_manifest = NULL; struct list *updates = NULL; int ret; int lock_fd; int retries = 0; int timeout = 10; srand(time(NULL)); ret = swupd_init(&lock_fd); if (ret != 0) { /* being here means we already close log by a previously caught error */ printf("Updater failed to initialize, exiting now.\n"); return ret; } if (!check_network()) { printf("Error: Network issue, unable to proceed with update\n"); ret = EXIT_FAILURE; goto clean_curl; } printf("Update started.\n"); read_subscriptions_alt(); if (!signature_initialize(UPDATE_CA_CERTS_PATH "/" SIGNATURE_CA_CERT)) { goto clean_curl; } /* Step 1: get versions */ ret = check_versions(¤t_version, &server_version, path_prefix); if (ret < 0) { goto clean_curl; } if (server_version <= current_version) { printf("Version on server (%i) is not newer than system version (%i)\n", server_version, current_version); ret = EXIT_SUCCESS; goto clean_curl; } printf("Preparing to update from %i to %i\n", current_version, server_version); /* Step 2: housekeeping */ if (rm_staging_dir_contents("download")) { goto clean_curl; } load_current_manifests: /* Step 3: setup manifests */ /* get the from/to MoM manifests */ printf("Querying current manifest.\n"); ret = load_manifests(current_version, current_version, "MoM", NULL, ¤t_manifest); if (ret) { /* TODO: possibly remove this as not getting a "from" manifest is not fatal * - we just don't apply deltas */ if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); printf("Retry #%d downloading from/to MoM Manifests\n", retries); goto load_current_manifests; } printf("Failure retrieving manifest from server\n"); goto clean_exit; } /* Reset the retries and timeout for subsequent download calls */ retries = 0; timeout = 10; load_server_manifests: printf("Querying server manifest.\n"); ret = load_manifests(current_version, server_version, "MoM", NULL, &server_manifest); if (ret) { if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); printf("Retry #%d downloading server Manifests\n", retries); goto load_server_manifests; } printf("Failure retrieving manifest from server\n"); goto clean_exit; } if (current_manifest == NULL || server_manifest == NULL) { printf("Unable to load manifest after retrying (config or network problem?)\n"); goto clean_exit; } retries = 0; timeout = 10; ret = add_included_manifests(server_manifest); if (ret) { goto clean_exit; } subscription_versions_from_MoM(current_manifest, 1); subscription_versions_from_MoM(server_manifest, 0); link_submanifests(current_manifest, server_manifest); /* updating subscribed manifests is done as part of recurse_manifest */ /* read the current collective of manifests that we are subscribed to */ current_manifest->submanifests = recurse_manifest(current_manifest, NULL); if (!current_manifest->submanifests) { printf("Cannot load current MoM sub-manifests, (%s), exiting\n", strerror(errno)); goto clean_exit; } /* consolidate the current collective manifests down into one in memory */ current_manifest->files = files_from_bundles(current_manifest->submanifests); current_manifest->files = consolidate_files(current_manifest->files); /* read the new collective of manifests that we are subscribed to */ server_manifest->submanifests = recurse_manifest(server_manifest, NULL); if (!server_manifest->submanifests) { printf("Error: Cannot load server MoM sub-manifests, (%s), exiting\n", strerror(errno)); goto clean_exit; } /* consolidate the new collective manifests down into one in memory */ server_manifest->files = files_from_bundles(server_manifest->submanifests); server_manifest->files = consolidate_files(server_manifest->files); /* prepare for an update process based on comparing two in memory manifests */ link_manifests(current_manifest, server_manifest); #if 0 debug_write_manifest(current_manifest, "debug_manifest_current.txt"); debug_write_manifest(server_manifest, "debug_manifest_server.txt"); #endif /* Step 4: check disk state before attempting update */ run_preupdate_scripts(server_manifest); download_packs: /* Step 5: get the packs and untar */ ret = download_subscribed_packs(false); if (ret) { // packs don't always exist, tolerate that but not ENONET if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); printf("Retry #%d downloading packs\n", retries); goto download_packs; } printf("No network, or server unavailable for pack downloads\n"); goto clean_exit; } /* Step 6: some more housekeeping */ /* TODO: consider trying to do less sorting of manifests */ updates = create_update_list(current_manifest, server_manifest); link_renames(updates, current_manifest); /* TODO: Have special lists for candidate and renames */ print_statistics(current_version, server_version); /* Step 7: apply the update */ ret = update_loop(updates, server_manifest); if (ret == 0) { ret = update_device_latest_version(server_version); printf("Update was applied.\n"); } delete_motd(); /* Run any scripts that are needed to complete update */ run_scripts(); clean_exit: list_free_list(updates); free_manifest(current_manifest); free_manifest(server_manifest); clean_curl: signature_terminate(); swupd_curl_cleanup(); free_subscriptions(); free_globals(); v_lockfile(lock_fd); dump_file_descriptor_leaks(); if ((current_version < server_version) && (ret == 0)) { printf("Update successful. System updated from version %d to version %d\n", current_version, server_version); } else if (ret == 0) { printf("Update complete. System already up-to-date at version %d\n", current_version); } return ret; }
static void process_data(struct ieee80211_frame * wh, int len) { REQUIRE(wh != NULL); unsigned char * p = (unsigned char *) (wh + 1); struct llc * llc; int wep = wh->i_fc[1] & IEEE80211_FC1_WEP; int eapol = 0; struct client * c; int stype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; int orig = len; unsigned char *bssid, *clientaddr; struct network * n; len -= sizeof(*wh); if (stype == IEEE80211_FC0_SUBTYPE_QOS) { p += 2; len -= 2; } if (!wep && len >= 8) { llc = (struct llc *) p; eapol = memcmp(llc, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8) == 0; p += 8; len -= 8; } if (!eapol) return; if (len < 5) return; /* type == key */ if (p[1] != 0x03) return; /* desc == WPA or RSN */ if (p[4] != 0xFE && p[4] != 0x02) return; bssid = wh->i_addr1; clientaddr = wh->i_addr2; if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS) { bssid = wh->i_addr2; clientaddr = wh->i_addr1; } else if (!(wh->i_fc[1] & IEEE80211_FC1_DIR_TODS)) bssid = wh->i_addr3; /* IBSS */ n = find_add_net(bssid); if (n->n_handshake) return; c = find_add_client(n, clientaddr); process_eapol(n, c, p, len, wh, orig); if (n->n_handshake) check_network(n); }
static void process_beacon(struct ieee80211_frame * wh, int totlen) { REQUIRE(wh != NULL); unsigned char * p = (unsigned char *) (wh + 1); int bhlen = 8 + 2 + 2; int len = totlen; char ssid[256]; int wpa = 0; int rc; int ssids = 0; int hidden = 0; struct network * n; totlen -= sizeof(*wh); if (totlen < bhlen) goto __bad; if (!(IEEE80211_BEACON_CAPABILITY(p) & IEEE80211_CAPINFO_PRIVACY)) return; p += bhlen; totlen -= bhlen; ssid[0] = 0; while (totlen > 2) { int id = *p++; int l = *p++; totlen -= 2; if (totlen < l) goto __bad; switch (id) { case IEEE80211_ELEMID_SSID: if (++ssids > 1) break; if (l == 0 || p[0] == 0) hidden = 1; else { memcpy(ssid, p, l); ssid[l] = 0; } break; case IEEE80211_ELEMID_VENDOR: if ((rc = parse_elem_vendor(&p[-2], l + 2)) == -1) goto __bad; if (rc) wpa = 1; break; case IEEE80211_ELEMID_RSN: if ((rc = parse_rsn(p, l, 1)) == -1) goto __bad; if (rc) wpa = 1; break; } p += l; totlen -= l; } if (!wpa) return; n = find_add_net(wh->i_addr3); if (n->n_beaconlen) return; n->n_beaconlen = len; ALLEGE(n->n_beaconlen <= (int) sizeof(n->n_beacon)); memcpy(n->n_beacon, wh, n->n_beaconlen); strncpy(n->n_ssid, ssid, sizeof(n->n_ssid)); (n->n_ssid)[sizeof(n->n_ssid) - 1] = '\0'; check_network(n); return; __bad: printf("bad beacon\n"); }
/* This function does a simple verification of files listed in the * subscribed bundle manifests. If the optional "fix" or "install" parameter * is specified, the disk will be modified at each point during the * sequential comparison of manifest files to disk files, where the disk is * found to not match the manifest. This is notably different from update, * which attempts to atomically (or nearly atomically) activate a set of * pre-computed and validated staged changes as a group. */ int verify_main(int argc, char **argv) { struct manifest *official_manifest = NULL; int ret; int lock_fd; struct list *subs = NULL; copyright_header("software verify"); if (!parse_options(argc, argv)) { return EINVALID_OPTION; } /* parse command line options */ assert(argc >= 0); assert(argv != NULL); ret = swupd_init(&lock_fd); if (ret != 0) { printf("Failed verify initialization, exiting now.\n"); return ret; } /* Gather current manifests */ if (!version) { version = get_current_version(path_prefix); if (version < 0) { printf("Error: Unable to determine current OS version\n"); ret = ECURRENT_VERSION; goto clean_and_exit; } } if (version == -1) { version = get_latest_version(); if (version < 0) { printf("Unable to get latest version for install\n"); ret = EXIT_FAILURE; goto clean_and_exit; } } printf("Verifying version %i\n", version); if (!check_network()) { printf("Error: Network issue, unable to download manifest\n"); ret = ENOSWUPDSERVER; goto clean_and_exit; } read_subscriptions_alt(&subs); /* * FIXME: We need a command line option to override this in case the * certificate is hosed and the admin knows it and wants to recover. */ ret = rm_staging_dir_contents("download"); if (ret != 0) { printf("Failed to remove prior downloads, carrying on anyway\n"); } official_manifest = load_mom(version); if (!official_manifest) { /* This is hit when or if an OS version is specified for --fix which * is not available, or if there is a server error and a manifest is * not provided. */ printf("Unable to download/verify %d Manifest.MoM\n", version); ret = EMOM_NOTFOUND; /* No repair is possible without a manifest, nor is accurate reporting * of the state of the system. Therefore cleanup, report failure and exit */ goto clean_and_exit; } ret = add_included_manifests(official_manifest, &subs); if (ret) { ret = EMANIFEST_LOAD; goto clean_and_exit; } set_subscription_versions(official_manifest, NULL, &subs); official_manifest->submanifests = recurse_manifest(official_manifest, subs, NULL); if (!official_manifest->submanifests) { printf("Error: Cannot load MoM sub-manifests\n"); ret = ERECURSE_MANIFEST; goto clean_and_exit; } official_manifest->files = files_from_bundles(official_manifest->submanifests); official_manifest->files = consolidate_files(official_manifest->files); /* when fixing or installing we need input files. */ if (cmdline_option_fix || cmdline_option_install) { ret = get_required_files(official_manifest, subs); if (ret != 0) { ret = -ret; goto clean_and_exit; } } /* preparation work complete. */ /* * NOTHING ELSE IS ALLOWED TO FAIL/ABORT after this line. * This tool is there to recover a nearly-bricked system. Aborting * from this point forward, for any reason, will result in a bricked system. * * I don't care what your static analysis tools says * I don't care what valgrind tells you * * There shall be no "goto fail;" from this point on. * * *** THE SHOW MUST GO ON *** */ if (cmdline_option_fix || cmdline_option_install) { /* * Next put the files in place that are missing completely. * This is to avoid updating a symlink to a library before the new full file * is already there. It's also the most safe operation, adding files rarely * has unintended side effect. So lets do the safest thing first. */ printf("Adding any missing files\n"); add_missing_files(official_manifest); } if (cmdline_option_quick) { /* quick only replaces missing files, so it is done here */ goto brick_the_system_and_clean_curl; } if (cmdline_option_fix) { bool repair = true; printf("Fixing modified files\n"); deal_with_hash_mismatches(official_manifest, repair); /* removing files could be risky, so only do it if the * prior phases had no problems */ if ((file_not_fixed_count == 0) && (file_not_replaced_count == 0)) { remove_orphaned_files(official_manifest); } } else { bool repair = false; printf("Verifying files\n"); deal_with_hash_mismatches(official_manifest, repair); } free_manifest(official_manifest); brick_the_system_and_clean_curl: /* clean up */ /* * naming convention: All exit goto labels must follow the "brick_the_system_and_FOO:" pattern */ /* report a summary of what we managed to do and not do */ printf("Inspected %i files\n", file_checked_count); if (cmdline_option_fix || cmdline_option_install) { printf(" %i files were missing\n", file_missing_count); if (file_missing_count) { printf(" %i of %i missing files were replaced\n", file_replaced_count, file_missing_count); printf(" %i of %i missing files were not replaced\n", file_not_replaced_count, file_missing_count); } } if (!cmdline_option_quick && file_mismatch_count > 0) { printf(" %i files did not match\n", file_mismatch_count); if (cmdline_option_fix) { printf(" %i of %i files were fixed\n", file_fixed_count, file_mismatch_count); printf(" %i of %i files were not fixed\n", file_not_fixed_count, file_mismatch_count); } } if ((file_not_fixed_count == 0) && (file_not_replaced_count == 0) && cmdline_option_fix && !cmdline_option_quick) { printf(" %i files found which should be deleted\n", file_extraneous_count); if (file_extraneous_count) { printf(" %i of %i files were deleted\n", file_deleted_count, file_extraneous_count); printf(" %i of %i files were not deleted\n", file_not_deleted_count, file_extraneous_count); } } if (cmdline_option_fix || cmdline_option_install) { // always run in a fix or install case need_update_boot = true; need_update_bootloader = true; run_scripts(); } sync(); if ((file_not_fixed_count == 0) && (file_not_replaced_count == 0) && (file_not_deleted_count == 0)) { ret = EXIT_SUCCESS; } else { ret = EXIT_FAILURE; } /* this concludes the critical section, after this point it's clean up time, the disk content is finished and final */ clean_and_exit: telemetry(ret ? TELEMETRY_CRIT : TELEMETRY_INFO, "verify", "fix=%d\nret=%d\n" "current_version=%d\n" "file_replaced_count=%d\n" "file_not_replaced_count=%d\n" "file_missing_count=%d\n" "file_fixed_count=%d\n" "file_not_fixed_count=%d\n" "file_deleted_count=%d\n" "file_not_deleted_count=%d\n" "file_mismatch_count=%d\n" "file_extraneous_count=%d\n", cmdline_option_fix || cmdline_option_install, ret, version, file_replaced_count, file_not_replaced_count, file_missing_count, file_fixed_count, file_not_fixed_count, file_deleted_count, file_not_deleted_count, file_mismatch_count, file_extraneous_count); if (ret == EXIT_SUCCESS) { if (cmdline_option_fix || cmdline_option_install) { printf("Fix successful\n"); } else { /* This is just a verification */ printf("Verify successful\n"); } } else { if (cmdline_option_fix || cmdline_option_install) { printf("Error: Fix did not fully succeed\n"); } else { /* This is just a verification */ printf("Error: Verify did not fully succeed\n"); } } swupd_deinit(lock_fd, &subs); return ret; }