From: Andreas Steffen Date: Fri, 21 Jun 2013 12:15:18 +0000 (+0200) Subject: Implemented pacman in a more reliable way X-Git-Tag: 5.1.0dr1~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45eb318ed4f516503aa418d21df182c3a81dc4e3;p=thirdparty%2Fstrongswan.git Implemented pacman in a more reliable way --- diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql index dcc4e75d1c..46e0c44c85 100644 --- a/src/libimcv/imv/data.sql +++ b/src/libimcv/imv/data.sql @@ -3,61 +3,61 @@ INSERT INTO products ( /* 1 */ name ) VALUES ( - 'Debian 7.0' + 'Debian 6.0 i686' ); INSERT INTO products ( /* 2 */ name ) VALUES ( - 'Debian 7.0 i686' + 'Debian 6.0 x86_64' ); INSERT INTO products ( /* 3 */ name ) VALUES ( - 'Debian 7.0 x86_64' + 'Debian 7.0 i686' ); INSERT INTO products ( /* 4 */ name ) VALUES ( - 'Ubuntu 10.04' + 'Debian 7.0 x86_64' ); INSERT INTO products ( /* 5 */ name ) VALUES ( - 'Ubuntu 10.04 i686' + 'Debian 8.0 i686' ); INSERT INTO products ( /* 6 */ name ) VALUES ( - 'Ubuntu 10.04 x86_64' + 'Debian 8.0 x86_64' ); INSERT INTO products ( /* 7 */ name ) VALUES ( - 'Ubuntu 10.10' + 'Ubuntu 10.04 i686' ); INSERT INTO products ( /* 8 */ name ) VALUES ( - 'Ubuntu 10.10 i686' + 'Ubuntu 10.04 x86_64' ); INSERT INTO products ( /* 9 */ name ) VALUES ( - 'Ubuntu 10.10 x86_64' + 'Ubuntu 10.10 i686' ); INSERT INTO products ( /* 10 */ name ) VALUES ( - 'Ubuntu 11.04' + 'Ubuntu 10.10 x86_64' ); INSERT INTO products ( /* 11 */ @@ -74,83 +74,59 @@ INSERT INTO products ( /* 12 */ INSERT INTO products ( /* 13 */ name -) VALUES ( - 'Ubuntu 11.10' -); - -INSERT INTO products ( /* 14 */ - name ) VALUES ( 'Ubuntu 11.10 i686' ); -INSERT INTO products ( /* 15 */ +INSERT INTO products ( /* 14 */ name ) VALUES ( 'Ubuntu 11.10 x86_64' ); -INSERT INTO products ( /* 16 */ - name -) VALUES ( - 'Ubuntu 12.04' -); - -INSERT INTO products ( /* 17 */ +INSERT INTO products ( /* 15 */ name ) VALUES ( 'Ubuntu 12.04 i686' ); -INSERT INTO products ( /* 18 */ +INSERT INTO products ( /* 16 */ name ) VALUES ( 'Ubuntu 12.04 x86_64' ); -INSERT INTO products ( /* 19 */ - name -) VALUES ( - 'Ubuntu 12.10' -); - -INSERT INTO products ( /* 20 */ +INSERT INTO products ( /* 17 */ name ) VALUES ( 'Ubuntu 12.10 i686' ); -INSERT INTO products ( /* 21 */ +INSERT INTO products ( /* 18 */ name ) VALUES ( 'Ubuntu 12.10 x86_64' ); -INSERT INTO products ( /* 22 */ - name -) VALUES ( - 'Ubuntu 13.04' -); - -INSERT INTO products ( /* 23 */ +INSERT INTO products ( /* 19 */ name ) VALUES ( 'Ubuntu 13.04 i686' ); -INSERT INTO products ( /* 24 */ +INSERT INTO products ( /* 20 */ name ) VALUES ( 'Ubuntu 13.04 x86_64' ); -INSERT INTO products ( /* 25 */ +INSERT INTO products ( /* 21 */ name ) VALUES ( 'Android 4.1.1' ); -INSERT INTO products ( /* 26 */ +INSERT INTO products ( /* 22 */ name ) VALUES ( 'Android 4.2.1' @@ -299,109 +275,109 @@ INSERT INTO algorithms ( INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 2, 32768, X'6c6f8e12f6cbfba612e780374c4cdcd40f20968a' + 4, 2, 32768, X'6c6f8e12f6cbfba612e780374c4cdcd40f20968a' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 2, 16384, X'dbcecd19d59310183cf5c31ddee29e8d7bec64d3f9583aad074330a1b3024b07' + 4, 2, 16384, X'dbcecd19d59310183cf5c31ddee29e8d7bec64d3f9583aad074330a1b3024b07' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 2, 8192, X'197c5385e5853003188833d4f991136c1b0875fa416a60b1159f64e57e457b3184762c884a802a2bda194c058e3bd953' + 4, 2, 8192, X'197c5385e5853003188833d4f991136c1b0875fa416a60b1159f64e57e457b3184762c884a802a2bda194c058e3bd953' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 4, 32768, X'3ad204f99eb7262efab79cfca02628870ea76361' + 4, 4, 32768, X'3ad204f99eb7262efab79cfca02628870ea76361' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 4, 16384, X'3a2170aad92fdd58b55e0e199822bc873cf587b2d1eb1ed7ed8dcea97ae86376' + 4, 4, 16384, X'3a2170aad92fdd58b55e0e199822bc873cf587b2d1eb1ed7ed8dcea97ae86376' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 4, 8192, X'f778076baa876b5e4b502494a3db081fb09dd870dee6991d54104a74b7e009c58fe261db5ffd13c11e08ef0cefcfa59f' + 4, 4, 8192, X'f778076baa876b5e4b502494a3db081fb09dd870dee6991d54104a74b7e009c58fe261db5ffd13c11e08ef0cefcfa59f' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 5, 32768, X'ecd9c7076cc0572724c7a67db7f19c2831e0445f' + 4, 5, 32768, X'ecd9c7076cc0572724c7a67db7f19c2831e0445f' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 5, 16384, X'28f3ea5afd34444c8232ea75003131e294a0c9b847de300e4b205d38c1a41305' + 4, 5, 16384, X'28f3ea5afd34444c8232ea75003131e294a0c9b847de300e4b205d38c1a41305' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 3, 5, 8192, X'51921a8b9322f2d3f06d55002ff40a79da67e70cb563b2a50977642d603dfac2ccbb68b3d32a8bb350769b75d6254208' + 4, 5, 8192, X'51921a8b9322f2d3f06d55002ff40a79da67e70cb563b2a50977642d603dfac2ccbb68b3d32a8bb350769b75d6254208' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 1, 32768, X'd9309b9e45928239d7a7b18711e690792632cce4' + 18, 1, 32768, X'd9309b9e45928239d7a7b18711e690792632cce4' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 1, 16384, X'dbfa1856d278d8707c4989b30dd065b4bcd309908f0f2e6e66ff2aa83ff93f59' + 18, 1, 16384, X'dbfa1856d278d8707c4989b30dd065b4bcd309908f0f2e6e66ff2aa83ff93f59' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 1, 8192, X'fb8d027f03bb5ebb47741ed247eb9e174127b714d20229885feb37e0979aeb14a1b74020cded891d680441093625729c' + 18, 1, 8192, X'fb8d027f03bb5ebb47741ed247eb9e174127b714d20229885feb37e0979aeb14a1b74020cded891d680441093625729c' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 3, 32768, X'3715f2f94016a91fab5bbc503f0f1d43c5a9fc2b' + 18, 3, 32768, X'3715f2f94016a91fab5bbc503f0f1d43c5a9fc2b' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 3, 16384, X'c03a5296b5decb87b01517f9927a8b2349dfb29ff9f5ba084f994c155ca5d4be' + 18, 3, 16384, X'c03a5296b5decb87b01517f9927a8b2349dfb29ff9f5ba084f994c155ca5d4be' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 3, 8192, X'b8bc345f56115235cc6091f61e312ce43ea54a5b99e7295002ae7b415fd35e06ec4c731ab70ad00d784bb53a318a2fa0' + 18, 3, 8192, X'b8bc345f56115235cc6091f61e312ce43ea54a5b99e7295002ae7b415fd35e06ec4c731ab70ad00d784bb53a318a2fa0' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 5, 32768, X'e59602f4edf24c1b36199588886d06665d4adcd7' + 18, 5, 32768, X'e59602f4edf24c1b36199588886d06665d4adcd7' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 5, 16384, X'090e1b77bda7fe665e498c6b5e09dbb7ddc5cfe57f213de48f4fb6736484f500' + 18, 5, 16384, X'090e1b77bda7fe665e498c6b5e09dbb7ddc5cfe57f213de48f4fb6736484f500' ); INSERT INTO file_hashes ( product, file, algo, hash ) VALUES ( - 21, 5, 8192, X'7cbdb4612a13443dba910ecdef5161f2213e52c9b4a2eef14bcee5d287e9df931cd022e9e9715518ad9c9b6e3384a668' + 18, 5, 8192, X'7cbdb4612a13443dba910ecdef5161f2213e52c9b4a2eef14bcee5d287e9df931cd022e9e9715518ad9c9b6e3384a668' ); /* Packages */ @@ -485,155 +461,180 @@ INSERT INTO components ( /* Groups */ INSERT INTO groups ( /* 1 */ - name, parent + name ) VALUES ( - 'Debian i686', 6 + 'Default' ); INSERT INTO groups ( /* 2 */ name, parent ) VALUES ( - 'Debian x86_64', 6 + 'Linux', 1 ); INSERT INTO groups ( /* 3 */ name, parent ) VALUES ( - 'Ubuntu i686', 6 + 'Android', 1 ); INSERT INTO groups ( /* 4 */ name, parent ) VALUES ( - 'Ubuntu x86_64', 6 + 'Debian i686', 2 ); INSERT INTO groups ( /* 5 */ name, parent ) VALUES ( - 'Android', 7 + 'Debian x86_64', 2 ); INSERT INTO groups ( /* 6 */ name, parent ) VALUES ( - 'Linux', 7 + 'Ubuntu i686', 2 ); INSERT INTO groups ( /* 7 */ - name + name, parent ) VALUES ( - 'Default' + 'Ubuntu x86_64', 2 ); + /* Default Product Groups */ INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 1, 2 + 4, 1 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 4, 3 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 4, 5 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 5, 2 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 5, 4 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 2, 3 + 5, 6 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 3, 5 + 6, 7 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 3, 8 + 6, 9 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 3, 11 + 6, 11 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 3, 14 + 6, 13 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 3, 17 + 6, 15 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 3, 20 + 6, 17 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 3, 23 + 6, 19 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 4, 6 + 7, 8 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 4, 9 + 7, 10 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 4, 12 + 7, 12 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 4, 15 + 7, 14 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 4, 18 + 7, 16 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 4, 21 + 7, 18 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 4, 24 + 7, 20 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 5, 25 + 3, 21 ); INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( - 5, 26 + 3, 22 ); /* Policies */ diff --git a/src/libimcv/plugins/imv_os/imv_os_database.c b/src/libimcv/plugins/imv_os/imv_os_database.c index c7f9b6be1b..a4cc015ec0 100644 --- a/src/libimcv/plugins/imv_os/imv_os_database.c +++ b/src/libimcv/plugins/imv_os/imv_os_database.c @@ -44,10 +44,8 @@ METHOD(imv_os_database_t, check_packages, status_t, enumerator_t *package_enumerator) { char *product, *package, *release, *cur_release; - u_char *pos; - chunk_t os_name, os_version, name, version; + chunk_t name, version; os_type_t os_type; - size_t os_version_len; os_package_state_t package_state; int pid, gid; int count = 0, count_ok = 0, count_no_match = 0, count_blacklist = 0; @@ -55,21 +53,12 @@ METHOD(imv_os_database_t, check_packages, status_t, status_t status = SUCCESS; bool found, match; - state->get_info(state, &os_type, &os_name, &os_version); + product = state->get_info(state, &os_type, NULL, NULL); if (os_type == OS_TYPE_ANDROID) { /*no package dependency on Android version */ - product = strdup(enum_to_name(os_type_names, os_type)); - } - else - { - /* remove appended platform info */ - pos = memchr(os_version.ptr, ' ', os_version.len); - os_version_len = pos ? (pos - os_version.ptr) : os_version.len; - product = malloc(os_name.len + 1 + os_version_len + 1); - sprintf(product, "%.*s %.*s", (int)os_name.len, os_name.ptr, - (int)os_version_len, os_version.ptr); + product = enum_to_name(os_type_names, os_type); } DBG1(DBG_IMV, "processing installed '%s' packages", product); @@ -79,13 +68,10 @@ METHOD(imv_os_database_t, check_packages, status_t, DB_TEXT, product, DB_INT); if (!e) { - free(product); - return FAILED; } if (!e->enumerate(e, &pid)) { e->destroy(e); - free(product); return NOT_FOUND; } e->destroy(e); @@ -102,7 +88,6 @@ METHOD(imv_os_database_t, check_packages, status_t, DB_TEXT, package, DB_INT); if (!e) { - free(product); free(package); return FAILED; } @@ -130,7 +115,6 @@ METHOD(imv_os_database_t, check_packages, status_t, DB_INT, pid, DB_INT, gid, DB_TEXT, DB_INT); if (!e) { - free(product); free(package); free(release); return FAILED; @@ -181,7 +165,6 @@ METHOD(imv_os_database_t, check_packages, status_t, free(package); free(release); } - free(product); state->set_count(state, count, count_no_match, count_blacklist, count_ok); return status; diff --git a/src/libimcv/plugins/imv_os/pacman.c b/src/libimcv/plugins/imv_os/pacman.c index 25e63760bd..f8922bfd43 100644 --- a/src/libimcv/plugins/imv_os/pacman.c +++ b/src/libimcv/plugins/imv_os/pacman.c @@ -21,12 +21,33 @@ #include #include #include +#include #include "imv_os_state.h" #include #include +typedef enum pacman_state_t pacman_state_t; + +enum pacman_state_t { + PACMAN_STATE_BEGIN_PACKAGE, + PACMAN_STATE_VERSION, + PACMAN_STATE_END_PACKAGE +}; + +typedef struct stats_t stats_t; + +struct stats_t { + time_t release; + int product; + int packages; + int new_packages; + int new_versions; + int updated_versions; + int deleted_versions; +}; + /** * global debug output variables */ @@ -88,54 +109,192 @@ static void usage(void) } /** - * Extract the time the package file was generated + * Update the package database */ -static time_t extract_time(char *line) +static bool update_database(database_t *db, char *package, char *version, + bool security, stats_t *stats) { - struct tm t; - char wday[4], mon[4]; - char* months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - int i; - - if (sscanf(line, "Generated: %3s %3s %2d %2d:%2d:%2d %4d UTC", wday, mon, - &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) != 7) + char *cur_version, *version_update = NULL, *version_delete = NULL; + int cur_security, security_update = 0, security_delete = 0; + int pac_id = 0, vid = 0, vid_update = 0, vid_delete = 0; + u_int cur_time; + bool add_version = TRUE; + enumerator_t *e; + + /* increment package count */ + stats->packages++; + + /* check if package is already in database */ + e = db->query(db, "SELECT id FROM packages WHERE name = ?", + DB_TEXT, package, DB_INT); + if (!e) + { + return FALSE; + } + if (!e->enumerate(e, &pac_id)) + { + pac_id = 0; + } + e->destroy(e); + + if (!pac_id && security) + { + if (db->execute(db, &pac_id, "INSERT INTO packages (name) VALUES (?)", + DB_TEXT, package) != 1) + { + fprintf(stderr, "could not store package '%s' to database\n", + package); + return FALSE; + } + stats->new_packages++; + } + + /* check for package versions already in database */ + e = db->query(db, + "SELECT id, release, security, time FROM versions " + "WHERE package = ? AND product = ?", DB_INT, pac_id, + DB_INT, stats->product, DB_INT, DB_TEXT, DB_INT, DB_UINT); + if (!e) { - return UNDEFINED_TIME; + return FALSE; } - t.tm_isdst = 0; - t.tm_year -= 1900; - t.tm_mon = 12; - for (i = 0; i < countof(months); i++) + while (e->enumerate(e, &vid, &cur_version, &cur_security, &cur_time)) { - if (streq(mon, months[i])) + if (streq(version, cur_version)) { - t.tm_mon = i; + /* already in data base */ + add_version = FALSE; break; } + else if (stats->release >= cur_time) + { + if (security) + { + if (cur_security) + { + vid_update = vid; + version_update = strdup(cur_version); + security_update = cur_security; + } + else + { + vid_delete = vid; + version_delete = strdup(cur_version); + security_delete = cur_security; + } + } + else + { + if (!cur_security) + { + vid_update = vid; + version_update = strdup(cur_version); + security_update = cur_security; + } + } + } + else + { + if (security == cur_security) + { + add_version = FALSE; + } + } + } + e->destroy(e); + + if ((!vid && !security) || (vid && !add_version)) + { + free(version_update); + free(version_delete); + return TRUE; + } + + if ((!vid && security) || (vid && !vid_update)) + { + printf("%s (%s) %s\n", package, version, security ? "[s]" : ""); + + if (db->execute(db, &vid, + "INSERT INTO versions " + "(package, product, release, security, time) " + "VALUES (?, ?, ?, ?, ?)", DB_INT, pac_id, DB_INT, stats->product, + DB_TEXT, version, DB_INT, security, DB_INT, stats->release) != 1) + { + fprintf(stderr, "could not store version '%s' to database\n", + version); + free(version_update); + free(version_delete); + return FALSE; + } + stats->new_versions++; } - if (t.tm_mon == 12) + else { - return UNDEFINED_TIME; + printf("%s (%s) %s updated by\n", + package, version_update, security_update ? "[s]" : ""); + printf("%s (%s) %s\n", package, version, security ? "[s]" : ""); + + if (db->execute(db, NULL, + "UPDATE versions SET release = ?, time = ? WHERE id = ?", + DB_TEXT, version, DB_INT, stats->release, DB_INT, vid_update) <= 0) + { + fprintf(stderr, "could not update version '%s' to database\n", + version); + free(version_update); + free(version_delete); + return FALSE; + } + stats->updated_versions++; } - return mktime(&t) - timezone; + if (vid_delete) + { + printf("%s (%s) %s deleted\n", + package, version_delete, security_delete ? "[s]" : ""); + if (db->execute(db, NULL, + "DELETE FROM versions WHERE id = ?", + DB_INT, vid_delete) <= 0) + { + fprintf(stderr, "could not delete version '%s' from database\n", + version_delete); + free(version_update); + free(version_delete); + return FALSE; + } + stats->deleted_versions++; + } + free(version_update); + free(version_delete); + + return TRUE; } /** * Process a package file and store updates in the database */ -static void process_packages(char *filename, char *product, bool update) +static void process_packages(char *filename, char *product, bool security) { - char *uri, line[12288], *pos; - int count = 0, errored = 0, vulnerable = 0, new_packages = 0; - int new_versions = 0, updated_versions = 0, deleted_versions = 0; - time_t gen_time; - u_int32_t pid = 0; + char *uri, line[BUF_LEN], *pos, *package = NULL, *version = NULL; + pacman_state_t pacman_state; enumerator_t *e; database_t *db; + int pid; FILE *file; + struct stat st; + stats_t stats; + bool success; + + /* initialize statistics */ + memset(&stats, 0x00, sizeof(stats_t)); + + /* getting creation date of package file */ + if (stat(filename, &st)) + { + fprintf(stderr, "unable to obtain creation date on '%s'", filename); + exit(EXIT_FAILURE); + } + stats.release = st.st_mtime; /* opening package file */ printf("loading\"%s\"\n", filename); @@ -167,13 +326,13 @@ static void process_packages(char *filename, char *product, bool update) DB_TEXT, product, DB_INT); if (e) { - if (!e->enumerate(e, &pid)) + if (e->enumerate(e, &pid)) { - pid = 0; + stats.product = pid; } e->destroy(e); } - if (!pid) + if (!stats.product) { if (db->execute(db, &pid, "INSERT INTO products (name) VALUES (?)", DB_TEXT, product) != 1) @@ -184,248 +343,78 @@ static void process_packages(char *filename, char *product, bool update) db->destroy(db); exit(EXIT_FAILURE); } + stats.product = pid; } + pacman_state = PACMAN_STATE_BEGIN_PACKAGE; + while (fgets(line, sizeof(line), file)) { - char *package, *version; - char *cur_version, *version_update = NULL, *version_delete = NULL; - bool security, add_version = TRUE; - int cur_security, security_update = 0, security_delete = 0; - u_int32_t gid = 0, vid = 0, vid_update = 0, vid_delete = 0; - time_t cur_time; - - count++; - if (count == 1) - { - printf("%s", line); - } - if (count == 3) - { - gen_time = extract_time(line); + /* set read pointer to beginning of line */ + pos = line; - if (gen_time == UNDEFINED_TIME) - { - fprintf(stderr, "could not extract generation time\n"); - fclose(file); - db->destroy(db); - exit(EXIT_FAILURE); - } - printf("Generated: %T\n", &gen_time, TRUE); - } - if (count < 7) + switch (pacman_state) { - continue; - } - - /* look for the package name */ - pos = strchr(line, ' '); - if (!pos) - { - fprintf(stderr, "could not extract package name from '%.*s'\n", - (int)(strlen(line)-1), line); - errored++; - continue; - } - *pos++ = '\0'; - package = line; - - /* look for version string in parentheses */ - if (*pos == '(') - { - version = ++pos; - pos = strchr(pos, ')'); - if (pos) - { - *pos++ = '\0'; - } - else - { - fprintf(stderr, "could not extract package version from " - "'%.*s'\n", (int)(strlen(line)-1), line); - errored++; - continue; - } - } - else - { - /* no version information, skip entry */ - continue; - } - security = (strstr(pos, "[security]") != NULL); - if (security) - { - vulnerable++; - } - - /* handle non-security packages in update mode only */ - if (!update && !security) - { - continue; - } - - /* check if package is already in database */ - e = db->query(db, "SELECT id FROM packages WHERE name = ?", - DB_TEXT, package, DB_INT); - if (e) - { - if (!e->enumerate(e, &gid)) - { - gid = 0; - } - e->destroy(e); - } - if (!gid && security) - { - if (db->execute(db, &gid, "INSERT INTO packages (name) VALUES (?)", - DB_TEXT, package) != 1) - { - fprintf(stderr, "could not store package '%s' to database\n", - package); - fclose(file); - db->destroy(db); - exit(EXIT_FAILURE); - } - new_packages++; - } - - /* check for package versions already in database */ - e = db->query(db, - "SELECT id, release, security, time FROM versions " - "WHERE package = ? AND product = ?", - DB_INT, gid, DB_INT, pid, DB_INT, DB_TEXT, DB_INT, DB_INT); - if (!e) - { - break; - } - while (e->enumerate(e, &vid, &cur_version, &cur_security, &cur_time)) - { - if (streq(version, cur_version)) - { - /* already in data base */ - add_version = FALSE; + case PACMAN_STATE_BEGIN_PACKAGE: + pos = strstr(pos, "Package: "); + if (!pos) + { + continue; + } + pos += 9; + package = pos; + pos = strchr(pos, '\n'); + if (pos) + { + package = strndup(package, pos - package); + pacman_state = PACMAN_STATE_VERSION; + } break; - } - else if (gen_time > cur_time) - { - if (security) + case PACMAN_STATE_VERSION: + pos = strstr(pos, "Version: "); + if (!pos) { - if (cur_security) - { - vid_update = vid; - version_update = strdup(cur_version); - security_update = cur_security; - } - else - { - vid_delete = vid; - version_delete = strdup(cur_version); - security_delete = cur_security; - } + continue; } - else + pos += 9; + version = pos; + pos = strchr(pos, '\n'); + if (pos) { - if (!cur_security) - { - vid_update = vid; - version_update = strdup(cur_version); - security_update = cur_security; - } + version = strndup(version, pos - version); + pacman_state = PACMAN_STATE_END_PACKAGE; } - } - else - { - if (security == cur_security) + break; + case PACMAN_STATE_END_PACKAGE: + if (*pos != '\n') { - add_version = FALSE; + continue; } - } - } - e->destroy(e); - - if ((!vid && !security) || (vid && !add_version)) - { - free(version_update); - free(version_delete); - continue; - } - - if ((!vid && security) || (vid && !vid_update)) - { - printf("%s (%s) %s\n", package, version, security ? "[s]" : ""); - - if (db->execute(db, &vid, - "INSERT INTO versions " - "(package, product, release, security, time) " - "VALUES (?, ?, ?, ?, ?)", DB_INT, gid, DB_INT, pid, - DB_TEXT, version, DB_INT, security, DB_INT, gen_time) != 1) - { - fprintf(stderr, "could not store version '%s' to database\n", - version); - free(version_update); - free(version_delete); - fclose(file); - db->destroy(db); - exit(EXIT_FAILURE); - } - new_versions++; - } - else - { - printf("%s (%s) %s updated by\n", - package, version_update, security_update ? "[s]" : ""); - printf("%s (%s) %s\n", package, version, security ? "[s]" : ""); - - if (db->execute(db, NULL, - "UPDATE versions SET release = ?, time = ? WHERE id = ?", - DB_TEXT, version, DB_INT, gen_time, DB_INT, vid_update) <= 0) - { - fprintf(stderr, "could not update version '%s' to database\n", - version); - free(version_update); - free(version_delete); - fclose(file); - db->destroy(db); - exit(EXIT_FAILURE); - } - updated_versions++; - } - - if (vid_delete) - { - printf("%s (%s) %s deleted\n", - package, version_delete, security_delete ? "[s]" : ""); - - if (db->execute(db, NULL, - "DELETE FROM versions WHERE id = ?", - DB_INT, vid_delete) <= 0) - { - fprintf(stderr, "could not delete version '%s' from database\n", - version_delete); - free(version_update); - free(version_delete); - fclose(file); - db->destroy(db); - exit(EXIT_FAILURE); - } - deleted_versions++; + success = update_database(db, package, version, security, &stats); + free(package); + free(version); + if (!success) + { + fclose(file); + db->destroy(db); + exit(EXIT_FAILURE); + } + pacman_state = PACMAN_STATE_BEGIN_PACKAGE; } - free(version_update); - free(version_delete); } fclose(file); db->destroy(db); - printf("processed %d packages, %d security, %d new packages, " - "%d new versions, %d updated versions, %d deleted versions, " - "%d errored\n", count - 6, vulnerable, new_packages, new_versions, - updated_versions, deleted_versions, errored); + printf("processed %d packages, %d new packages, %d new versions, " + "%d updated versions, %d deleted versions\n", + stats.packages, stats.new_packages, stats.new_versions, + stats.updated_versions, stats.deleted_versions); } static void do_args(int argc, char *argv[]) { char *filename = NULL, *product = NULL; - bool update = FALSE; + bool security = FALSE; /* reinit getopt state */ optind = 0; @@ -438,7 +427,7 @@ static void do_args(int argc, char *argv[]) { "help", no_argument, NULL, 'h' }, { "file", required_argument, NULL, 'f' }, { "product", required_argument, NULL, 'p' }, - { "update", no_argument, NULL, 'u' }, + { "security", no_argument, NULL, 's' }, { 0,0,0,0 } }; @@ -456,8 +445,8 @@ static void do_args(int argc, char *argv[]) case 'p': product = optarg; continue; - case 'u': - update = TRUE; + case 's': + security = TRUE; continue; } break; @@ -465,7 +454,7 @@ static void do_args(int argc, char *argv[]) if (filename && product) { - process_packages(filename, product, update); + process_packages(filename, product, security); } else { diff --git a/src/libimcv/plugins/imv_os/pacman.sh b/src/libimcv/plugins/imv_os/pacman.sh index e9134ea5d5..af66c9489a 100755 --- a/src/libimcv/plugins/imv_os/pacman.sh +++ b/src/libimcv/plugins/imv_os/pacman.sh @@ -1,40 +1,158 @@ #!/bin/sh -DATE=`date +%Y%m%d` -DEBIAN=http://packages.debian.org -UBUNTU=http://packages.ubuntu.com -UBUNTU_VERSIONS="quantal precise oneiric lucid" -PACKAGES=allpackages?format=txt.gz +DATE=`date +%Y%m%d-%H%M` +UBUNTU="http://security.ubuntu.com/ubuntu/dists" +UBUNTU_VERSIONS="raring quantal precise lucid" +UBUNTU_DIRS="main multiverse restricted universe" +UBUNTU_ARCH="binary-amd64 binary-i386" +DEBIAN="http://security.debian.org/dists" +DEBIAN_VERSIONS="jessie wheezy squeeze" +DEBIAN_DIRS="main contrib non-free" +DEBIAN_ARCH="binary-amd64 binary-i386" PACMAN=/usr/libexec/ipsec/pacman DIR=/etc/pts -cd $DIR +cd $DIR/dists for v in $UBUNTU_VERSIONS do - wget $UBUNTU/$v/$PACKAGES -O $DATE-$v.txt.gz - wget $UBUNTU/$v-updates/$PACKAGES -O $DATE-$v-updates.txt.gz + for a in $UBUNTU_ARCH + do + mkdir -p $v-security/$a $v-updates/$a + for d in $UBUNTU_DIRS + do + wget $UBUNTU/$v-security/$d/$a/Packages.bz2 -O $v-security/$a/Packages-$d.bz2 + wget $UBUNTU/$v-updates/$d/$a/Packages.bz2 -O $v-updates/$a/Packages-$d.bz2 + done + bunzip2 -f $v-security/$a/*.bz2 $v-updates/$a/*.bz2 + done done -wget $DEBIAN/stable/$PACKAGES -O $DATE-squeeze.txt.gz -gunzip *.gz +for v in $DEBIAN_VERSIONS +do + for a in $DEBIAN_ARCH + do + mkdir -p $v-updates/$a + for d in $DEBIAN_DIRS + do + wget $DEBIAN/$v/updates/$d/$a/Packages.bz2 -O $v-updates/$a/Packages-$d.bz2 + done + bunzip2 -f $v-updates/$a/*.bz2 + done +done + +for f in raring-security/binary-amd64/* +do + $PACMAN --product "Ubuntu 13.04 x86_64" --file $f --security +done +echo +for f in raring-updates/binary-amd64/* +do + $PACMAN --product "Ubuntu 13.04 x86_64" --file $f +done +echo +for f in raring-security/binary-i386/* +do + $PACMAN --product "Ubuntu 13.04 i686" --file $f --security +done +echo +for f in raring-updates/binary-i386/* +do + $PACMAN --product "Ubuntu 13.04 i686" --file $f +done +echo -$PACMAN --product "Ubuntu 12.10" --file $DATE-quantal.txt +for f in quantal-security/binary-amd64/* +do + $PACMAN --product "Ubuntu 12.10 x86_64" --file $f --security +done echo -$PACMAN --product "Ubuntu 12.10" --file $DATE-quantal-updates.txt --update +for f in quantal-updates/binary-amd64/* +do + $PACMAN --product "Ubuntu 12.10 x86_64" --file $f +done echo -$PACMAN --product "Ubuntu 12.04" --file $DATE-precise.txt +for f in quantal-security/binary-i386/* +do + $PACMAN --product "Ubuntu 12.10 i686" --file $f --security +done echo -$PACMAN --product "Ubuntu 12.04" --file $DATE-precise-updates.txt --update +for f in quantal-updates/binary-i386/* +do + $PACMAN --product "Ubuntu 12.10 i686" --file $f +done echo -$PACMAN --product "Ubuntu 11.10" --file $DATE-oneiric.txt + +for f in precise-security/binary-amd64/* +do + $PACMAN --product "Ubuntu 12.04 x86_64" --file $f --security +done echo -$PACMAN --product "Ubuntu 11.10" --file $DATE-oneiric-updates.txt --update +for f in precise-updates/binary-amd64/* +do + $PACMAN --product "Ubuntu 12.04 x86_64" --file $f +done echo -$PACMAN --product "Ubuntu 10.04" --file $DATE-lucid.txt +for f in precise-security/binary-i386/* +do + $PACMAN --product "Ubuntu 12.04 i686" --file $f --security +done echo -$PACMAN --product "Ubuntu 10.04" --file $DATE-lucid-updates.txt --update +for f in precise-updates/binary-i386/* +do + $PACMAN --product "Ubuntu 12.04 i686" --file $f +done echo -$PACMAN --product "Debian squeeze" --file $DATE-squeeze.txt -cp config.db config.db-$DATE +for f in lucid-security/binary-amd64/* +do + $PACMAN --product "Ubuntu 10.04 x86_64" --file $f --security +done +echo +for f in lucid-updates/binary-amd64/* +do + $PACMAN --product "Ubuntu 10.04 x86_64" --file $f +done +echo +for f in lucid-security/binary-i386/* +do + $PACMAN --product "Ubuntu 10.04 i686" --file $f --security +done +echo +for f in lucid-updates/binary-i386/* +do + $PACMAN --product "Ubuntu 10.04 i686" --file $f +done +echo + +for f in jessie-updates/binary-amd64/* +do + $PACMAN --product "Debian 8.0 x86_64" --file $f --security +done +echo +for f in jessie-updates/binary-i386/* +do + $PACMAN --product "Debian 8.0 i686" --file $f --security +done + +for f in wheezy-updates/binary-amd64/* +do + $PACMAN --product "Debian 7.0 x86_64" --file $f --security +done +echo +for f in wheezy-updates/binary-i386/* +do + $PACMAN --product "Debian 7.0 i686" --file $f --security +done + +for f in squeeze-updates/binary-amd64/* +do + $PACMAN --product "Debian 6.0 x86_64" --file $f --security +done +echo +for f in squeeze-updates/binary-i386/* +do + $PACMAN --product "Debian 6.0 i686" --file $f --security +done + +cp $DIR/config.db $DIR/config.db-$DATE