[Spice-commits] 6 commits - Makefile.am vdagent/as_user.cpp vdagent/as_user.h vdagent/file_xfer.cpp vdagent/file_xfer.h vdagent/vdagent.vcproj

Uri Lublin uril at kemper.freedesktop.org
Thu Nov 14 04:57:44 PST 2013


 Makefile.am            |   14 ++++++---
 vdagent/as_user.cpp    |   73 +++++++++++++++++++++++++++++++++++++++++++++++++
 vdagent/as_user.h      |   38 +++++++++++++++++++++++++
 vdagent/file_xfer.cpp  |   34 ++++++++++++++++++----
 vdagent/file_xfer.h    |    3 +-
 vdagent/vdagent.vcproj |    8 +++++
 6 files changed, 157 insertions(+), 13 deletions(-)

New commits:
commit efea0d654bed290fcb183292ae3d62d0ba8a8b35
Author: Uri Lublin <uril at redhat.com>
Date:   Thu Nov 7 23:50:52 2013 +0200

    Makefile.am: add INCLUDES to AM_CPPFLAGS
    
    Fixes the following autoreconf (automake) warning:
    Makefile.am:6: warning: 'INCLUDES' is the old name for 'AM_CPPFLAGS' (or '*_CPPFLAGS')

diff --git a/Makefile.am b/Makefile.am
index da0b5a5..749ef56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,13 +3,15 @@ MAINTAINERCLEANFILES =
 
 DIST_SUBDIRS = spice-protocol
 
-INCLUDES =				\
+AM_CXXFLAGS = -flto -fwhole-program
+AM_CPPFLAGS = 				\
+	-DUNICODE 			\
+	-D_UNICODE			\
+	-DOLDMSVCRT			\
 	-I$(top_srcdir)/common		\
 	-I$(top_srcdir)/spice-protocol	\
 	$(NULL)
 
-AM_CXXFLAGS = -flto -fwhole-program
-AM_CPPFLAGS = -DUNICODE -D_UNICODE -DOLDMSVCRT
 AM_LDFLAGS = -static
 if !ENABLE_DEBUG
 AM_LDFLAGS += -s
commit 0a9047384833d05e7c0b16a494730584665b673b
Author: Uri Lublin <uril at redhat.com>
Date:   Tue Nov 5 18:49:51 2013 +0200

    Makefile.am: tabify

diff --git a/Makefile.am b/Makefile.am
index 768e984..da0b5a5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,8 +32,8 @@ vdagent_SOURCES =			\
 	vdagent/desktop_layout.h	\
 	vdagent/display_setting.cpp	\
 	vdagent/display_setting.h	\
-        vdagent/file_xfer.cpp		\
-        vdagent/file_xfer.h		\
+	vdagent/file_xfer.cpp		\
+	vdagent/file_xfer.h		\
 	vdagent/vdagent.cpp		\
 	vdagent/as_user.cpp		\
 	vdagent/as_user.h		\
commit 4335b0d43a420784e753bd85bf4cecfbda3d991b
Author: Uri Lublin <uril at redhat.com>
Date:   Tue Nov 5 18:43:42 2013 +0200

    vdagent: file_xfer: make g_key_get_string safer
    
    By providing the size of the destination string buffer.

diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp
index eb2119a..e402eb2 100644
--- a/vdagent/file_xfer.cpp
+++ b/vdagent/file_xfer.cpp
@@ -49,7 +49,7 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
 
     status->id = start->id;
     status->result = VD_AGENT_FILE_XFER_STATUS_ERROR;
