From veillard at redhat.com Fri Sep 14 08:36:29 2012 From: veillard at redhat.com (Daniel Veillard) Date: Fri, 14 Sep 2012 16:36:29 +0800 Subject: [Libvirt-cim] [PATCH] fix id parsing with white space In-Reply-To: <1343979419-30227-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1343979419-30227-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <20120914083629.GX16500@redhat.com> On Fri, Aug 03, 2012 at 03:36:59PM +0800, Wenchao Xia wrote: > When device id string contains white space, parse is not correct. > This patch fix it > > Signed-off-by: Wenchao Xia > --- > libxkutil/device_parsing.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) ACK, pushed, but giving an example would be useful, I don't know any device with space in its name Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ From veillard at redhat.com Fri Sep 14 08:48:23 2012 From: veillard at redhat.com (Daniel Veillard) Date: Fri, 14 Sep 2012 16:48:23 +0800 Subject: [Libvirt-cim] [PATCH] provide a hack to borrow non-root ssh keys in migration In-Reply-To: <1345803509-13036-1-git-send-email-xiawenc@linux.vnet.ibm.com> References: <1345803509-13036-1-git-send-email-xiawenc@linux.vnet.ibm.com> Message-ID: <20120914084822.GY16500@redhat.com> On Fri, Aug 24, 2012 at 06:18:29PM +0800, Wenchao Xia wrote: > This patch allow libvirt-cim to use non-root's ssh key, avoid > using root's key to avoid exposing root's ssh login. Because libvirt-cim > runs in root mode so it is hard to satisfy some server security rules > especially about root's ssh key exposing. This is a walk around to improve > it. This has serious security implications, so I think this really must be documented in a very clear way: - how do you allow another key - how do you tell which one to pick, where and who can set this up - there is a copy done, it's hard to tell from which soure to which destination based just on code review - does that work with SELinux turned on ? As is it's very hard to review the code to give an ACK, > Signed-off-by: Wenchao Xia > --- > src/Virt_VSMigrationService.c | 96 +++++++++++++++++++++++++++++++++++++++-- > 1 files changed, 92 insertions(+), 4 deletions(-) > > diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c > index 76e3d25..55442ee 100644 > --- a/src/Virt_VSMigrationService.c > +++ b/src/Virt_VSMigrationService.c > @@ -150,6 +150,7 @@ static CMPIStatus get_migration_uri(CMPIInstance *msd, > > static char *dest_uri(const char *cn, > const char *dest, > + const char *dest_params, > uint16_t transport) > { > const char *prefix; > @@ -157,6 +158,7 @@ static char *dest_uri(const char *cn, > const char *param = ""; > char *uri = NULL; > int rc; > + int param_labeled = 0; > > if (STARTS_WITH(cn, "Xen")) > prefix = "xen"; > @@ -197,16 +199,75 @@ static char *dest_uri(const char *cn, > goto out; > } > > - if (!STREQC(param, "")) > + if (!STREQC(param, "")) { > rc = asprintf(&uri, "%s/%s", uri, param); > + param_labeled = 1; > + } > > - if (rc == -1) > + if (rc == -1) { > uri = NULL; > + goto out; > + } > > + if (dest_params) { > + if (param_labeled == 0) { > + rc = asprintf(&uri, "%s?%s", uri, dest_params); > + } else { > + rc = asprintf(&uri, "%s%s", uri, dest_params); > + } > + if (rc == -1) { > + uri = NULL; > + goto out; > + } > + } > out: > return uri; > } > > +/* libvirt need private key specified must be placed in a directory owned by > + root, because libvirt-cim now runs as root. So here the key would be copied, > + up layer need to delete that key after migration. This method could allow > + libvirt-cim borrow a non-root ssh private key, instead of using root's private > + key, avoid security risk. */ > +static int ssh_key_cp(const char *src, const char *dest) though the function is named ssh_key_cp it can be used to copy anything to anywhere. Moreover it runs popen on a built command, where are src and dest coming from, they aren't validated for sanity. what happen if dest is "/tmp ; rm-rf /" ??? > +{ > + char *cmd = NULL; > + int rc; > + int ret = 0; > + FILE *stream = NULL; > + char buf[256]; > + > + rc = asprintf(&cmd, "cp -f %s %s", src, dest); > + if (rc == -1) { > + cmd = NULL; > + ret = -1; > + goto out; > + } > + > + CU_DEBUG("excuting system cmd [%s].", cmd); > + stream = popen(cmd, "r"); the "popen" man page says The command argument is a pointer to a null-terminated string contain? ing a shell command line. This command is passed to /bin/sh using the -c flag; interpretation, if any, is performed by the shell. Sorry, the reason of that patch is supposedly to increase security and to me it's actually opening a huge security hole there. if you need to copy a file, do it cleanly, and verify the arguments are sane. NACK > + if (stream == NULL) { > + CU_DEBUG("Failed to open pipe to run command"); > + ret = -2; > + goto out; > + } > + usleep(10000); > + > + buf[255] = 0; > + while (fgets(buf, sizeof(buf), stream) != NULL) { > + CU_DEBUG("Exception got: %s.", buf); > + ret = -3; > + goto out; > + } > + > + out: > + if (stream != NULL) { > + pclose(stream); > + } > + free(cmd); > + return ret; > +} > + > static CMPIStatus get_msd_values(const CMPIObjectPath *ref, > const char *destination, > const CMPIArgs *argsin, > @@ -217,6 +278,14 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, > CMPIInstance *msd; > uint16_t uri_type; > char *uri = NULL; > + const char *dest_params = NULL; > + const char *ssh_hack_src = NULL; > + const char *ssh_hack_dest = NULL; > + int ret; > + > + cu_get_str_arg(argsin, "DestinationHostParams", &dest_params); > + cu_get_str_arg(argsin, "SSH_Key_Src", &ssh_hack_src); > + cu_get_str_arg(argsin, "SSH_Key_Dest", &ssh_hack_dest); > > s = get_msd(ref, argsin, &msd); > if (s.rc != CMPI_RC_OK) > @@ -230,7 +299,7 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, > if (s.rc != CMPI_RC_OK) > goto out; > > - uri = dest_uri(CLASSNAME(ref), destination, uri_type); > + uri = dest_uri(CLASSNAME(ref), destination, dest_params, uri_type); > if (uri == NULL) { > cu_statusf(_BROKER, &s, > CMPI_RC_ERR_FAILED, > @@ -238,6 +307,19 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, > goto out; > } > > + if ((ssh_hack_src) && (ssh_hack_dest)) { > + CU_DEBUG("hacking ssh keys src %s, dest %s.", > + ssh_hack_src, ssh_hack_dest); > + ret = ssh_key_cp(ssh_hack_src, ssh_hack_dest); > + if (ret < 0) { > + cu_statusf(_BROKER, &s, > + CMPI_RC_ERR_FAILED, > + "Failed to copy ssh key files"); > + goto out; > + } > + } > + > + CU_DEBUG("Migrate tring to connect remote host with uri %s.", uri); > *conn = virConnectOpen(uri); > if (*conn == NULL) { > CU_DEBUG("Failed to connect to remote host (%s)", uri); > @@ -1537,7 +1619,7 @@ static CMPIStatus migrate_vs_host(CMPIMethodMI *self, > const char *dhost = NULL; > CMPIObjectPath *system; > const char *name = NULL; > - > + > cu_get_str_arg(argsin, "DestinationHost", &dhost); > cu_get_ref_arg(argsin, "ComputerSystem", &system); > > @@ -1608,6 +1690,9 @@ static struct method_handler vsimth = { > .handler = vs_migratable_host, > .args = {{"ComputerSystem", CMPI_ref, false}, > {"DestinationHost", CMPI_string, false}, > + {"DestinationHostParams", CMPI_string, true}, > + {"SSH_Key_Src", CMPI_string, true}, > + {"SSH_Key_Dest", CMPI_string, true}, > {"MigrationSettingData", CMPI_instance, true}, > {"NewSystemSettingData", CMPI_instance, true}, > {"NewResourceSettingData", CMPI_instanceA, true}, > @@ -1632,6 +1717,9 @@ static struct method_handler mvsth = { > .handler = migrate_vs_host, > .args = {{"ComputerSystem", CMPI_ref, false}, > {"DestinationHost", CMPI_string, false}, > + {"DestinationHostParams", CMPI_string, true}, > + {"SSH_Key_Src", CMPI_string, true}, > + {"SSH_Key_Dest", CMPI_string, true}, > {"MigrationSettingData", CMPI_instance, true}, > {"NewSystemSettingData", CMPI_instance, true}, > {"NewResourceSettingData", CMPI_instanceA, true}, > -- > 1.7.1 > -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ From snmishra at linux.vnet.ibm.com Fri Sep 14 20:12:48 2012 From: snmishra at linux.vnet.ibm.com (snmishra at linux.vnet.ibm.com) Date: Fri, 14 Sep 2012 13:12:48 -0700 Subject: [Libvirt-cim] [PATCH] provide a hack to borrow non-root ssh keys in migration In-Reply-To: <20120914084822.GY16500@redhat.com> References: <1345803509-13036-1-git-send-email-xiawenc@linux.vnet.ibm.com> <20120914084822.GY16500@redhat.com> Message-ID: <20120914131248.Horde.K3YVcJir309QU4-Af7qAI0A@imap.linux.ibm.com> Thanks DV for looking at the patch. Wayne, do you have any other solution? DV, Can you please push this patch - https://www.redhat.com/archives/libvirt-cim/2012-July/msg00007.html Wayne, Are there any other patches to be reviewed/pushed? Thanks Sharad Mishra IBM Quoting Daniel Veillard : > On Fri, Aug 24, 2012 at 06:18:29PM +0800, Wenchao Xia wrote: >> This patch allow libvirt-cim to use non-root's ssh key, avoid >> using root's key to avoid exposing root's ssh login. Because libvirt-cim >> runs in root mode so it is hard to satisfy some server security rules >> especially about root's ssh key exposing. This is a walk around to improve >> it. > > This has serious security implications, so I think this really must be > documented in a very clear way: > - how do you allow another key > - how do you tell which one to pick, where and who can set this up > - there is a copy done, it's hard to tell from which soure to which > destination based just on code review > - does that work with SELinux turned on ? > > As is it's very hard to review the code to give an ACK, > >> Signed-off-by: Wenchao Xia >> --- >> src/Virt_VSMigrationService.c | 96 >> +++++++++++++++++++++++++++++++++++++++-- >> 1 files changed, 92 insertions(+), 4 deletions(-) >> >> diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c >> index 76e3d25..55442ee 100644 >> --- a/src/Virt_VSMigrationService.c >> +++ b/src/Virt_VSMigrationService.c >> @@ -150,6 +150,7 @@ static CMPIStatus get_migration_uri(CMPIInstance *msd, >> >> static char *dest_uri(const char *cn, >> const char *dest, >> + const char *dest_params, >> uint16_t transport) >> { >> const char *prefix; >> @@ -157,6 +158,7 @@ static char *dest_uri(const char *cn, >> const char *param = ""; >> char *uri = NULL; >> int rc; >> + int param_labeled = 0; >> >> if (STARTS_WITH(cn, "Xen")) >> prefix = "xen"; >> @@ -197,16 +199,75 @@ static char *dest_uri(const char *cn, >> goto out; >> } >> >> - if (!STREQC(param, "")) >> + if (!STREQC(param, "")) { >> rc = asprintf(&uri, "%s/%s", uri, param); >> + param_labeled = 1; >> + } >> >> - if (rc == -1) >> + if (rc == -1) { >> uri = NULL; >> + goto out; >> + } >> >> + if (dest_params) { >> + if (param_labeled == 0) { >> + rc = asprintf(&uri, "%s?%s", uri, dest_params); >> + } else { >> + rc = asprintf(&uri, "%s%s", uri, dest_params); >> + } >> + if (rc == -1) { >> + uri = NULL; >> + goto out; >> + } >> + } >> out: >> return uri; >> } >> >> +/* libvirt need private key specified must be placed in a >> directory owned by >> + root, because libvirt-cim now runs as root. So here the key would >> be copied, >> + up layer need to delete that key after migration. This method could allow >> + libvirt-cim borrow a non-root ssh private key, instead of using >> root's private >> + key, avoid security risk. */ >> +static int ssh_key_cp(const char *src, const char *dest) > > though the function is named ssh_key_cp it can be used to copy > anything to anywhere. Moreover it runs popen on a built command, > where are src and dest coming from, they aren't validated for > sanity. what happen if dest is "/tmp ; rm-rf /" ??? > >> +{ >> + char *cmd = NULL; >> + int rc; >> + int ret = 0; >> + FILE *stream = NULL; >> + char buf[256]; >> + >> + rc = asprintf(&cmd, "cp -f %s %s", src, dest); >> + if (rc == -1) { >> + cmd = NULL; >> + ret = -1; >> + goto out; >> + } >> + >> + CU_DEBUG("excuting system cmd [%s].", cmd); >> + stream = popen(cmd, "r"); > > the "popen" man page says > The command argument is a pointer to a null-terminated string contain? > ing a shell command line. This command is passed to /bin/sh using the > -c flag; interpretation, if any, is performed by the shell. > > Sorry, the reason of that patch is supposedly to increase security > and to me it's actually opening a huge security hole there. if you need > to copy a file, do it cleanly, and verify the arguments are sane. > > NACK > >> + if (stream == NULL) { >> + CU_DEBUG("Failed to open pipe to run command"); >> + ret = -2; >> + goto out; >> + } >> + usleep(10000); >> + >> + buf[255] = 0; >> + while (fgets(buf, sizeof(buf), stream) != NULL) { >> + CU_DEBUG("Exception got: %s.", buf); >> + ret = -3; >> + goto out; >> + } >> + >> + out: >> + if (stream != NULL) { >> + pclose(stream); >> + } >> + free(cmd); >> + return ret; >> +} >> + >> static CMPIStatus get_msd_values(const CMPIObjectPath *ref, >> const char *destination, >> const CMPIArgs *argsin, >> @@ -217,6 +278,14 @@ static CMPIStatus get_msd_values(const >> CMPIObjectPath *ref, >> CMPIInstance *msd; >> uint16_t uri_type; >> char *uri = NULL; >> + const char *dest_params = NULL; >> + const char *ssh_hack_src = NULL; >> + const char *ssh_hack_dest = NULL; >> + int ret; >> + >> + cu_get_str_arg(argsin, "DestinationHostParams", &dest_params); >> + cu_get_str_arg(argsin, "SSH_Key_Src", &ssh_hack_src); >> + cu_get_str_arg(argsin, "SSH_Key_Dest", &ssh_hack_dest); >> >> s = get_msd(ref, argsin, &msd); >> if (s.rc != CMPI_RC_OK) >> @@ -230,7 +299,7 @@ static CMPIStatus get_msd_values(const >> CMPIObjectPath *ref, >> if (s.rc != CMPI_RC_OK) >> goto out; >> >> - uri = dest_uri(CLASSNAME(ref), destination, uri_type); >> + uri = dest_uri(CLASSNAME(ref), destination, dest_params, uri_type); >> if (uri == NULL) { >> cu_statusf(_BROKER, &s, >> CMPI_RC_ERR_FAILED, >> @@ -238,6 +307,19 @@ static CMPIStatus get_msd_values(const >> CMPIObjectPath *ref, >> goto out; >> } >> >> + if ((ssh_hack_src) && (ssh_hack_dest)) { >> + CU_DEBUG("hacking ssh keys src %s, dest %s.", >> + ssh_hack_src, ssh_hack_dest); >> + ret = ssh_key_cp(ssh_hack_src, ssh_hack_dest); >> + if (ret < 0) { >> + cu_statusf(_BROKER, &s, >> + CMPI_RC_ERR_FAILED, >> + "Failed to copy ssh key files"); >> + goto out; >> + } >> + } >> + >> + CU_DEBUG("Migrate tring to connect remote host with uri %s.", uri); >> *conn = virConnectOpen(uri); >> if (*conn == NULL) { >> CU_DEBUG("Failed to connect to remote host (%s)", uri); >> @@ -1537,7 +1619,7 @@ static CMPIStatus migrate_vs_host(CMPIMethodMI *self, >> const char *dhost = NULL; >> CMPIObjectPath *system; >> const char *name = NULL; >> - >> + >> cu_get_str_arg(argsin, "DestinationHost", &dhost); >> cu_get_ref_arg(argsin, "ComputerSystem", &system); >> >> @@ -1608,6 +1690,9 @@ static struct method_handler vsimth = { >> .handler = vs_migratable_host, >> .args = {{"ComputerSystem", CMPI_ref, false}, >> {"DestinationHost", CMPI_string, false}, >> + {"DestinationHostParams", CMPI_string, true}, >> + {"SSH_Key_Src", CMPI_string, true}, >> + {"SSH_Key_Dest", CMPI_string, true}, >> {"MigrationSettingData", CMPI_instance, true}, >> {"NewSystemSettingData", CMPI_instance, true}, >> {"NewResourceSettingData", CMPI_instanceA, true}, >> @@ -1632,6 +1717,9 @@ static struct method_handler mvsth = { >> .handler = migrate_vs_host, >> .args = {{"ComputerSystem", CMPI_ref, false}, >> {"DestinationHost", CMPI_string, false}, >> + {"DestinationHostParams", CMPI_string, true}, >> + {"SSH_Key_Src", CMPI_string, true}, >> + {"SSH_Key_Dest", CMPI_string, true}, >> {"MigrationSettingData", CMPI_instance, true}, >> {"NewSystemSettingData", CMPI_instance, true}, >> {"NewResourceSettingData", CMPI_instanceA, true}, >> -- >> 1.7.1 >> > > -- > Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ > daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/ > http://veillard.com/ | virtualization library http://libvirt.org/ > > _______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim From xiaxia347work at 163.com Sat Sep 15 00:36:37 2012 From: xiaxia347work at 163.com (xiaxia347work) Date: Sat, 15 Sep 2012 08:36:37 +0800 Subject: [Libvirt-cim] [PATCH] provide a hack to borrow non-root ssh keys in migration In-Reply-To: <20120914131248.Horde.K3YVcJir309QU4-Af7qAI0A@imap.linux.ibm.com> References: <1345803509-13036-1-git-send-email-xiawenc@linux.vnet.ibm.com> <20120914084822.GY16500@redhat.com><20120914131248.Horde.K3YVcJir309QU4-Af7qAI0A@imap.linux.ibm.com> Message-ID: <1bc83d44.438.139c75b1a22.Coremail.xiaxia347work@163.com> HI still have 2 need to look at I think, one is the patch with the title of the mail, another is https://www.redhat.com/archives/libvirt-cim/2012-July/msg00007.html mentioned before. About the non-root ssh keys patch: - how do you allow another key it is based on adding aditional parameter "?keyfile=[PLACE]" in URL for libvirt remote access, this patch added an optionin libvirt-cim migration call, so client can pass this option in now. - how do you tell which one to pick, where and who can set this up It is decided by the client who have authority to start migration, basically this patch added 3 parameters: DestinationHostParams, SSH_Key_Src, SSH_Key_Dest. This patch would first cp -f SSH_Key_Src, SSH_Key_Dest, then append DestinationHostParams in URI. Copying was done because libvirt reject the keyfile if the directory was not owned by the caller, in libvirt-cim it is root. Finally user must do: first setup a non-root account who have the capability to manage system VMs in libvirt(call it USER A here), generate USER A's ssh-key pairs and setup them on two nodes that want to do migration, then specify these three options to borrow USER A's private key. After migration, caller could delete the key-pairs. If these 3 options were not sepcified, then they can do migration with root's indentity as before. - there is a copy done, it's hard to tell from which soure to which destination based just on code review Yes, cim client must know this themself, but usually there would be only one account's key file for migration exist, and cim caller knows where is source and destination. - does that work with SELinux turned on ? my test was done with SELinux turned off, when SELinux was on it may succeed unless "copy" or "virsh connect qemu+ssh:URI?keyfile=XXX" broke for SELinux. But for simple I think SELinux was not guarenteed to work for this. 2012-09-15 Best Regards Wenchao Xia ????snmishra ?????2012-09-15 04:13 ???Re: [Libvirt-cim] [PATCH] provide a hack to borrow non-root ssh keys in migration ????"Daniel Veillard" ???"libvirt-cim" Thanks DV for looking at the patch. Wayne, do you have any other solution? DV, Can you please push this patch - https://www.redhat.com/archives/libvirt-cim/2012-July/msg00007.html Wayne, Are there any other patches to be reviewed/pushed? Thanks Sharad Mishra IBM Quoting Daniel Veillard : > On Fri, Aug 24, 2012 at 06:18:29PM +0800, Wenchao Xia wrote: >> This patch allow libvirt-cim to use non-root's ssh key, avoid >> using root's key to avoid exposing root's ssh login. Because libvirt-cim >> runs in root mode so it is hard to satisfy some server security rules >> especially about root's ssh key exposing. This is a walk around to improve >> it. > > This has serious security implications, so I think this really must be > documented in a very clear way: > - how do you allow another key > - how do you tell which one to pick, where and who can set this up > - there is a copy done, it's hard to tell from which soure to which > destination based just on code review > - does that work with SELinux turned on ? > > As is it's very hard to review the code to give an ACK, > >> Signed-off-by: Wenchao Xia >> --- >> src/Virt_VSMigrationService.c | 96 >> +++++++++++++++++++++++++++++++++++++++-- >> 1 files changed, 92 insertions(+), 4 deletions(-) >> >> diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c >> index 76e3d25..55442ee 100644 >> --- a/src/Virt_VSMigrationService.c >> +++ b/src/Virt_VSMigrationService.c >> @@ -150,6 +150,7 @@ static CMPIStatus get_migration_uri(CMPIInstance *msd, >> >> static char *dest_uri(const char *cn, >> const char *dest, >> + const char *dest_params, >> uint16_t transport) >> { >> const char *prefix; >> @@ -157,6 +158,7 @@ static char *dest_uri(const char *cn, >> const char *param = ""; >> char *uri = NULL; >> int rc; >> + int param_labeled = 0; >> >> if (STARTS_WITH(cn, "Xen")) >> prefix = "xen"; >> @@ -197,16 +199,75 @@ static char *dest_uri(const char *cn, >> goto out; >> } >> >> - if (!STREQC(param, "")) >> + if (!STREQC(param, "")) { >> rc = asprintf(&uri, "%s/%s", uri, param); >> + param_labeled = 1; >> + } >> >> - if (rc == -1) >> + if (rc == -1) { >> uri = NULL; >> + goto out; >> + } >> >> + if (dest_params) { >> + if (param_labeled == 0) { >> + rc = asprintf(&uri, "%s?%s", uri, dest_params); >> + } else { >> + rc = asprintf(&uri, "%s%s", uri, dest_params); >> + } >> + if (rc == -1) { >> + uri = NULL; >> + goto out; >> + } >> + } >> out: >> return uri; >> } >> >> +/* libvirt need private key specified must be placed in a >> directory owned by >> + root, because libvirt-cim now runs as root. So here the key would >> be copied, >> + up layer need to delete that key after migration. This method could allow >> + libvirt-cim borrow a non-root ssh private key, instead of using >> root's private >> + key, avoid security risk. */ >> +static int ssh_key_cp(const char *src, const char *dest) > > though the function is named ssh_key_cp it can be used to copy > anything to anywhere. Moreover it runs popen on a built command, > where are src and dest coming from, they aren't validated for > sanity. what happen if dest is "/tmp ; rm-rf /" ??? > >> +{ >> + char *cmd = NULL; >> + int rc; >> + int ret = 0; >> + FILE *stream = NULL; >> + char buf[256]; >> + >> + rc = asprintf(&cmd, "cp -f %s %s", src, dest); >> + if (rc == -1) { >> + cmd = NULL; >> + ret = -1; >> + goto out; >> + } >> + >> + CU_DEBUG("excuting system cmd [%s].", cmd); >> + stream = popen(cmd, "r"); > > the "popen" man page says > The command argument is a pointer to a null-terminated string contain? > ing a shell command line. This command is passed to /bin/sh using the > -c flag; interpretation, if any, is performed by the shell. > > Sorry, the reason of that patch is supposedly to increase security > and to me it's actually opening a huge security hole there. if you need > to copy a file, do it cleanly, and verify the arguments are sane. > > NACK > >> + if (stream == NULL) { >> + CU_DEBUG("Failed to open pipe to run command"); >> + ret = -2; >> + goto out; >> + } >> + usleep(10000); >> + >> + buf[255] = 0; >> + while (fgets(buf, sizeof(buf), stream) != NULL) { >> + CU_DEBUG("Exception got: %s.", buf); >> + ret = -3; >> + goto out; >> + } >> + >> + out: >> + if (stream != NULL) { >> + pclose(stream); >> + } >> + free(cmd); >> + return ret; >> +} >> + >> static CMPIStatus get_msd_values(const CMPIObjectPath *ref, >> const char *destination, >> const CMPIArgs *argsin, >> @@ -217,6 +278,14 @@ static CMPIStatus get_msd_values(const >> CMPIObjectPath *ref, >> CMPIInstance *msd; >> uint16_t uri_type; >> char *uri = NULL; >> + const char *dest_params = NULL; >> + const char *ssh_hack_src = NULL; >> + const char *ssh_hack_dest = NULL; >> + int ret; >> + >> + cu_get_str_arg(argsin, "DestinationHostParams", &dest_params); >> + cu_get_str_arg(argsin, "SSH_Key_Src", &ssh_hack_src); >> + cu_get_str_arg(argsin, "SSH_Key_Dest", &ssh_hack_dest); >> >> s = get_msd(ref, argsin, &msd); >> if (s.rc != CMPI_RC_OK) >> @@ -230,7 +299,7 @@ static CMPIStatus get_msd_values(const >> CMPIObjectPath *ref, >> if (s.rc != CMPI_RC_OK) >> goto out; >> >> - uri = dest_uri(CLASSNAME(ref), destination, uri_type); >> + uri = dest_uri(CLASSNAME(ref), destination, dest_params, uri_type); >> if (uri == NULL) { >> cu_statusf(_BROKER, &s, >> CMPI_RC_ERR_FAILED, >> @@ -238,6 +307,19 @@ static CMPIStatus get_msd_values(const >> CMPIObjectPath *ref, >> goto out; >> } >> >> + if ((ssh_hack_src) && (ssh_hack_dest)) { >> + CU_DEBUG("hacking ssh keys src %s, dest %s.", >> + ssh_hack_src, ssh_hack_dest); >> + ret = ssh_key_cp(ssh_hack_src, ssh_hack_dest); >> + if (ret < 0) { >> + cu_statusf(_BROKER, &s, >> + CMPI_RC_ERR_FAILED, >> + "Failed to copy ssh key files"); >> + goto out; >> + } >> + } >> + >> + CU_DEBUG("Migrate tring to connect remote host with uri %s.", uri); >> *conn = virConnectOpen(uri); >> if (*conn == NULL) { >> CU_DEBUG("Failed to connect to remote host (%s)", uri); >> @@ -1537,7 +1619,7 @@ static CMPIStatus migrate_vs_host(CMPIMethodMI *self, >> const char *dhost = NULL; >> CMPIObjectPath *system; >> const char *name = NULL; >> - >> + >> cu_get_str_arg(argsin, "DestinationHost", &dhost); >> cu_get_ref_arg(argsin, "ComputerSystem", &system); >> >> @@ -1608,6 +1690,9 @@ static struct method_handler vsimth = { >> .handler = vs_migratable_host, >> .args = {{"ComputerSystem", CMPI_ref, false}, >> {"DestinationHost", CMPI_string, false}, >> + {"DestinationHostParams", CMPI_string, true}, >> + {"SSH_Key_Src", CMPI_string, true}, >> + {"SSH_Key_Dest", CMPI_string, true}, >> {"MigrationSettingData", CMPI_instance, true}, >> {"NewSystemSettingData", CMPI_instance, true}, >> {"NewResourceSettingData", CMPI_instanceA, true}, >> @@ -1632,6 +1717,9 @@ static struct method_handler mvsth = { >> .handler = migrate_vs_host, >> .args = {{"ComputerSystem", CMPI_ref, false}, >> {"DestinationHost", CMPI_string, false}, >> + {"DestinationHostParams", CMPI_string, true}, >> + {"SSH_Key_Src", CMPI_string, true}, >> + {"SSH_Key_Dest", CMPI_string, true}, >> {"MigrationSettingData", CMPI_instance, true}, >> {"NewSystemSettingData", CMPI_instance, true}, >> {"NewResourceSettingData", CMPI_instanceA, true}, >> -- >> 1.7.1 >> > > -- > Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ > daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/ > http://veillard.com/ | virtualization library http://libvirt.org/ > > _______________________________________________ > Libvirt-cim mailing list > Libvirt-cim at redhat.com > https://www.redhat.com/mailman/listinfo/libvirt-cim _______________________________________________ Libvirt-cim mailing list Libvirt-cim at redhat.com https://www.redhat.com/mailman/listinfo/libvirt-cim From xiaxia347work at 163.com Sat Sep 15 00:38:22 2012 From: xiaxia347work at 163.com (xiaxia347work) Date: Sat, 15 Sep 2012 08:38:22 +0800 Subject: [Libvirt-cim] [PATCH] fix id parsing with white space In-Reply-To: <20120914083629.GX16500@redhat.com> References: <1343979419-30227-1-git-send-email-xiawenc@linux.vnet.ibm.com><20120914083629.GX16500@redhat.com> Message-ID: <7ed368e0.461.139c75cb012.Coremail.xiaxia347work@163.com> sorry for missed that in doc, before this patch assoication with the pool contain space in it would fail. 2012-09-15 Best Regards Wenchao Xia ????Daniel Veillard ?????2012-09-14 16:36 ???Re: [Libvirt-cim] [PATCH] fix id parsing with white space ????"Wenchao Xia" ???"libvirt-cim" On Fri, Aug 03, 2012 at 03:36:59PM +0800, Wenchao Xia wrote: > When device id string contains white space, parse is not correct. > This patch fix it > > Signed-off-by: Wenchao Xia > --- > libxkutil/device_parsing.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) ACK, pushed, but giving an example would be useful, I don't know any device with space in its name Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ _______________________________________________ Libvirt-cim mailing list Libvirt-cim at redhat.com https://www.redhat.com/mailman/listinfo/libvirt-cim -------------- next part -------------- An HTML attachment was scrubbed... URL: From xiawenc at linux.vnet.ibm.com Wed Sep 19 08:46:25 2012 From: xiawenc at linux.vnet.ibm.com (Wenchao Xia) Date: Wed, 19 Sep 2012 16:46:25 +0800 Subject: [Libvirt-cim] [PATCH V2] provide a hack to borrow non-root ssh keys in migration Message-ID: <1348044385-27592-1-git-send-email-xiawenc@linux.vnet.ibm.com> This patch allow libvirt-cim to use non-root's ssh key, not using root's key to avoid exposing root's ssh login. Because libvirt-cim runs in root mode so it is hard to satisfy some server security rules especially about root's ssh key exposing. This is a walk around to improve it. This patch added three additonal paremeters in vs migration and migratable method, they are DestinationHostParams, SSH_Key_Src, SSH_Key_Dest. DestinationHostParams is the addtional string which would be appended after the uri if it was set, so with this parameter user could add additional parameter in libvirt remote uri, such as "?keyfile=/tmp/tempkey.rsa". Because libvirt woulkd ignore the private key file parameter, if the key's directory was not owned by the user, and libvirt-cim runs as root, so SSH_Key_Src and SSH_Key_Dest were provided to allow a copying of keyfile to a directory that owned by root, at runtime. if SSH_Key_Src and SSH_Key_Dest were set, libvirt-cim would run shell command "cp -f [SSH_Key_Src] [SSH_Key_Dest]". Typically cim client with authority to do a migration, could specify these three additonal parameters with ssh migration method set, as DestinationHostParams="?keyfile=/root/temp_migration_key.rsa" SSH_Key_Src="/home/VController/.ssh/id_rsa" SSH_Key_Dest="/root/temp_migration_key.rsa" then, the migration would complete with VController's key pairs, instead of root's, avoided turning on root's ssh logins. Test was done when SELinux was shutdown. V2: Better documentation. Signed-off-by: Wenchao Xia --- src/Virt_VSMigrationService.c | 96 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/Virt_VSMigrationService.c b/src/Virt_VSMigrationService.c index 76e3d25..55442ee 100644 --- a/src/Virt_VSMigrationService.c +++ b/src/Virt_VSMigrationService.c @@ -150,6 +150,7 @@ static CMPIStatus get_migration_uri(CMPIInstance *msd, static char *dest_uri(const char *cn, const char *dest, + const char *dest_params, uint16_t transport) { const char *prefix; @@ -157,6 +158,7 @@ static char *dest_uri(const char *cn, const char *param = ""; char *uri = NULL; int rc; + int param_labeled = 0; if (STARTS_WITH(cn, "Xen")) prefix = "xen"; @@ -197,16 +199,75 @@ static char *dest_uri(const char *cn, goto out; } - if (!STREQC(param, "")) + if (!STREQC(param, "")) { rc = asprintf(&uri, "%s/%s", uri, param); + param_labeled = 1; + } - if (rc == -1) + if (rc == -1) { uri = NULL; + goto out; + } + if (dest_params) { + if (param_labeled == 0) { + rc = asprintf(&uri, "%s?%s", uri, dest_params); + } else { + rc = asprintf(&uri, "%s%s", uri, dest_params); + } + if (rc == -1) { + uri = NULL; + goto out; + } + } out: return uri; } +/* libvirt need private key specified must be placed in a directory owned by + root, because libvirt-cim now runs as root. So here the key would be copied, + up layer need to delete that key after migration. This method could allow + libvirt-cim borrow a non-root ssh private key, instead of using root's private + key, avoid security risk. */ +static int ssh_key_cp(const char *src, const char *dest) +{ + char *cmd = NULL; + int rc; + int ret = 0; + FILE *stream = NULL; + char buf[256]; + + rc = asprintf(&cmd, "cp -f %s %s", src, dest); + if (rc == -1) { + cmd = NULL; + ret = -1; + goto out; + } + + CU_DEBUG("excuting system cmd [%s].", cmd); + stream = popen(cmd, "r"); + if (stream == NULL) { + CU_DEBUG("Failed to open pipe to run command"); + ret = -2; + goto out; + } + usleep(10000); + + buf[255] = 0; + while (fgets(buf, sizeof(buf), stream) != NULL) { + CU_DEBUG("Exception got: %s.", buf); + ret = -3; + goto out; + } + + out: + if (stream != NULL) { + pclose(stream); + } + free(cmd); + return ret; +} + static CMPIStatus get_msd_values(const CMPIObjectPath *ref, const char *destination, const CMPIArgs *argsin, @@ -217,6 +278,14 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, CMPIInstance *msd; uint16_t uri_type; char *uri = NULL; + const char *dest_params = NULL; + const char *ssh_hack_src = NULL; + const char *ssh_hack_dest = NULL; + int ret; + + cu_get_str_arg(argsin, "DestinationHostParams", &dest_params); + cu_get_str_arg(argsin, "SSH_Key_Src", &ssh_hack_src); + cu_get_str_arg(argsin, "SSH_Key_Dest", &ssh_hack_dest); s = get_msd(ref, argsin, &msd); if (s.rc != CMPI_RC_OK) @@ -230,7 +299,7 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, if (s.rc != CMPI_RC_OK) goto out; - uri = dest_uri(CLASSNAME(ref), destination, uri_type); + uri = dest_uri(CLASSNAME(ref), destination, dest_params, uri_type); if (uri == NULL) { cu_statusf(_BROKER, &s, CMPI_RC_ERR_FAILED, @@ -238,6 +307,19 @@ static CMPIStatus get_msd_values(const CMPIObjectPath *ref, goto out; } + if ((ssh_hack_src) && (ssh_hack_dest)) { + CU_DEBUG("hacking ssh keys src %s, dest %s.", + ssh_hack_src, ssh_hack_dest); + ret = ssh_key_cp(ssh_hack_src, ssh_hack_dest); + if (ret < 0) { + cu_statusf(_BROKER, &s, + CMPI_RC_ERR_FAILED, + "Failed to copy ssh key files"); + goto out; + } + } + + CU_DEBUG("Migrate tring to connect remote host with uri %s.", uri); *conn = virConnectOpen(uri); if (*conn == NULL) { CU_DEBUG("Failed to connect to remote host (%s)", uri); @@ -1537,7 +1619,7 @@ static CMPIStatus migrate_vs_host(CMPIMethodMI *self, const char *dhost = NULL; CMPIObjectPath *system; const char *name = NULL; - + cu_get_str_arg(argsin, "DestinationHost", &dhost); cu_get_ref_arg(argsin, "ComputerSystem", &system); @@ -1608,6 +1690,9 @@ static struct method_handler vsimth = { .handler = vs_migratable_host, .args = {{"ComputerSystem", CMPI_ref, false}, {"DestinationHost", CMPI_string, false}, + {"DestinationHostParams", CMPI_string, true}, + {"SSH_Key_Src", CMPI_string, true}, + {"SSH_Key_Dest", CMPI_string, true}, {"MigrationSettingData", CMPI_instance, true}, {"NewSystemSettingData", CMPI_instance, true}, {"NewResourceSettingData", CMPI_instanceA, true}, @@ -1632,6 +1717,9 @@ static struct method_handler mvsth = { .handler = migrate_vs_host, .args = {{"ComputerSystem", CMPI_ref, false}, {"DestinationHost", CMPI_string, false}, + {"DestinationHostParams", CMPI_string, true}, + {"SSH_Key_Src", CMPI_string, true}, + {"SSH_Key_Dest", CMPI_string, true}, {"MigrationSettingData", CMPI_instance, true}, {"NewSystemSettingData", CMPI_instance, true}, {"NewResourceSettingData", CMPI_instanceA, true}, -- 1.7.1 From xiawenc at linux.vnet.ibm.com Fri Sep 21 09:22:59 2012 From: xiawenc at linux.vnet.ibm.com (Wenchao Xia) Date: Fri, 21 Sep 2012 17:22:59 +0800 Subject: [Libvirt-cim] [PATCH] do not deregister virt classes in yum upgrade Message-ID: <1348219379-23580-1-git-send-email-xiawenc@linux.vnet.ibm.com> Now yum upgrade will deregister the virt classes, make libvirt-cim not workable. This patch fixed it from now on. Signed-off-by: Wenchao Xia --- libvirt-cim.spec.in | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libvirt-cim.spec.in b/libvirt-cim.spec.in index d78eee7..3def978 100644 --- a/libvirt-cim.spec.in +++ b/libvirt-cim.spec.in @@ -104,18 +104,22 @@ rm -fr $RPM_BUILD_ROOT -r %{CIMV2_REG} -m %{CIMV2_MOF} -v >/dev/null 2>&1 || true %preun -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ +#Deregister only in uninstall, do nothing in upgrade. +if [ "$1" = "0" ]; then + echo "Deleting registered classes in libvirt-cim..." + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n @CIM_VIRT_NS@ \ -r %{REGISTRATION} -m %{SCHEMA} >/dev/null 2>&1 || true -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n root/interop \ -r %{INTEROP_REG} -m %{INTEROP_MOF} >/dev/null 2>&1 || true -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n root/PG_InterOp \ -r %{PGINTEROP_REG} -m %{PGINTEROP_MOF} >/dev/null 2>&1 || true -%{_datadir}/%{name}/provider-register.sh -d -t pegasus \ + %{_datadir}/%{name}/provider-register.sh -d -t pegasus \ -n root/cimv2 \ -r %{CIMV2_REG} -m %{CIMV2_MOF} >/dev/null 2>&1 || true +fi %postun -p /sbin/ldconfig -- 1.7.1