-    if (!g_key_get_string(file_meta, "vdagent-file-xfer", "name", file_name) ||
+    if (!g_key_get_string(file_meta, "vdagent-file-xfer", "name", file_name, sizeof(file_name)) ||
             !g_key_get_uint64(file_meta, "vdagent-file-xfer", "size", &file_size)) {
         vd_printf("file id %u meta parsing failed", start->id);
         return;
@@ -181,10 +181,12 @@ bool FileXfer::dispatch(VDAgentMessage* msg, VDAgentFileXferStatusMessage* statu
 //minimal parsers for GKeyFile, supporting only key=value with no spaces.
 #define G_KEY_MAX_LEN 256
 
-bool FileXfer::g_key_get_string(char* data, const char* group, const char* key, char* value)
+bool FileXfer::g_key_get_string(char* data, const char* group, const char* key, char* value,
+                                                  unsigned vsize)
 {
     char group_pfx[G_KEY_MAX_LEN], key_pfx[G_KEY_MAX_LEN];
-    char *group_pos, *key_pos, *next_group_pos;
+    char *group_pos, *key_pos, *next_group_pos, *start, *end;
+    unsigned len;
 
     snprintf(group_pfx, sizeof(group_pfx), "[%s]", group);
     if (!(group_pos = strstr((char*)data, group_pfx))) return false;
@@ -193,15 +195,26 @@ bool FileXfer::g_key_get_string(char* data, const char* group, const char* key,
     if (!(key_pos = strstr(group_pos, key_pfx))) return false;
 
     next_group_pos = strstr(group_pos + strlen(group_pfx), "[");
-    if (next_group_pos && key_pos > next_group_pos) return false; 
+    if (next_group_pos && key_pos > next_group_pos) return false;
 
-    return !!sscanf(key_pos + strlen(key_pfx), "%s\n", value);
+    start = key_pos + strlen(key_pfx);
+    end = strchr(start, '\n');
+    if (!end) return false;
+
+    len = end - start;
+    if (len >= vsize) return false;
+
+    memcpy(value, start, len);
+    value[len] = '\0';
+
+    return true;
 }
 
 bool FileXfer::g_key_get_uint64(char* data, const char* group, const char* key, uint64_t* value)
 {
     char str[G_KEY_MAX_LEN];
 
-    if (!g_key_get_string(data, group, key, str)) return false;
+    if (!g_key_get_string(data, group, key, str, sizeof(str)))
+        return false;
     return !!sscanf(str, "%" PRIu64, value);
 }
diff --git a/vdagent/file_xfer.h b/vdagent/file_xfer.h
index 649b296..b506f59 100644
--- a/vdagent/file_xfer.h
+++ b/vdagent/file_xfer.h
@@ -44,7 +44,8 @@ private:
     void handle_start(VDAgentFileXferStartMessage* start, VDAgentFileXferStatusMessage* status);
     bool handle_data(VDAgentFileXferDataMessage* data, VDAgentFileXferStatusMessage* status);
     void handle_status(VDAgentFileXferStatusMessage* status);
-    bool g_key_get_string(char* data, const char* group, const char* key, char* value);
+    bool g_key_get_string(char* data, const char* group, const char* key, char* value,
+                                        unsigned vsize);
     bool g_key_get_uint64(char* data, const char* group, const char* key, uint64_t* value);
 
 private:
commit 066f614cee28609176cb24c594e034e7a1237220
Author: Uri Lublin <uril at redhat.com>
Date:   Tue Nov 5 18:45:59 2013 +0200

    vdagent: file-xfer: make user desktop the target directory
    
    Before, the target directory was a public one (for all users),
    as file creation was not done with user privileges.
    
    Now that the file is created with user privileges, it's
    better to make the user desktop the target directory.

diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp
index 2a6480a..eb2119a 100644
--- a/vdagent/file_xfer.cpp
+++ b/vdagent/file_xfer.cpp
@@ -60,7 +60,7 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
         return;
     }
 
-    if (FAILED(SHGetFolderPathA(NULL, CSIDL_COMMON_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE, NULL,
+    if (FAILED(SHGetFolderPathA(NULL, CSIDL_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE, NULL,
             SHGFP_TYPE_CURRENT, file_path))) {
         vd_printf("failed getting desktop path");
         return;
commit 71193f658131d31b28b6d9afdd385111bc32377b
Author: Uri Lublin <uril at redhat.com>
Date:   Tue Nov 5 18:35:27 2013 +0200

    file_xfer: create file with user privileges

diff --git a/vdagent/file_xfer.cpp b/vdagent/file_xfer.cpp
index 66b489a..2a6480a 100644
--- a/vdagent/file_xfer.cpp
+++ b/vdagent/file_xfer.cpp
@@ -21,6 +21,7 @@
 #include <inttypes.h>
 #include <stdio.h>
 #include "file_xfer.h"
+#include "as_user.h"
 
 FileXfer::~FileXfer()
 {
@@ -44,6 +45,7 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
     FileXferTask* task;
     uint64_t file_size;
     HANDLE handle;
+    AsUser as_user;
 
     status->id = start->id;
     status->result = VD_AGENT_FILE_XFER_STATUS_ERROR;
@@ -53,6 +55,11 @@ void FileXfer::handle_start(VDAgentFileXferStartMessage* start,
         return;
     }
     vd_printf("%u %s (%" PRIu64 ")", start->id, file_name, file_size);
+    if (!as_user.begin()) {
+        vd_printf("as_user failed");
+        return;
+    }
+
     if (FAILED(SHGetFolderPathA(NULL, CSIDL_COMMON_DESKTOPDIRECTORY | CSIDL_FLAG_CREATE, NULL,
             SHGFP_TYPE_CURRENT, file_path))) {
         vd_printf("failed getting desktop path");
commit 750a8bab405588d91c41f84c458d9cda0f7189bf
Author: Uri Lublin <uril at redhat.com>
Date:   Sun Nov 3 11:28:57 2013 +0200

    vdagent: add as_user to run tasks with user privileges
    
    The class calls Impersonate upon begin(), and Revert
    upon end() or destruction.
    
    The user is the current user that is logged in.
    
     create mode 100644 vdagent/as_user.cpp
     create mode 100644 vdagent/as_user.h

diff --git a/Makefile.am b/Makefile.am
index f907031..768e984 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,8 @@ vdagent_SOURCES =			\
         vdagent/file_xfer.cpp		\
         vdagent/file_xfer.h		\
 	vdagent/vdagent.cpp		\
+	vdagent/as_user.cpp		\
+	vdagent/as_user.h		\
 	$(NULL)
 
 vdagent_rc.$(OBJEXT): vdagent/vdagent.rc
diff --git a/vdagent/as_user.cpp b/vdagent/as_user.cpp
new file mode 100644
index 0000000..d2d6c58
--- /dev/null
+++ b/vdagent/as_user.cpp
@@ -0,0 +1,73 @@
+/*
+   Copyright (C) 2013 Red Hat, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "vdcommon.h"
+#include "as_user.h"
+
+#include <wtsapi32.h>
+
+AsUser::AsUser(DWORD session_id):
+    _started(false),
+    _session_id(session_id),
+    _token(INVALID_HANDLE_VALUE)
+{
+}
+
+bool AsUser::begin()
+{
+    BOOL ret;
+
+    if (_session_id == (DWORD)-1) {
+        ret = ProcessIdToSessionId(GetCurrentProcessId(), &_session_id);
+        if (!ret) {
+            vd_printf("ProcessIdToSessionId failed %lu", GetLastError());
+            return false;
+        }
+    }
+    if (_token == INVALID_HANDLE_VALUE) {
+        ret = WTSQueryUserToken(_session_id, &_token);
+        if (!ret) {
+            vd_printf("WTSQueryUserToken failed -- %lu", GetLastError());
+        return false;
+        }
+    }
+
+    ret = ImpersonateLoggedOnUser(_token);
+    if (!ret) {
+        vd_printf("ImpersonateLoggedOnUser failed: %lu", GetLastError());
+        return false;
+    }
+
+    _started = true;
+    return true;
+}
+
+void AsUser::end()
+{
+    if (_started) {
+        RevertToSelf();
+        _started = false;
+    }
+}
+
+AsUser::~AsUser()
+{
+    end();
+    if (_token != INVALID_HANDLE_VALUE) {
+        CloseHandle(_token);
+    }
+}
diff --git a/vdagent/as_user.h b/vdagent/as_user.h
new file mode 100644
index 0000000..6243e98
--- /dev/null
+++ b/vdagent/as_user.h
@@ -0,0 +1,38 @@
+/*
+   Copyright (C) 2013 Red Hat, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _H_AS_USER_
+#define _H_AS_USER_
+
+/** AsUser runs a task as the user logged on in session_id.
+ *  Constructor calls Impersonate, Destructor calls Revert, so
+ *  the caller needs not worry about that.
+ */
+class AsUser {
+public:
+    ~AsUser();
+    AsUser(DWORD session_id = (DWORD)-1);
+    bool begin();
+    void end();
+
+private:
+    DWORD _session_id;
+    HANDLE _token;
+    bool _started;
+};
+
+#endif
diff --git a/vdagent/vdagent.vcproj b/vdagent/vdagent.vcproj
index 6943e5e..f9f4228 100644
--- a/vdagent/vdagent.vcproj
+++ b/vdagent/vdagent.vcproj
@@ -342,6 +342,10 @@
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
 			<File
+				RelativePath=".\as_user.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\desktop_layout.cpp"
 				>
 			</File>
@@ -372,6 +376,10 @@
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
 			<File
+				RelativePath=".\as_user.h"
+				>
+			</File>
+			<File
 				RelativePath=".\desktop_layout.h"
 				>
 			</File>


More information about the Spice-commits mailing list