--- /dev/null
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @file CMakeLists.txt
+# @author
+# @brief
+#
+
+############################# Check minimum CMake version #####################
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sdbd)
+
+############################# cmake packages ##################################
+
+INCLUDE(FindPkgConfig)
+
+############################# compiler flags ##################################
+
+SET(SDBD_SRCS
+ src/sdb.c
+ src/fdevent.c
+ src/transport.c
+ src/transport_local.c
+ src/transport_usb.c
+ src/sockets.c
+ src/services.c
+ src/file_sync_service.c
+ src/usb_linux_client.c
+ src/utils.c
+ src/socket_inaddr_any_server.c
+ src/socket_local_client.c
+ src/socket_local_server.c
+ src/socket_loopback_client.c
+ src/socket_loopback_server.c
+ src/socket_network_client.c
+ src/sdktools.c
+ src/strutils.c
+ src/fileutils.c
+ )
+
+pkg_check_modules(pkgs REQUIRED
+ capi-system-info
+ vconf
+ vasum
+ glib-2.0
+ dbus-1
+ dbus-glib-1
+ security-server
+ )
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+INCLUDE_DIRECTORIES(src)
+
+ADD_DEFINITIONS("-O2 -g -Wall -Wno-unused-parameter -fPIE")
+ADD_DEFINITIONS("-DSDB_HOST=0")
+ADD_DEFINITIONS("-D_XOPEN_SOURCE")
+ADD_DEFINITIONS("-D_GNU_SOURCE")
+ADD_DEFINITIONS("-DHAVE_FORKEXEC")
+ADD_DEFINITIONS("-D_DROP_PRIVILEGE")
+ADD_DEFINITIONS("-D_FILE_OFFSET_BITS=64")
+
+IF (_ARM_TARGET)
+ ADD_DEFINITIONS("-DANDROID_GADGET=1")
+ENDIF (_ARM_TARGET)
+
+IF(TARGET_ARCH STREQUAL x86)
+ ADD_DEFINITIONS("-DTARGET_ARCH_X86")
+ELSE()
+ ADD_DEFINITIONS("-DTARGET_ARCH_ARM")
+ENDIF()
+
+IF(WEARABLE_PROFILE STREQUAL on)
+ ADD_DEFINITIONS("-D_WEARABLE")
+ENDIF()
+
+find_package(Threads REQUIRED)
+
+ADD_EXECUTABLE(sdbd ${SDBD_SRCS})
+TARGET_LINK_LIBRARIES(sdbd -pie -lsmack -lresolv -ldl ${CMAKE_THREAD_LIBS_INIT} ${pkgs_LDFLAGS})
+
+install(TARGETS sdbd DESTINATION /usr/sbin)
+++ /dev/null
-#
-#
-# Makefile for sdbd
-#
-
-#
-HOST_OS := $(shell uname -s | tr A-Z a-z)
-
-# sdb host tool
-# =========================================================
-
-SDBD_SRC_FILES := \
- src/sdb.c \
- src/fdevent.c \
- src/transport.c \
- src/transport_local.c \
- src/transport_usb.c \
- src/sockets.c \
- src/services.c \
- src/file_sync_service.c \
- src/usb_linux_client.c \
- src/utils.c \
- src/socket_inaddr_any_server.c \
- src/socket_local_client.c \
- src/socket_local_server.c \
- src/socket_loopback_client.c \
- src/socket_loopback_server.c \
- src/socket_network_client.c \
- src/sdktools.c \
- src/strutils.c \
- src/fileutils.c
-
-SDBD_CFLAGS := -O2 -g -DSDB_HOST=0 -Wall -Wno-unused-parameter
-SDBD_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
-SDBD_CFLAGS += -DHAVE_FORKEXEC -fPIE -D_DROP_PRIVILEGE -D_FILE_OFFSET_BITS=64
-SDBD_LFLAGS := -lcapi-system-info -lvconf -lsmack
-IFLAGS := -Iinclude -Isrc -I/usr/include/system -I/usr/include/vconf
-OBJDIR := bin
-INSTALLDIR := usr/sbin
-
-UNAME := $(shell uname -sm)
-ifneq (,$(findstring 86,$(UNAME)))
- HOST_ARCH := x86
-endif
-
-TARGET_ARCH = $(HOST_ARCH)
-ifeq ($(TARGET_ARCH),)
- TARGET_ARCH := arm
-endif
-
-ifeq ($(TARGET_ARCH),arm)
- MODULE := sdbd
- SDBD_CFLAGS += -DANDROID_GADGET=1
-else
-ifeq ($(TARGET_HOST),true)
- MODULE := sdb
-else
- MODULE := sdbd
-endif
-endif
-
-all : $(MODULE)
-
-sdbd : $(SDBD_SRC_FILES)
- mkdir -p $(OBJDIR)
- $(CC) -pthread -o $(OBJDIR)/$(MODULE) $(SDBD_CFLAGS) $(IFLAGS) $(SDBD_SRC_FILES) $(SDBD_LFLAGS)
-
-install :
- mkdir -p $(DESTDIR)/$(INSTALLDIR)
- install $(OBJDIR)/$(MODULE) $(DESTDIR)/$(INSTALLDIR)/$(MODULE)
-
-clean :
- rm -rf $(OBJDIR)/*
-* Thu Nov 27 2014 Sanghoon Hong <sanghoon.hong@samsung.com>
- - added a notify thread for emulator detection
- - fixed a broken connection issue while 'pull'ing files
* Wed Nov 27 2013 Yoonki Park <yoonki.park@samsung.com>
- changed port redirection to usb0 instead of loopback
* Wed Apr 04 2013 Ho Namkoong <ho.namkoong@samsung.com>
Name: sdbd
-Version: 2.2.23
+Version: 2.2.32
Release: 1
License: Apache-2.0
Summary: SDB daemon
Source1001: sdbd_device.service
Source1002: sdbd_emulator.service
-BuildRequires: capi-system-info-devel
-BuildRequires: vconf-devel
-BuildRequires: smack-devel
+BuildRequires: cmake
+#BuildRequires: sec-product-features
+BuildRequires: pkgconfig(libsmack)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(vasum)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dbus-1)
+BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(security-server)
Requires: default-files-tizen
Requires: sys-assert
Requires: debug-launchpad
Requires: dbus
+Requires: security-server
%description
Description: SDB daemon.
%setup -q
%build
+%if "%{?tizen_profile_name}" == "wearable"
+%define wearable_profile on
+%else
+%define wearable_profile off
+%endif
+%ifarch %{ix86}
+%define target_arch x86
+%else
+%define target_arch arm
+%endif
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+ -DWEARABLE_PROFILE=%{wearable_profile} \
+ -DTARGET_ARCH=%{target_arch}
+
make %{?jobs:-j%jobs}
%install
install -m 0644 %SOURCE1002 %{buildroot}%{_libdir}/systemd/system/sdbd.service
mkdir -p %{buildroot}/%{_libdir}/systemd/system/emulator.target.wants
ln -s %{_libdir}/systemd/system/sdbd.service %{buildroot}/%{_libdir}/systemd/system/emulator.target.wants/
-mkdir -p %{buildroot}%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
-ln -s %{_libdir}/systemd/system/sdbd.service %{buildroot}%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
-
%else
install -m 0644 %SOURCE1001 %{buildroot}%{_libdir}/systemd/system/sdbd.service
%endif
%{_libdir}/systemd/system/sdbd.service
%ifarch %{ix86}
%{_libdir}/systemd/system/emulator.target.wants/sdbd.service
-%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/sdbd.service
%endif
/usr/share/license/%{name}
/usr/bin/profile_command
%changelog
+* Thu Jul 13 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Supported 'boot' protocol to get status of platform booting
+- Add new protocol "capability" to get the platform capability information
+
+* Thu Jun 15 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Added to network smack rule for emulator guest IP (10.0.2.15)
+- Removed to create sdb_port.txt file
+
+* Thu Jun 8 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Used CMake
+
+* Thu Jun 2 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Added to ask sdb server to connect emulator with bridged network.
+
+* Thu May 23 2015 - Shingil Kang <shingil.kang@samsung.com>
+- notify_sdbd_startup_thread() added.
+
+* Thu May 21 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Removed systemd dependency of zone
+- Set default dependency off
+- Removed requires(post) condition
+
+* Mon Apr 30 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Fix a bug for sdb 'push' into /opt, /var, /root, /home in foreground zone shell mode
+- Change to apply connection mode (zone/host/denied) in boot time
+
+* Mon Apr 21 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Execute debug-launchpad when zone is started
+* Mon Apr 18 2015 - Shingil Kang <shingil.kang@samsung.com>
+- Change "sdb forward" command to be zone-aware
[Unit]
Description=sdbd
+After=tmp.mount
[Service]
Type=forking
[Unit]
Description=sdbd
+After=tmp.mount dbus.service
+#DefaultDependencies=false
[Service]
Type=forking
Environment=DISPLAY=:0
PIDFile=/tmp/.sdbd.pid
RemainAfterExit=yes
-ExecStartPre=/bin/bash -c "/bin/echo `/bin/sed 's/^.*sdb_port=\([^, ]*\).*$/\1/g' /proc/cmdline` > /opt/home/sdb_port.txt"
+ExecStartPre=/bin/bash -c "/bin/echo '10.0.2.15/32 system::debugging_network' >> /smack/netlabel"
ExecStart=/usr/sbin/sdbd
[Install]
#!/bin/bash
-VERSION="3.0"
+VERSION="4.0"
KILL=/usr/bin/killall
MANAGER=/usr/bin/da_manager
FIND=/usr/bin/find
GETAPPINSTALLPATH="/usr/bin/pkgcmd -a"
PORTFILE=/tmp/port.da
-READLINK=/usr/bin/readlink
print_usage()
{
echo "usage: profile_command [options]"
echo "Options:"
- echo "getprobemap get da_api_map"
- echo "killmanager terminate da_manager"
- echo "runmanager execute da_manager"
- echo "findunittest find unittest project"
+ echo "getprobemap get da_api_map"
+ echo "killmanager terminate da_manager"
+ echo "runmanager execute da_manager"
+ echo "findunittest find unittest project"
echo "getversion get version"
echo "killvalgrind kill valgrind process"
- echo "readlink filepath get value of given symbolic link or canonical file name"
}
get_probe_map()
process_list()
{
- /bin/ps -eo pid,cmd
+ /bin/ps -ewo pid,cmd
}
get_version()
echo $VERSION
}
-read_link()
-{
- $READLINK -f $FILEPATH
-}
-
kill_valgrind()
{
/bin/ps ax | /bin/grep "/home/developer/sdk_tools/valgrind/usr/bin/valgrin[d]" | /usr/bin/awk '{print "kill -3 " $1}' | /bin/sh
}
-if test $# -gt 2 -o $# -lt 1; then
+if test $# -ne 1 ; then
print_usage
exit 1
fi
-if test -n "$2"; then
- case "$1" in
- readlink)
- FILEPATH=$2
- ;;
- *)
- print_usage
- exit 1
- ;;
- esac
-fi
-
case "$1" in
killmanager)
kill_manager
getversion)
get_version
;;
- readlink)
- read_link
- ;;
killvalgrind)
- kill_valgrind
- ;;
- getprobemap)
- get_probe_map
- ;;
+ kill_valgrind
+ ;;
+ getprobemap)
+ get_probe_map
+ ;;
*)
echo "Unknown option!"
print_usage
if [ "" != "$attach_id" ]
#debug attach
then
- cmd="$COV_TEST_PREFIX /home/developer/sdk_tools/gdbserver/gdbserver :$port --attach $attach_id"
+ cmd="/usr/bin/launch_debug $launch_app_arg1 __AUL_SDK__ ATTACH __DLP_ATTACH_ARG__ --attach,:$port,$attach_id"
#debug
else
if [ "" != "$result_mode" ]
<smack request="system::debugging_network" type="w" />
<smack request="device::input" type="rwx" />
<smack request="*" type="rwxat" />
+ <smack request="tizen::vconf::platform::rw" type="r" />
+ <smack request="tizen::vconf::public::r::platform::rw" type="r" />
+ <smack request="tizen::vconf::setting::admin" type="r" />
+ <smack request="procps" type="rx" />
+ <smack request="security-server::label" type="w" />
</request>
<permit>
<smack permit="system::use_internet" type="w" />
<smack permit="wrt::wrt-launcher" type="rw" />
</permit>
</define>
+ <assign>
+ <filesystem path="/usr/lib/*" label="_" exec_label="none"/>
+ </assign>
<request>
<domain name="sdbd" />
</request>
*/
if (sdb_dirstart(hint) != NULL) {
if (getcwd(path_buf, sizeof(path_buf)) == NULL) {
- fprintf(stderr, "sdb: Couldn't get CWD: %s\n", strerror(errno));
+ fprintf(stderr, "sdb: Couldn't get CWD: errno:%d\n", errno);
return NULL;
}
if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) {
lfd = sdb_open(path, O_RDONLY);
if(lfd < 0) {
- fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno));
+ fprintf(stderr,"cannot open '%s': errno:%d\n", path, errno);
return -1;
}
if(ret < 0) {
if(errno == EINTR)
continue;
- fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno));
+ fprintf(stderr,"cannot read '%s': errno:%d\n", path, errno);
break;
}
len = readlink(path, sbuf->data, SYNC_DATA_MAX-1);
if(len < 0) {
- fprintf(stderr, "error reading link '%s': %s\n", path, strerror(errno));
+ fprintf(stderr, "error reading link '%s': errno:%d\n", path, errno);
return -1;
}
sbuf->data[len] = '\0';
// this requires that we read the entire file into memory.
lfd = sdb_open(lpath, O_RDONLY);
if(lfd < 0) {
- fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));
+ fprintf(stderr,"cannot open '%s': errno:%d\n", lpath, errno);
return -1;
}
mkdirs((char *)lpath);
lfd = sdb_creat(lpath, 0644);
if(lfd < 0) {
- fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno));
+ fprintf(stderr,"cannot create '%s': errno:%d\n", lpath, errno);
return -1;
}
goto handle_data;
}
if(writex(lfd, buffer, len)) {
- fprintf(stderr,"cannot write '%s': %s\n", rpath, strerror(errno));
+ fprintf(stderr,"cannot write '%s': errno:%d\n", rpath, errno);
sdb_close(lfd);
return -1;
}
d = opendir(lpath);
if(d == 0) {
- fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));
+ fprintf(stderr,"cannot open '%s': errno:%d\n", lpath, errno);
return -1;
}
} else {
ci = mkcopyinfo(lpath, rpath, name, 0);
if(lstat(ci->src, &st)) {
- fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno));
+ fprintf(stderr,"cannot stat '%s': errno:%d\n", ci->src, errno);
closedir(d);
return -1;
}
if(stat(lpath, &st)) {
- fprintf(stderr,"cannot stat '%s': %s\n", lpath, strerror(errno));
+ fprintf(stderr,"cannot stat '%s': errno:%d\n", lpath, errno);
sync_quit(fd);
return 1;
}
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/smack.h>
+#include <security-server.h>
#include "sysdeps.h"
#define TRACE_TAG TRACE_SYNC
#include "sdb.h"
+#include "sdbd_plugin.h"
#include "file_sync_service.h"
#include "sdktools.h"
#include "utils.h"
#define SYNC_TIMEOUT 15
-struct sync_permit_rule
-{
- const char *name;
- const char *regx;
- int mode; // 0:push, 1: pull, 2: push&push
-};
-
-struct sync_permit_rule sdk_sync_permit_rule[] = {
-// /* 0 */ {"rds", "^((/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/info/\\.sdk_delta\\.info$", 1},
- /* 1 */ {"unitest", "^((/tmp)|(/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data/[a-zA-Z0-9_\\-]{1,50}\\.xml$", 1},
- /* 2 */ {"codecoverage", "^((/tmp)|(/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data/+(.)*\\.gcda$", 1},
- /* 3 */ {"da", "^(/tmp/da/)*+[a-zA-Z0-9_\\-\\.]{1,50}\\.png$", 1},
- /* end */ {NULL, NULL, 0}
-};
-
/* The typical default value for the umask is S_IWGRP | S_IWOTH (octal 022).
* Before use the DIR_PERMISSION, the process umask value should be set 0 using umask().
*/
#define DIR_PERMISSION 0777
-int is_install_pkg_file = 0;
-
static void set_syncfile_smack_label(char *src) {
char *label_transmuted = NULL;
char *label = NULL;
int pos = src_chr - src + 1;
char dirname[512];
- if (getuid() != 0) {
- D("need root permission to set smack label: %d\n", getuid());
- return;
- }
-
snprintf(dirname, pos, "%s", src);
//D("src:[%s], dirname:[%s]\n", src, dirname);
if (!strcmp("TRUE", label_transmuted)) {
rc = smack_getlabel(dirname, &label, SMACK_LABEL_ACCESS);
if (rc == 0 && label != NULL) {
- if (smack_setlabel(src, label, SMACK_LABEL_ACCESS) == -1) {
- D("unable to set sync file smack label %s due to %s\n", label, strerror(errno));
+ rc = security_server_label_access(src, label);
+ if (rc != SECURITY_SERVER_API_SUCCESS) {
+ D("unable to set sync file smack label %s due to %d\n", label, errno);
}
free(label);
}
}
free(label_transmuted);
} else {
- if (smack_setlabel(src, SMACK_SYNC_FILE_LABEL, SMACK_LABEL_ACCESS) == -1) {
- D("unable to set sync file smack label %s due to (errno:%d)\n", SMACK_SYNC_FILE_LABEL, errno);
+ rc = security_server_label_access(src, SMACK_SYNC_FILE_LABEL);
+ if (rc != SECURITY_SERVER_API_SUCCESS) {
+ D("unable to set sync file smack label %s due to %d\n", SMACK_SYNC_FILE_LABEL, errno);
}
}
}
static void sync_read_label_notify(int s)
{
- char buffer[512] = {0,};
+ char buffer[512 + 1] = {0,};
while (1) {
- int len = sdb_read(s, buffer, sizeof(buffer));
+ int len = sdb_read(s, buffer, sizeof(buffer) - 1);
if (len < 0) {
- D("sync notify read error : (errno:%d)\n", errno);
+ D("sync notify read errno:%d\n", errno);
exit(-1);
}
D("sync notify child process exit\n");
exit(-1);
}
- buffer[511] = '\0';
+ buffer[len] = '\0';
char *path = buffer;
path++;
path++;
sync_send_label_notify(noti_fd, name, 1);
}
if((ret < 0) && (errno != EEXIST)) {
- D("mkdir(\"%s\") -> (errno:%d)\n", name, errno);
+ D("mkdir(\"%s\") -> errno:%d\n", name, errno);
*x = '/';
return ret;
}
msg.stat.mode = 0;
msg.stat.size = 0;
msg.stat.time = 0;
- D("failed to stat %s due to: (errno:%d)\n", path, errno);
+ D("failed to stat %s due to: errno:%d\n", path, errno);
} else {
msg.stat.mode = htoll(st.st_mode);
msg.stat.size = htoll(st.st_size);
char tmp[1024 + 256 + 1];
char *fname;
+ char dirent_buffer[ sizeof(struct dirent) + 260 + 1 ] = {0,};
+ struct dirent *dirent_r = (struct dirent*)dirent_buffer;
+
len = strlen(path);
memcpy(tmp, path, len);
tmp[len] = '/';
d = opendir(path);
if(d == NULL) {
- D("failed to open dir due to: (errno:%d)\n", errno);
+ D("failed to open dir due to: errno:%d\n", errno);
goto done;
}
- while((de = readdir(d))) {
+ while((readdir_r(d, dirent_r, &de) == 0) && de) {
int len = strlen(de->d_name);
/* not supposed to be possible, but
static int fail_errno(int s)
{
- char err_msg[20] = {0, };
- snprintf(err_msg, sizeof(err_msg), "(errno:%d)", errno);
- return fail_message(s, err_msg);
+ char buf[512];
+
+ strerror_r(s, buf, sizeof(buf));
+
+ return fail_message(s, buf);
}
// FIXME: should get the following paths with api later but, do it for simple and not having dependency on other packages
+#define VAR_ABS_PATH "/opt/var"
+#define VSM_ZONE_PATH "/var/lib/lxc/"
+#define VSM_ZONE_ROOTFS "rootfs/"
#define CMD_MEDIADB_UPDATE "/usr/bin/mediadb-update"
#define MEDIA_CONTENTS_PATH1 "/opt/media"
#define MEDIA_CONTENTS_PATH2 "/opt/usr/media"
#define MEDIA_CONTENTS_PATH3 "/opt/storage/sdcard"
static void sync_mediadb(char *path) {
+ int is_inzone = 0;
+
if (access(CMD_MEDIADB_UPDATE, F_OK) != 0) {
D("%s: command not found\n", CMD_MEDIADB_UPDATE);
return;
}
- if (strstr(path, MEDIA_CONTENTS_PATH1) != NULL) {
- char *arg_list[] = {CMD_MEDIADB_UPDATE, "r", MEDIA_CONTENTS_PATH1, NULL};
+ if (strstr(path, VAR_ABS_PATH) == path) {
+ path += 4;
+ }
+ if (strstr(path, VSM_ZONE_PATH) == path) {
+ path += sizeof(VSM_ZONE_PATH) - 1;
+ while (*(path++) != '/');
+ while (*(path++) == '/');
+ path--;
- spawn(CMD_MEDIADB_UPDATE, arg_list);
- D("media db update done to %s\n", MEDIA_CONTENTS_PATH1);
- } else if (strstr(path, MEDIA_CONTENTS_PATH2) != NULL) {
- char *arg_list[] = {CMD_MEDIADB_UPDATE, "r", MEDIA_CONTENTS_PATH2, NULL};
+ if (strstr(path, VSM_ZONE_ROOTFS) == path) {
+ path += sizeof(VSM_ZONE_ROOTFS) - 1;
+ while (*(path++) == '/');
+ path -= 2;
+ is_inzone = 1;
+ }
+ }
- spawn(CMD_MEDIADB_UPDATE, arg_list);
+ if (strstr(path, MEDIA_CONTENTS_PATH1) != NULL) {
+ if (is_inzone) {
+ char *arg_list[] = {CMD_ATTACH, "-f", "--", CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH1, NULL};
+ spawn(CMD_ATTACH, arg_list);
+ } else {
+ char *arg_list[] = {CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH1, NULL};
+ spawn(CMD_MEDIADB_UPDATE, arg_list);
+ D("media db update done to %s\n", MEDIA_CONTENTS_PATH1);
+ }
+ } else if (strstr(path, MEDIA_CONTENTS_PATH2) != NULL) {
+ if (is_inzone) {
+ char *arg_list[] = {CMD_ATTACH, "-f", "--", CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH2, NULL};
+ spawn(CMD_ATTACH, arg_list);
+ } else {
+ char *arg_list[] = {CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH2, NULL};
+ spawn(CMD_MEDIADB_UPDATE, arg_list);
+ }
D("media db update done to %s\n", MEDIA_CONTENTS_PATH2);
} else if (strstr(path, MEDIA_CONTENTS_PATH3) != NULL) {
- char *arg_list[] = {CMD_MEDIADB_UPDATE, "r", MEDIA_CONTENTS_PATH3, NULL};
-
- spawn(CMD_MEDIADB_UPDATE, arg_list);
+ if (is_inzone) {
+ char *arg_list[] = {CMD_ATTACH, "-f", "--", CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH3, NULL};
+ spawn(CMD_ATTACH, arg_list);
+ } else {
+ char *arg_list[] = {CMD_MEDIADB_UPDATE, "-r", MEDIA_CONTENTS_PATH3, NULL};
+ spawn(CMD_MEDIADB_UPDATE, arg_list);
+ }
D("media db update done to %s\n", MEDIA_CONTENTS_PATH3);
}
return;
}
#endif /* HAVE_SYMLINKS */
+static int is_support_push()
+{
+ return (!strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PUSHPULL, strlen(SDBD_CAP_RET_PUSHPULL))
+ || !strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PUSH, strlen(SDBD_CAP_RET_PUSH)));
+}
+
+static int is_support_pull()
+{
+ return (!strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PUSHPULL, strlen(SDBD_CAP_RET_PUSHPULL))
+ || !strncmp(g_capabilities.filesync_support, SDBD_CAP_RET_PULL, strlen(SDBD_CAP_RET_PULL)));
+}
+
static int do_send(int s, int noti_fd, char *path, char *buffer)
{
char *tmp;
mode_t mode;
int is_link, ret;
+ // Check the capability for file push support.
+ if(!is_support_push()) {
+ fail_message(s, "NO support file push.");
+ return -1;
+ }
+
tmp = strrchr(path,',');
if(tmp) {
*tmp = 0;
mode = 0644; // set default permission value in most of unix system.
is_link = 0;
}
- if(is_install_pkg_file) {
- mode = 0444;
+ if (is_pkg_file_path(path)) {
+ mode = 0644;
is_link = 0;
}
syncmsg msg;
int fd, r;
+ // Check the capability for file push support.
+ if (!is_support_pull()) {
+ fail_message(s, "NO support file pull.");
+ return -1;
+ }
+
fd = sdb_open(path, O_RDONLY);
if(fd < 0) {
if(fail_errno(s)) return -1;
return 0;
}
-static int verify_sync_rule(const char* path) {
- regex_t regex;
- int ret;
- char buf[PATH_MAX];
- int i=0;
+static pid_t get_zone_init_pid(const char *name) {
+ char filename[PATH_MAX];
+ FILE *fp;
+ pid_t ret = -1;
- // to prevent hijacking the pkg file.
- if (is_pkg_file_path(path)) {
- is_install_pkg_file = 1;
- D("matched pkg file path: to prevent hijacking the pkg file\n");
- return 1;
- }
+ snprintf(filename, sizeof(filename),
+ "/sys/fs/cgroup/devices/lxc/%s/cgroup.procs", name);
- for (i=0; sdk_sync_permit_rule[i].regx != NULL; i++) {
- ret = regcomp(®ex, sdk_sync_permit_rule[i].regx, REG_EXTENDED);
- if(ret){
- return 0;
- }
- // execute regular expression
- ret = regexec(®ex, path, 0, NULL, 0);
- if(!ret){
- regfree(®ex);
- D("found matched rule(%s) from %s path\n", sdk_sync_permit_rule[i].name, path);
- return 1;
- } else if( ret == REG_NOMATCH ){
- // do nothin
- } else{
- regerror(ret, ®ex, buf, sizeof(buf));
- D("regex match failed(%s): %s\n",sdk_sync_permit_rule[i].name, buf);
+ fp = fopen(filename, "r");
+
+ if (fp != NULL) {
+ if (fscanf(fp, "%d", &ret) < 0) {
+ D("Failed to read %s\n", filename);
+ ret = -2;
}
+ fclose(fp);
+ } else {
+ D("Unable to access %s\n", filename);
+ ret = errno;
}
- regfree(®ex);
- return 0;
+ return ret;
}
void file_sync_service(int fd, void *cookie)
struct timeval timeout;
int rv;
int s[2];
- is_install_pkg_file = 0;
+ char zone_path[1025] = {0, };
+ char name_vsm[1025] = {0, };
if(sdb_socketpair(s)) {
D("cannot create service socket pair\n");
FD_ZERO(&set); /* clear the set */
FD_SET(fd, &set); /* add our file descriptor to the set */
+ timeout.tv_sec = SYNC_TIMEOUT;
+ timeout.tv_usec = 0;
+
pid_t pid = fork();
if (pid == 0) {
sync_read_label_notify(s[1]);
} else if (pid > 0) {
sdb_close(s[1]);
+
+ if (hostshell_mode == 0) {
+ FILE *fp;
+ fp = popen("/usr/bin/vsm-foreground", "r");
+ if (fp == NULL) {
+ D("Failed to create pipe of vsm-foreground\n");
+ goto fail;
+ }
+ fgets(name_vsm, 1025, fp);
+ pclose(fp);
+
+ //trim zone name
+ namelen = strlen(name_vsm);
+ while (name_vsm[--namelen] == '\n')
+ ;
+ name_vsm[namelen + 1] = '\0';
+ snprintf(zone_path, 1025, "/proc/%d/root",
+ get_zone_init_pid(name_vsm));
+ chroot(zone_path);
+ chdir("/");
+ }
+
for(;;) {
D("sync: waiting for command for %d sec\n", SYNC_TIMEOUT);
- // in Linux, timeout would be altered after each select() call.
- // Therefore, re-initialization is needed.
- timeout.tv_sec = SYNC_TIMEOUT;
- timeout.tv_usec = 0;
rv = select(fd + 1, &set, NULL, NULL, &timeout);
if (rv == -1) {
D("sync file descriptor select failed\n");
msg.req.namelen = 0;
D("sync: '%s' '%s'\n", (char*) &msg.req, name);
- if (should_drop_privileges() && !verify_sync_rule(name)) {
+ if (should_drop_privileges()) {
set_developer_privileges();
}
SDB_MUTEX(dns_lock)
SDB_MUTEX(socket_list_lock)
SDB_MUTEX(transport_lock)
+SDB_MUTEX(zone_check_lock);
#if SDB_HOST
SDB_MUTEX(local_transports_lock)
#endif
if (cc < 0) {
// ENOENT means socket file doesn't exist
// ECONNREFUSED means socket exists but nobody is listening
- D("AF_UNIX connect failed for '%s': %s\n",
- fileName, strerror(errno));
+ D("AF_UNIX connect failed for '%s': errno:%d\n",
+ fileName, errno);
sdb_close(sock);
return -1;
}
fd = open("/dev/qemu_pipe", O_RDWR);
if (fd < 0) {
- D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno));
+ D("%s: Could not open /dev/qemu_pipe: errno:%d", __FUNCTION__, errno);
//errno = ENOSYS;
return -1;
}
ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1));
if (ret != buffLen+1) {
- D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno));
+ D("%s: Could not connect to %s pipe service: errno:%d", __FUNCTION__, pipeName, errno);
if (ret == 0) {
errno = ECONNRESET;
} else if (ret > 0) {
#include <signal.h>
#include <grp.h>
#include <pthread.h>
+#include <dlfcn.h>
#include "sysdeps.h"
#include "sdb.h"
#include "strutils.h"
#include "utils.h"
+#include "sdktools.h"
#if !SDB_HOST
#include <linux/prctl.h>
#else
#include "usb_vendors.h"
#endif
-#include <system_info_internal.h>
+#include <system_info.h>
#include <vconf.h>
#include "utils.h"
-
#define PROC_CMDLINE_PATH "/proc/cmdline"
#define USB_SERIAL_PATH "/sys/class/usb_mode/usb0/iSerial"
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#define GUEST_IP_INTERFACE "eth0"
+
+SDB_MUTEX_DEFINE(zone_check_lock);
#if SDB_TRACE
SDB_MUTEX_DEFINE( D_lock );
#endif
int HOST = 0;
+int initial_zone_mode_check = 0;
+
+void* g_sdbd_plugin_handle = NULL;
+SDBD_PLUGIN_CMD_PROC_PTR sdbd_plugin_cmd_proc = NULL;
int is_emulator(void) {
- if (access(USB_NODE_FILE, F_OK) == 0) {
+/* XXX: If the target device supports x86 architecture,
+ * this routine is INVALID. */
+#ifdef TARGET_ARCH_X86
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+int is_container_enabled(void) {
+ bool value;
+ int ret;
+ ret = system_info_get_platform_bool("tizen.org/feature/container", &value);
+ if (ret != SYSTEM_INFO_ERROR_NONE) {
+ D("failed to get container information: %d\n", errno);
+ return 0;
+ } else {
+ D("tizen container: %d\n", value);
+ if (value == true)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+int has_container(void) {
+ FILE *fp;
+ char name_vsm[1025] = {0, };
+ char empty_vsm[1025] = {0, };
+ fp = popen(CMD_LIST, "r");
+ if(fp == NULL) {
+ D("Failed to create pipe of %s \n", CMD_LIST);
return 0;
- } else {
+ }
+ fgets(name_vsm, 1025, fp);
+ pclose(fp);
+
+ D("zone list :%s\n", name_vsm);
+ // check zone list
+ if((name_vsm[0] == '\n') || !strncmp(name_vsm, empty_vsm, 1025))
+ return 0;
+ else
return 1;
+}
+
+char** get_zone_list() {
+ FILE *fp;
+ char name_vsm[1025] = {0, };
+ char empty_vsm[1025] = {0, };
+ fp = popen(CMD_LIST, "r");
+ if(fp == NULL) {
+ D("Failed to create pipe of %s \n", CMD_LIST);
+ return 0;
+ }
+ fgets(name_vsm, 1025, fp);
+ pclose(fp);
+
+ D("zone list :%s\n", name_vsm);
+
+ if((name_vsm[0] == '\n') || !strncmp(name_vsm, empty_vsm, 1025))
+ return NULL;
+ else {
+ char** tokens = str_split(name_vsm, '\n');
+ return tokens;
}
}
sdb_unlink(SDB_PIDPATH);
#endif
char *cmd1_args[] = {"/usr/bin/killall", "/usr/bin/debug_launchpad_preloading_preinitializing_daemon", NULL};
-
- if (!is_emulator()) {
- int val = 0;
- if (vconf_get_int(DEBUG_MODE_KEY, &val)) {
- D("Failed to get debug mode\n");
- } else {
- if (usb_mode != 6 && val == 6) { // set mtp mode by default!.
- vconf_set_int(DEBUG_MODE_KEY, 2);
- }
- }
- } else {
- // do nothing on a emulator
- }
spawn("/usr/bin/killall", cmd1_args);
sdb_sleep_ms(1000);
}
{
va_list ap;
va_start(ap, fmt);
- fprintf(stderr, "error: (errno:%d): ", errno);
+ fprintf(stderr, "errno: %d: ", errno);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
return port;
}
-int get_emulator_name(char str[], int str_size) {
+static int get_cmdline_value(char *split, char str[], int str_size) {
char cmdline[512];
int fd = unix_open(PROC_CMDLINE_PATH, O_RDONLY);
- char *name_str = "vm_name=";
if (fd < 0) {
D("fail to read /proc/cmdline\n");
}
if(read_line(fd, cmdline, sizeof(cmdline))) {
D("qemu cmd: %s\n", cmdline);
- if (get_str_cmdline(cmdline, name_str, str, str_size) < 1) {
- D("could not get emulator name from cmdline\n");
+ if (get_str_cmdline(cmdline, split, str, str_size) < 1) {
+ D("could not get the (%s) value from cmdline\n", split);
sdb_close(fd);
return -1;
}
return 0;
}
+int get_emulator_name(char str[], int str_size) {
+ return get_cmdline_value("vm_name=", str, str_size);
+}
+
int get_device_name(char str[], int str_size) {
char *value = NULL;
- int r = system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &value);
+ int r = system_info_get_platform_string("http://tizen.org/system/model_name", &value);
if (r != SYSTEM_INFO_ERROR_NONE) {
D("fail to get system model:%d\n", errno);
return -1;
return -1;
}
+int get_emulator_hostip(char str[], int str_size) {
+ return get_cmdline_value("host_ip=", str, str_size);
+}
+
+int get_emulator_guestip(char str[], int str_size) {
+ int s;
+ struct ifreq ifr;
+ struct sockaddr_in *sin;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if(s < 0) {
+ D("socket error\n");
+ return -1;
+ }
+
+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", GUEST_IP_INTERFACE);
+ if(ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+ D("ioctl hwaddr error\n");
+ sdb_close(s);
+ return -1;
+ }
+
+ if(ioctl(s, SIOCGIFADDR, &ifr) < 0) {
+ D("ioctl addr error\n");
+ sdb_close(s);
+ return -1;
+ }
+ sin = (struct sockaddr_in *)&ifr.ifr_addr;
+ snprintf(str, str_size, "%s", inet_ntoa(sin->sin_addr));
+ sdb_close(s);
+
+ return 0;
+}
+
void parse_banner(char *banner, atransport *t)
{
char *type, *product, *end;
if (is_pwlocked() && t->connection_state == CS_PWLOCK) { // in case of already locked before get A_CNXN
D("open failed due to password locked before get A_CNXN:%d\n", t->connection_state);
send_close(0, p->msg.arg0, t);
+ } else if (hostshell_mode == 2){
+ D("open failed due to denied mode\n");
+ send_close(0, p->msg.arg0, t);
} else {
if(t->connection_state != CS_OFFLINE) {
char *name = (char*) p->data;
fd = sdb_socket_accept(_fd, &addr, &alen);
if(fd < 0) return;
- if (sdb_socket_setbufsize(fd, CHUNK_SIZE) == -1) {
- D("failed to set buffer size of sdb socket: (errno:%d)\n", errno);
- }
+ sdb_socket_setbufsize(fd, CHUNK_SIZE);
s = create_local_socket(fd);
if(s) {
static void sdb_cleanup(void)
{
+ if (g_sdbd_plugin_handle) {
+ dlclose(g_sdbd_plugin_handle);
+ g_sdbd_plugin_handle = NULL;
+ }
usb_cleanup();
}
pwlock_status = 0;
D("failed to get pw lock status\n");
}
+#ifdef _WEARABLE
+ D("wearable lock applied\n");
+ // for wearable which uses different VCONF key (lock type)
+ if (vconf_get_int(VCONFKEY_SETAPPL_PRIVACY_LOCK_TYPE_INT, &pwlock_type)) {
+ pwlock_type = 0;
+ D("failed to get pw lock type\n");
+ }
+ if ((pwlock_status == VCONFKEY_IDLE_LOCK) && (pwlock_type != SETTING_PRIVACY_LOCK_TYPE_NONE)) {
+ D("device has been locked\n");
+ return 1; // locked!
+ }
+#else
+ D("mobile lock applied\n");
+ // for mobile
if (vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT, &pwlock_type)) {
pwlock_type = 0;
D("failed to get pw lock type\n");
}
- if (pwlock_status == VCONFKEY_IDLE_LOCK && (pwlock_type == SETTING_SCREEN_LOCK_TYPE_SIMPLE_PASSWORD || pwlock_type == SETTING_SCREEN_LOCK_TYPE_PASSWORD)) {
+ if (pwlock_status == VCONFKEY_IDLE_LOCK && ((pwlock_type != SETTING_SCREEN_LOCK_TYPE_NONE) && (pwlock_type != SETTING_SCREEN_LOCK_TYPE_SWIPE))) {
D("device has been locked\n");
return 1; // locked!
}
-
+#endif
return 0; // unlocked!
}
}
}
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#define BOOTING_DONE_SIGNAL "BootingDone"
+#define DEVICED_CORE_INTERFACE "org.tizen.system.deviced.core"
+#define SDBD_BOOT_INFO_FILE "/tmp/sdbd_boot_info"
+
+static DBusHandlerResult __sdbd_dbus_signal_filter(DBusConnection *conn,
+ DBusMessage *message, void *user_data) {
+ D("got dbus message\n");
+ const char *interface;
+
+ DBusError error;
+ dbus_error_init(&error);
+
+ interface = dbus_message_get_interface(message);
+ if (interface == NULL) {
+ D("reject by security issue - no interface\n");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ if (dbus_message_is_signal(message, DEVICED_CORE_INTERFACE,
+ BOOTING_DONE_SIGNAL)) {
+ booting_done = 1;
+ if (access(SDBD_BOOT_INFO_FILE, F_OK) == 0) {
+ D("booting is done before\n");
+ } else {
+ FILE *f = fopen(SDBD_BOOT_INFO_FILE, "w");
+ if (f != NULL) {
+ fprintf(f, "%d", 1);
+ fclose(f);
+ }
+ }
+ D("booting is done\n");
+ }
+
+ D("handled dbus message\n");
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static void *bootdone_cb(void *x) {
+ int MAX_LOCAL_BUFSZ = 128;
+ DBusError error;
+ DBusConnection *bus;
+ char rule[MAX_LOCAL_BUFSZ];
+ GMainLoop *mainloop;
+
+ g_type_init();
+
+ dbus_error_init(&error);
+ bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (!bus) {
+ D("Failed to connect to the D-BUS daemon: %s", error.message);
+ dbus_error_free(&error);
+ return -1;
+ }
+ dbus_connection_setup_with_g_main(bus, NULL);
+
+ snprintf(rule, MAX_LOCAL_BUFSZ, "type='signal',interface='%s'",
+ DEVICED_CORE_INTERFACE);
+ /* listening to messages */
+ dbus_bus_add_match(bus, rule, &error);
+ if (dbus_error_is_set(&error)) {
+ D("Fail to rule set: %s", error.message);
+ dbus_error_free(&error);
+ return -1;
+ }
+
+ if (dbus_connection_add_filter(bus, __sdbd_dbus_signal_filter, NULL, NULL)
+ == FALSE)
+ return -1;
+
+ D("booting signal initialized\n");
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+
+ D("dbus loop exited");
+
+ return 0;
+}
+
+void register_bootdone_cb() {
+ D("registerd bootdone callback\n");
+
+ sdb_thread_t t;
+ if (sdb_thread_create(&t, bootdone_cb, NULL)) {
+ D("cannot create service thread\n");
+ return;
+ }
+}
+
int set_developer_privileges() {
gid_t groups[] = { SID_DEVELOPER, SID_APP_LOGGING, SID_SYS_LOGGING, SID_INPUT };
if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
- D("set groups failed (errno: %d, %s)\n", errno, strerror(errno));
+ D("set groups failed (errno: %d)\n", errno);
}
// then switch user and group to developer
if (setgid(SID_DEVELOPER) != 0) {
- D("set group id failed (errno: %d, %s)\n", errno, strerror(errno));
+ D("set group id failed (errno: %d)\n", errno);
return -1;
}
}
}
// TODO: use pam later
- putenv("HOME=/home/developer");
+ setenv("HOME", "/home/developer", 1);
return 1;
}
spawn("/usr/bin/debug_launchpad_preloading_preinitializing_daemon", cmd_args);
}
-static void init_sdk_requirements() {
- struct stat st;
+#include <stdio.h>
+#include <glib.h>
+#include <vasum.h>
+
+static const char *const state_string[] = {
+ "STOPPED",
+ "STARTING",
+ "RUNNING",
+ "STOPPING",
+ "ABORTING",
+ "FREEZING",
+ "THAWED",
+};
+
+static const char *const event_string[] = {
+ "NONE",
+ "CREATED",
+ "DESTROYED",
+ "SWITCHED",
+};
+
+static void execute_required_process_in_each_zone(char* zone_name) {
+ D("Name of zone which executes required processes : %s \n", zone_name);
+
+ // debug-launchpad need to be executed in each zone
+ char zone_name_with_option[100] = {0,};
+ snprintf(zone_name_with_option, sizeof(zone_name_with_option), "--name=%s", zone_name);
+ char *arg_list[] = {CMD_ATTACH, zone_name_with_option, "--", "/usr/bin/debug_launchpad_preloading_preinitializing_daemon", NULL};
+ spawn(CMD_ATTACH, arg_list);
+}
+
+static int vasum_zone_state_cb( vsm_zone_h zone, vsm_zone_state_t state, void * userdata)
+{
+ char * zone_name;
+ vsm_zone_state_t before_state, new_state;
+
+ zone_name = vsm_get_zone_name(zone);
+ before_state = vsm_get_zone_state(zone);
+ new_state = state;
+
+ D("Zone state is changed : Name[%s] , Before State[%s], Changed State[%s]\n",
+ zone_name , state_string[state], state_string[state]);
+
+
+ if(state == 2) {
+ sdb_mutex_lock(&zone_check_lock);
+ // if state of zone is "RUNNING", execute required process in zone.
+ execute_required_process_in_each_zone(zone_name);
+
+ // in the case sdbd is started up before zone, check zone/host mode
+ if(!initial_zone_mode_check) {
+ D("set zone mode on when zone is started up\n");
+ initial_zone_mode_check = 1;
+ hostshell_mode = 0;
+ }
+ sdb_mutex_unlock(&zone_check_lock);
+ }
+
+
+ return 0;
+}
+
+static int vasum_event_cb( vsm_zone_h zone, vsm_zone_event_t event, void * userdata)
+{
+ char * zone_name;
+
+ zone_name = vsm_get_zone_name(zone);
+
+ D("Zone got event : Name[%s], Event[%s]\n", zone_name, event_string[event]);
+
+ return 0;
+}
+
+static gboolean vasum_context_callback(GIOChannel * channel, GIOCondition condition,
+ void *data)
+{
+ vsm_context_h ctx = (vsm_context_h)data;
+ /* Call handler function for update vsm_context */
+ vsm_enter_eventloop(ctx, 0, 0);
+ return TRUE;
+}
+
+
+static void *zone_check_thread(void *x) {
+ GMainLoop *mainloop;
+ vsm_context_h ctx;
+ int fd, ret;
+ int state_hndl = 0;
+ int event_hndl = 0;
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+
+ int i;
+ for(i = 0; i < 10; i++) {
+ D("Try to get vasum context : try %d\n", i);
+ ctx = vsm_create_context();
+ if (ctx != NULL) {
+ D("Got vasum context\n");
+ break;
+ }
+ if(i == 9) {
+ D("Failed to get vasum context, exit vasum zone check thread\n");
+ return;
+ }
+ D("Failed get vasum context\n");
+ sdb_sleep_ms(100);
+ }
+
+ /* Get vasum event file descriptor from vsm context */
+ fd = vsm_get_poll_fd(ctx);
+ if (fd < 0) {
+ D("Failed to get poll fd\n");
+ }
+
+ GIOChannel *channel = g_io_channel_unix_new(fd);
+ if (channel == NULL) {
+ D("Failed to allocate channel allocation\n");
+ return;
+ }
+
+ /* Bind vasum context to g_main_loop watch handler */
+ g_io_add_watch(channel, G_IO_IN, vasum_context_callback, ctx);
+
+ state_hndl = vsm_add_state_changed_callback(ctx, vasum_zone_state_cb, (void *) ctx);
+ if (state_hndl < 0) {
+ D("Failed to register state changed cb\n");
+ return -1;
+ }
+
+ event_hndl = vsm_add_event_callback(ctx, vasum_event_cb, (void *) ctx);
+ if (event_hndl < 0) {
+ D("Failed to register event cb\n");
+ return -1;
+ }
+
+ g_main_loop_run(mainloop);
+
+ ret = vsm_del_state_changed_callback(ctx, state_hndl);
+ if (ret != VSM_ERROR_NONE) {
+ D("Failed to deregister state changed callback\n");
+ }
+
+ ret = vsm_del_event_callback(ctx, event_hndl);
+ if (ret != VSM_ERROR_NONE) {
+ D("Failed to deregister event callback\n");
+ }
+
+ /* Cleanup context in vsm_context */
+ vsm_cleanup_context(ctx);
+
+ return 0;
+}
+
+static void create_zone_check_thread() {
+ sdb_thread_t t;
+ if (sdb_thread_create(&t, zone_check_thread, NULL)) {
+ D("cannot create_zone_check_thread.\n");
+ return;
+ }
+ D("created zone_check_thread\n");
+}
+
+/* default plugin proc */
+static int get_plugin_capability(const char* in_buf, sdbd_plugin_param out) {
+ int ret = SDBD_PLUGIN_RET_NOT_SUPPORT;
+
+ if (in_buf == NULL) {
+ D("Invalid argument\n");
+ return SDBD_PLUGIN_RET_FAIL;
+ }
+
+ if (SDBD_CMP_CAP(in_buf, SECURE)) {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+ } else if (SDBD_CMP_CAP(in_buf, INTER_SHELL)) {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+ } else if (SDBD_CMP_CAP(in_buf, FILESYNC)) {
+ // - push : SDBD_CAP_RET_PUSH
+ // - pull : SDBD_CAP_RET_PULL
+ // - both : SDBD_CAP_RET_PUSHPULL
+ // - disabled : SDBD_CAP_RET_DISABLED
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_PUSHPULL);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+ } else if (SDBD_CMP_CAP(in_buf, USBPROTO)) {
+ if (is_emulator()) {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+ } else {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+ }
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+ } else if (SDBD_CMP_CAP(in_buf, SOCKPROTO)) {
+ if (is_emulator()) {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+ } else {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+ }
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+ } else if (SDBD_CMP_CAP(in_buf, ROOTONOFF)) {
+ if (access("/bin/su", F_OK) == 0) {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_ENABLED);
+ } else {
+ snprintf(out.data, out.len, "%s", SDBD_CAP_RET_DISABLED);
+ }
+ } else if (SDBD_CMP_CAP(in_buf, PLUGIN_VER)) {
+ snprintf(out.data, out.len, "%s", UNKNOWN);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+ } else if (SDBD_CMP_CAP(in_buf, PRODUCT_VER)) {
+ snprintf(out.data, out.len, "%s", UNKNOWN);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+ }
+
+ return ret;
+}
+
+static int verify_shell_cmd(const char* in_buf, sdbd_plugin_param out) {
+ int ret = SDBD_PLUGIN_RET_FAIL;
+
+ if (in_buf == NULL) {
+ D("Invalid argument\n");
+ return SDBD_PLUGIN_RET_FAIL;
+ }
+
+ D("shell command : %s\n", in_buf);
+
+ snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+
+ return ret;
+}
+
+static int convert_shell_cmd(const char* in_buf, sdbd_plugin_param out) {
+ int ret = SDBD_PLUGIN_RET_FAIL;
+
+ if (in_buf == NULL) {
+ D("Invalid argument\n");
+ return SDBD_PLUGIN_RET_FAIL;
+ }
+
+ snprintf(out.data, out.len, "%s", in_buf);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+
+ return ret;
+}
+
+static int verify_peer_ip(const char* in_buf, sdbd_plugin_param out) {
+ int ret = SDBD_PLUGIN_RET_FAIL;
+
+ if (in_buf == NULL) {
+ D("Invalid argument\n");
+ return SDBD_PLUGIN_RET_FAIL;
+ }
+
+ D("peer ip : %s\n", in_buf);
+
+ snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+
+ return ret;
+}
+
+static int verify_sdbd_launch(const char* in_buf, sdbd_plugin_param out) {
+ snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+ return SDBD_PLUGIN_RET_SUCCESS;
+}
+
+static int verify_root_cmd(const char* in_buf, sdbd_plugin_param out) {
+ int ret = SDBD_PLUGIN_RET_FAIL;
+
+ if (in_buf == NULL) {
+ D("Invalid argument\n");
+ return SDBD_PLUGIN_RET_FAIL;
+ }
- // initialize usb mode
- usb_mode = 0;
+ D("shell command : %s\n", in_buf);
- if (stat(ONDEMAND_ROOT_PATH, &st) == -1) {
+ if (verify_root_commands(in_buf)) {
+ snprintf(out.data, out.len, "%s", SDBD_RET_VALID);
+ } else {
+ snprintf(out.data, out.len, "%s", SDBD_RET_INVALID);
+ }
+ ret = SDBD_PLUGIN_RET_SUCCESS;
+
+ return ret;
+}
+
+int default_cmd_proc(const char* cmd,
+ const char* in_buf, sdbd_plugin_param out) {
+ int ret = SDBD_PLUGIN_RET_NOT_SUPPORT;
+
+ /* Check the arguments */
+ if (cmd == NULL || out.data == NULL) {
+ D("Invalid argument\n");
+ return SDBD_PLUGIN_RET_FAIL;
+ }
+
+ D("handle the command : %s\n", cmd);
+
+ /* Handle the request from sdbd */
+ if (SDBD_CMP_CMD(cmd, PLUGIN_CAP)) {
+ ret = get_plugin_capability(in_buf, out);
+ } else if (SDBD_CMP_CMD(cmd, VERIFY_SHELLCMD)) {
+ ret = verify_shell_cmd(in_buf, out);
+ } else if (SDBD_CMP_CMD(cmd, CONV_SHELLCMD)) {
+ ret = convert_shell_cmd(in_buf, out);
+ } else if (SDBD_CMP_CMD(cmd, VERIFY_PEERIP)) {
+ ret = verify_peer_ip(in_buf, out);
+ } else if (SDBD_CMP_CMD(cmd, VERIFY_LAUNCH)) {
+ ret = verify_sdbd_launch(in_buf, out);
+ } else if (SDBD_CMP_CMD(cmd, VERIFY_ROOTCMD)) {
+ ret = verify_root_cmd(in_buf, out);
+ } else {
+ D("Not supported command : %s\n", cmd);
+ ret = SDBD_PLUGIN_RET_NOT_SUPPORT;
+ }
+
+ return ret;
+}
+
+int request_plugin_cmd(const char* cmd, const char* in_buf,
+ char *out_buf, unsigned int out_len)
+{
+ int ret = SDBD_PLUGIN_RET_FAIL;
+ sdbd_plugin_param out;
+
+ if (out_len > SDBD_PLUGIN_OUTBUF_MAX) {
+ D("invalid parameter : %s\n", cmd);
+ return 0;
+ }
+
+ out.data = out_buf;
+ out.len = out_len;
+
+ ret = sdbd_plugin_cmd_proc(cmd, in_buf, out);
+ if (ret == SDBD_PLUGIN_RET_FAIL) {
+ D("failed to request : %s\n", cmd);
+ return 0;
+ }
+ if (ret == SDBD_PLUGIN_RET_NOT_SUPPORT) {
+ // retry in default handler
+ ret = default_cmd_proc(cmd, in_buf, out);
+ if (ret == SDBD_PLUGIN_RET_FAIL) {
+ D("failed to request : %s\n", cmd);
+ return 0;
+ }
+ }
+
+ // add null character.
+ out_buf[out_len-1] = '\0';
+ D("return value: %s\n", out_buf);
+
+ return 1;
+}
+
+static void load_sdbd_plugin() {
+ sdbd_plugin_cmd_proc = NULL;
+
+ g_sdbd_plugin_handle = dlopen(SDBD_PLUGIN_PATH, RTLD_NOW);
+ if (!g_sdbd_plugin_handle) {
+ D("failed to dlopen(%s). error: %s\n", SDBD_PLUGIN_PATH, dlerror());
+ sdbd_plugin_cmd_proc = default_cmd_proc;
return;
}
- if (st.st_uid != SID_DEVELOPER || st.st_gid != SID_DEVELOPER) {
- char *arg_list[] = {"/bin/chown", ONDEMAND_ROOT_PATH, "-R", NULL};
- spawn("/bin/chown", arg_list);
+ sdbd_plugin_cmd_proc = dlsym(g_sdbd_plugin_handle, SDBD_PLUGIN_INTF);
+ if (!sdbd_plugin_cmd_proc) {
+ D("failed to get the sdbd plugin interface. error: %s\n", dlerror());
+ dlclose(g_sdbd_plugin_handle);
+ g_sdbd_plugin_handle = NULL;
+ sdbd_plugin_cmd_proc = default_cmd_proc;
+ return;
}
+ D("using sdbd plugin interface.(%s)\n", SDBD_PLUGIN_PATH);
+}
+
+static void init_sdk_requirements() {
+ struct stat st;
+
execute_required_process();
register_pwlock_cb();
+
+ if (is_emulator()) {
+ register_bootdone_cb();
+ }
+}
+
+int request_plugin_verification(const char* cmd, const char* in_buf) {
+ char out_buf[32] = {0,};
+
+ if(!request_plugin_cmd(cmd, in_buf, out_buf, sizeof(out_buf))) {
+ D("failed to request plugin command. : %s\n", SDBD_CMD_VERIFY_LAUNCH);
+ return 0;
+ }
+
+ if (strlen(out_buf) == 7 && !strncmp(out_buf, SDBD_RET_INVALID, 7)) {
+ D("[%s] is NOT verified.\n", cmd);
+ return 0;
+ }
+
+ D("[%s] is verified.\n", cmd);
+ return 1;
+}
+
+static char* get_cpu_architecture()
+{
+ int ret = 0;
+ bool b_value = false;
+
+ ret = system_info_get_platform_bool(
+ "http://tizen.org/feature/platform.core.cpu.arch.armv6", &b_value);
+ if (ret == SYSTEM_INFO_ERROR_NONE && b_value) {
+ return CPUARCH_ARMV6;
+ }
+
+ ret = system_info_get_platform_bool(
+ "http://tizen.org/feature/platform.core.cpu.arch.armv7", &b_value);
+ if (ret == SYSTEM_INFO_ERROR_NONE && b_value) {
+ return CPUARCH_ARMV7;
+ }
+
+ ret = system_info_get_platform_bool(
+ "http://tizen.org/feature/platform.core.cpu.arch.x86", &b_value);
+ if (ret == SYSTEM_INFO_ERROR_NONE && b_value) {
+ return CPUARCH_X86;
+ }
+
+ D("fail to get the CPU architecture of model:%d\n", errno);
+ return UNKNOWN;
+}
+
+static void init_capabilities(void) {
+ int ret = -1;
+ char *value = NULL;
+
+ memset(&g_capabilities, 0, sizeof(g_capabilities));
+
+ // CPU Architecture of model
+ snprintf(g_capabilities.cpu_arch, sizeof(g_capabilities.cpu_arch),
+ "%s", get_cpu_architecture());
+
+
+ // Secure protocol support
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SECURE,
+ g_capabilities.secure_protocol,
+ sizeof(g_capabilities.secure_protocol))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SECURE);
+ snprintf(g_capabilities.secure_protocol, sizeof(g_capabilities.secure_protocol),
+ "%s", DISABLED);
+ }
+
+
+ // Interactive shell support
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_INTER_SHELL,
+ g_capabilities.intershell_support,
+ sizeof(g_capabilities.intershell_support))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_INTER_SHELL);
+ snprintf(g_capabilities.intershell_support, sizeof(g_capabilities.intershell_support),
+ "%s", DISABLED);
+ }
+
+
+ // File push/pull support
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_FILESYNC,
+ g_capabilities.filesync_support,
+ sizeof(g_capabilities.filesync_support))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_FILESYNC);
+ snprintf(g_capabilities.filesync_support, sizeof(g_capabilities.filesync_support),
+ "%s", DISABLED);
+ }
+
+
+ // USB protocol support
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_USBPROTO,
+ g_capabilities.usbproto_support,
+ sizeof(g_capabilities.usbproto_support))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_USBPROTO);
+ snprintf(g_capabilities.usbproto_support, sizeof(g_capabilities.usbproto_support),
+ "%s", DISABLED);
+ }
+
+
+ // Socket protocol support
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SOCKPROTO,
+ g_capabilities.sockproto_support,
+ sizeof(g_capabilities.sockproto_support))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_SOCKPROTO);
+ snprintf(g_capabilities.sockproto_support, sizeof(g_capabilities.sockproto_support),
+ "%s", DISABLED);
+ }
+
+
+ // Root command support
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_ROOTONOFF,
+ g_capabilities.rootonoff_support,
+ sizeof(g_capabilities.rootonoff_support))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_ROOTONOFF);
+ snprintf(g_capabilities.rootonoff_support, sizeof(g_capabilities.rootonoff_support),
+ "%s", DISABLED);
+ }
+
+
+ // Zone support
+ ret = is_container_enabled();
+ snprintf(g_capabilities.zone_support, sizeof(g_capabilities.zone_support),
+ "%s", ret == 1 ? ENABLED : DISABLED);
+
+
+ // Multi-User support
+ // TODO: get this information from platform.
+ snprintf(g_capabilities.multiuser_support, sizeof(g_capabilities.multiuser_support),
+ "%s", DISABLED);
+
+
+ // Window size synchronization support
+ snprintf(g_capabilities.syncwinsz_support, sizeof(g_capabilities.syncwinsz_support),
+ "%s", ENABLED);
+
+
+ // Profile name
+ ret = system_info_get_platform_string("http://tizen.org/feature/profile", &value);
+ if (ret != SYSTEM_INFO_ERROR_NONE) {
+ snprintf(g_capabilities.profile_name, sizeof(g_capabilities.profile_name),
+ "%s", UNKNOWN);
+ D("fail to get profile name:%d\n", errno);
+ } else {
+ snprintf(g_capabilities.profile_name, sizeof(g_capabilities.profile_name),
+ "%s", value);
+ if (value != NULL) {
+ free(value);
+ }
+ }
+
+
+ // Vendor name
+ ret = system_info_get_platform_string("http://tizen.org/system/manufacturer", &value);
+ if (ret != SYSTEM_INFO_ERROR_NONE) {
+ snprintf(g_capabilities.vendor_name, sizeof(g_capabilities.vendor_name),
+ "%s", UNKNOWN);
+ D("fail to get the Vendor name:%d\n", errno);
+ } else {
+ snprintf(g_capabilities.vendor_name, sizeof(g_capabilities.vendor_name),
+ "%s", value);
+ if (value != NULL) {
+ free(value);
+ }
+ }
+
+
+ // Platform version
+ ret = system_info_get_platform_string("http://tizen.org/feature/platform.version", &value);
+ if (ret != SYSTEM_INFO_ERROR_NONE) {
+ snprintf(g_capabilities.platform_version, sizeof(g_capabilities.platform_version),
+ "%s", UNKNOWN);
+ D("fail to get platform version:%d\n", errno);
+ } else {
+ snprintf(g_capabilities.platform_version, sizeof(g_capabilities.platform_version),
+ "%s", value);
+ if (value != NULL) {
+ free(value);
+ }
+ }
+
+
+ // Product version
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PRODUCT_VER,
+ g_capabilities.product_version,
+ sizeof(g_capabilities.product_version))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PRODUCT_VER);
+ snprintf(g_capabilities.product_version, sizeof(g_capabilities.product_version),
+ "%s", UNKNOWN);
+ }
+
+
+ // Sdbd version
+ snprintf(g_capabilities.sdbd_version, sizeof(g_capabilities.sdbd_version),
+ "%d.%d.%d", SDB_VERSION_MAJOR, SDB_VERSION_MINOR, SDB_VERSION_PATCH);
+
+
+ // Sdbd plugin version
+ if(!request_plugin_cmd(SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PLUGIN_VER,
+ g_capabilities.sdbd_plugin_version,
+ sizeof(g_capabilities.sdbd_plugin_version))) {
+ D("failed to request. (%s:%s) \n", SDBD_CMD_PLUGIN_CAP, SDBD_CAP_TYPE_PLUGIN_VER);
+ snprintf(g_capabilities.sdbd_plugin_version, sizeof(g_capabilities.sdbd_plugin_version),
+ "%s", UNKNOWN);
+ }
}
#endif /* !SDB_HOST */
+static int is_support_usbproto()
+{
+ return (!strncmp(g_capabilities.usbproto_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
+static int is_support_sockproto()
+{
+ return (!strncmp(g_capabilities.sockproto_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
int sdb_main(int is_daemon, int server_port)
{
#if !SDB_HOST
+ load_sdbd_plugin();
+ init_capabilities();
+
init_drop_privileges();
init_sdk_requirements();
+ if (!request_plugin_verification(SDBD_CMD_VERIFY_LAUNCH, NULL)) {
+ D("sdbd should be launched in develop mode.\n");
+ return -1;
+ }
+
umask(000);
#endif
char local_name[30];
build_local_name(local_name, sizeof(local_name), server_port);
if(install_listener(local_name, "*smartsocket*", NULL)) {
- D("Cannot install listener (smartsocket)\n");
- return 1;
- //exit(1);
+ exit(1);
}
}
- if (!is_emulator()) {
+ hostshell_mode = 1;
+
+ /* Not support zone feature yet */
+ /*
+ if (is_container_enabled()) {
+ D("container feature permitted\n");
+
+ // register call-back to check state of zone
+ create_zone_check_thread();
+
+ // check if zone is started before sdbd, in the case sdbd does not get notified.
+ char** zone_list;
+ zone_list = get_zone_list();
+ if (zone_list != NULL) {
+ D("set zone mode on\n");
+ sdb_mutex_lock(&zone_check_lock);
+ if(!initial_zone_mode_check) {
+ initial_zone_mode_check = 1;
+ hostshell_mode = 0;
+ // execute processes needed by each zone
+ if (zone_list) {
+ int i;
+ for (i = 0; *(zone_list + i); i++) {
+ D("Name of zone which executes required processes (in sdb_main) : %s \n", *(zone_list + i));
+ // if zone name has prefix as '/', remove it
+ if (!strncmp(*(zone_list + i), "\/", 1)) {
+ execute_required_process_in_each_zone(
+ (*(zone_list + i) + 1));
+ } else {
+ execute_required_process_in_each_zone(*(zone_list + i));
+ }
+ free(*(zone_list + i));
+ }
+ free(zone_list);
+ }
+ }
+ sdb_mutex_unlock(&zone_check_lock);
+ } else {
+ D("not found any zone yet, denied mode on\n");
+ sdb_sleep_ms(500);
+ }
+ } else {
+ D("container feature not permitted, set host mode on\n");
+ initial_zone_mode_check = 1;
+ hostshell_mode = 1;
+ }
+*/
+ if (is_support_usbproto()) {
// listen on USB
usb_init();
// listen on tcp
//local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
- } else {
+ }
+ if (is_support_sockproto()){
// listen on default port
local_init(DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
}
dest->ptr = src->ptr;
dest->len = src->len;
- memcpy(&(dest->msg), &(src->msg), sizeof(amessage));
- // TODO: should verify what if data length is over MAX_PAYLOAD
int data_length = src->msg.data_length;
if(data_length > MAX_PAYLOAD) {
data_length = MAX_PAYLOAD;
- dest->msg.data_length = data_length;
- D("copy packet error: %d > MAX_PAYLOAD\n", src->msg.data_length);
}
+ memcpy(&(dest->msg), &(src->msg), sizeof(amessage) + data_length);
- memcpy(&(dest->data), &(src->data), data_length);
return 0;
}
#endif
#if !SDB_HOST
if (daemonize() < 0)
- fatal("daemonize() failed: (errno:%d)", errno);
+ fatal("daemonize() failed: errno:%d", errno);
#endif
start_device_log();
#define __SDB_H
#include <limits.h>
+#include <stddef.h>
#include "transport.h" /* readx(), writex() */
+#include "fdevent.h"
+#include "sdbd_plugin.h"
#define MAX_PAYLOAD 4096
#define A_VERSION 0x02000000 // SDB protocol version
#define SDB_VERSION_MAJOR 2 // Used for help/version information
-#define SDB_VERSION_MINOR 1 // Used for help/version information
+#define SDB_VERSION_MINOR 2 // Used for help/version information
+#define SDB_VERSION_PATCH 31 // Used for help/version information
#define SDB_SERVER_VERSION 0 // Increment this when we want to force users to start a new sdb server
*/
int closing;
- /* flag: quit adbd when both ends close the
- ** local service socket
- */
- int exit_on_close;
-
/* the asocket we are connected to
*/
adisconnect disconnect;
};
+#define UNKNOWN "unknown"
+#define INFOBUF_MAXLEN 64
+#define INFO_VERSION "2.2.0"
+typedef struct platform_info {
+ char platform_info_version[INFOBUF_MAXLEN];
+ char model_name[INFOBUF_MAXLEN]; // Emulator
+ char platform_name[INFOBUF_MAXLEN]; // Tizen
+ char platform_version[INFOBUF_MAXLEN]; // 2.2.1
+ char profile_name[INFOBUF_MAXLEN]; // 2.2.1
+} pinfo;
+
+#define ENABLED "enabled"
+#define DISABLED "disabled"
+#define CPUARCH_ARMV6 "armv6"
+#define CPUARCH_ARMV7 "armv7"
+#define CPUARCH_X86 "x86"
+#define CAPBUF_SIZE 4096
+#define CAPBUF_ITEMSIZE 32
+typedef struct platform_capabilities
+{
+ char secure_protocol[CAPBUF_ITEMSIZE]; // enabled or disabled
+ char intershell_support[CAPBUF_ITEMSIZE]; // enabled or disabled
+ char filesync_support[CAPBUF_ITEMSIZE]; // push or pull or pushpull or disabled
+ char rootonoff_support[CAPBUF_ITEMSIZE]; // enabled or disabled
+ char zone_support[CAPBUF_ITEMSIZE]; // enabled or disabled
+ char multiuser_support[CAPBUF_ITEMSIZE]; // enabled or disabled
+ char syncwinsz_support[CAPBUF_ITEMSIZE]; // enabled or disabled
+ char usbproto_support[CAPBUF_ITEMSIZE]; // enabled or disabled
+ char sockproto_support[CAPBUF_ITEMSIZE]; // enabled or disabled
+
+ char cpu_arch[CAPBUF_ITEMSIZE]; // cpu architecture (ex. x86)
+ char profile_name[CAPBUF_ITEMSIZE]; // profile name (ex. mobile)
+ char vendor_name[CAPBUF_ITEMSIZE]; // vendor name (ex. Tizen)
+
+ char platform_version[CAPBUF_ITEMSIZE]; // platform version (ex. 2.3.0)
+ char product_version[CAPBUF_ITEMSIZE]; // product version (ex. 1.0)
+ char sdbd_version[CAPBUF_ITEMSIZE]; // sdbd version
+ char sdbd_plugin_version[CAPBUF_ITEMSIZE]; // sdbd plugin version
+} pcap;
+pcap g_capabilities;
+
+#define SDBD_PLUGIN_PATH "/usr/lib/libsdbd_plugin.so"
+#define SDBD_PLUGIN_INTF "sdbd_plugin_cmd_proc"
+typedef int (*SDBD_PLUGIN_CMD_PROC_PTR)(const char*, const char*, sdbd_plugin_param);
+extern SDBD_PLUGIN_CMD_PROC_PTR sdbd_plugin_cmd_proc;
+int request_plugin_cmd(const char* cmd, const char* in_buf, char *out_buf, unsigned int out_len);
+int request_plugin_verification(const char* cmd, const char* in_buf);
void print_packet(const char *label, apacket *p);
void remount_service(int fd, void *cookie);
char * get_log_file_path(const char * log_name);
-int rootshell_mode;// 0: developer, 1: root
-int usb_mode; // 2:mtp 6:rndis
+int rootshell_mode; // 0: developer, 1: root
+int hostshell_mode; // 0: foreground zone, 1: host 2: denied
+int booting_done; // 0: platform booting is in progess 1: platform booting is done
// This is the users and groups config for the platform
#define SID_ROOT 0 /* traditional unix root user */
#define SID_TTY 5 /* group for /dev/ptmx */
-#define SID_APP 5000 /* application */
#define SID_DEVELOPER 5100 /* developer with SDK */
#define SID_APP_LOGGING 6509
#define SID_SYS_LOGGING 6527
int get_emulator_forward_port(void);
int get_emulator_name(char str[], int str_size);
int get_device_name(char str[], int str_size);
+int get_emulator_hostip(char str[], int str_size);
+int get_emulator_guestip(char str[], int str_size);
+
/* packet allocator */
apacket *get_apacket(void);
void put_apacket(apacket *p);
void usb_init();
void usb_cleanup();
int usb_write(usb_handle *h, const void *data, int len);
-int usb_read(usb_handle *h, void *data, int len);
+int usb_read(usb_handle *h, void *data, unsigned len);
int usb_close(usb_handle *h);
void usb_kick(usb_handle *h);
int copy_packet(apacket* dest, apacket* src);
int is_emulator(void);
+int is_container_enabled(void);
+int has_container(void);
#define DEFAULT_DEVICENAME "unknown"
#if SDB_HOST /* tizen-specific */
#endif
#define USB_NODE_FILE "/dev/samsung_sdb"
-#define DEBUG_MODE_KEY "db/usb/sel_mode"
+#define CMD_ATTACH "/usr/bin/vsm-attach"
+#define CMD_FOREGROUND "/usr/bin/vsm-foreground"
+#define CMD_LIST "/usr/bin/vsm-list"
--- /dev/null
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SDBD_PLUGIN_H
+#define __SDBD_PLUGIN_H
+
+#include <string.h>
+
+/* plugin commands */
+#define SDBD_CMD_PLUGIN_CAP "plugin_capability"
+#define SDBD_CMD_VERIFY_SHELLCMD "verify_shell_cmd"
+#define SDBD_CMD_CONV_SHELLCMD "convert_shell_cmd"
+#define SDBD_CMD_VERIFY_PEERIP "verify_peer_ip"
+#define SDBD_CMD_VERIFY_LAUNCH "verify_sdbd_launch"
+#define SDBD_CMD_VERIFY_ROOTCMD "verify_root_cmd"
+
+/* plugin capabilities */
+#define SDBD_CAP_TYPE_SECURE "secure_protocol_support"
+#define SDBD_CAP_TYPE_INTER_SHELL "interactive_shell_support"
+#define SDBD_CAP_TYPE_FILESYNC "file_sync_support"
+#define SDBD_CAP_TYPE_USBPROTO "usb_protocol_support"
+#define SDBD_CAP_TYPE_SOCKPROTO "socket_protocol_support"
+#define SDBD_CAP_TYPE_ROOTONOFF "root_onoff_support"
+#define SDBD_CAP_TYPE_PLUGIN_VER "sdbd_plugin_version"
+#define SDBD_CAP_TYPE_PRODUCT_VER "product_version"
+/* capability return string */
+#define SDBD_CAP_RET_ENABLED "enabled"
+#define SDBD_CAP_RET_DISABLED "disabled"
+#define SDBD_CAP_RET_PUSH "push"
+#define SDBD_CAP_RET_PULL "pull"
+#define SDBD_CAP_RET_PUSHPULL "pushpull"
+
+/* verification return string */
+#define SDBD_RET_VALID "valid"
+#define SDBD_RET_INVALID "invalid"
+
+/* proc interface return value */
+#define SDBD_PLUGIN_RET_SUCCESS (0)
+#define SDBD_PLUGIN_RET_FAIL (-1)
+#define SDBD_PLUGIN_RET_NOT_SUPPORT (-2)
+
+/* utility macro */
+#define SDBD_CMP_CMD(cmd, type) \
+ ((strlen(cmd) == strlen(SDBD_CMD_##type) \
+ && !strncmp(cmd, SDBD_CMD_##type, strlen(cmd)))?1:0)
+
+#define SDBD_CMP_CAP(cap, type) \
+ ((strlen(cap) == (strlen(SDBD_CAP_TYPE_##type)) \
+ && !strncmp(cap, SDBD_CAP_TYPE_##type, strlen(cap)))?1:0)
+
+/* out parameter structure */
+#define SDBD_SHELL_CMD_MAX 4096
+#define SDBD_PLUGIN_OUTBUF_MAX 4096
+typedef struct sdbd_plugin_param {
+ unsigned int len;
+ char *data;
+} sdbd_plugin_param;
+
+/* log system */
+// 1. set the environment value. : SDB_TRACE=all
+// 2. restart the sdbd deamon.
+// 3. log is output to the /tmp/sdbd-[date].txt
+#define SDBD_PLUGIN_LOG(...) \
+ fprintf(stderr, "%s::%s():", \
+ __FILE__, __FUNCTION__); \
+ fprintf(stderr, __VA_ARGS__);
+
+#endif
#include "utils.h"
struct sudo_command root_commands[] = {
- /* 0 */ {"da_command", "/usr/bin/da_command"},
- /* 1 */ {"profile", "/usr/bin/profile_command"},
- /* 2 */ {"rm1", "rm"},
- /* 3 */ {"rm2", "/bin/rm"},
- /* end */ {NULL, NULL}
+ /* 0 */
+ { "profile", "/usr/bin/profile_command",
+ { "killmanager",
+ "runmanager",
+ "findunittest",
+ "process",
+ "getversion",
+ "killvalgrind",
+ "getprobemap",
+ NULL
+ }
+ },
+ /* end */
+ { NULL, NULL, NULL }
};
static struct command_suffix
/* 1 */ {"redirect", ">"},
/* 2 */ {"semicolon", ";"}, // separated list is executed
/* 3 */ {"and", "&"},
+ /* 4 */ {"command_substitution1", "$"},
+ /* 5 */ {"command_substitution2", "`"},
/* end */ {NULL, NULL}
};
-struct arg_permit_rule sdk_arg_permit_rule[] = {
- /* 0 */ {"gcove_env1", "^GCOV_PREFIX=((/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data$", 1},
- /* 1 */ {"gcove_env2", "GCOV_PREFIX_STRIP=0", 0},
- /* 2 */ {"gcove_env3", "LD_LIBRARY_PATH=/home/developer/sdk_tools/gtest/usr/lib:$LD_LIBRARY_PATH", 0},
- /* 3 */ {"gcove_env4", "TIZEN_LAUNCH_MODE=debug", 0},
- /* 4 */ {"da_env1", "LD_PRELOAD=/usr/lib/da_probe_osp.so", 0},
- /* 5 */ {"gcove_arg1", "^\\-\\-gtest_output=xml:((/opt/apps)|(/opt/usr/apps))/[a-zA-Z0-9]{10}/data/[a-zA-Z0-9_\\-]{1,30}\\.xml$", 1},
- /* end */ {NULL, NULL, 0}
-};
-
/**
* return 1 if the arg is arrowed, otherwise 0 is denied
*/
}
index = is_root_commands(tokens[0]);
if (index == -1) {
- if (exec_app_standalone(arg1)) {
- ret = 1;
- } else {
- return 0; // just keep going to execute normal commands
- }
+ return 0; // just keep going to execute normal commands
}
switch (index) {
- case 0: { // in case of da_command
+ // in case of profile_command
+ case 0: {
ret = 0;
- if (!is_cmd_suffix_denied(arg1)) {
- ret = 1;
- }
- // this is exception to allow suffix
- if (cnt == 5 && !strcmp(tokens[1], "process")
- && !strcmp(tokens[2], "|")
- && !strcmp(tokens[3], "grep")
- && !is_cmd_suffix_denied(tokens[4])) {
- ret = 1;
- }
- break;
- }
- case 1: { // in case of oprofile_command
- ret = 0;
- if (!is_cmd_suffix_denied(arg1)) {
- ret = 1;
- }
- if (!strcmp(tokens[1], "valgrind") && cnt >= 3) {
- char *appid = NULL;
- // the tokens[2] should be apppath
- int rc = smack_lgetlabel(tokens[2], &appid, SMACK_LABEL_ACCESS);
- if (rc == 0 && appid != NULL) {
- if (apply_sdb_rules(SDBD_LABEL_NAME, appid, "rwax") < 0) {
- D("unable to set %s %s rules\n", SDBD_LABEL_NAME, appid);
- } else {
- D("apply rule to '%s %s rwax' rules\n", SDBD_LABEL_NAME, appid);
+ if (!is_cmd_suffix_denied(arg1) && (cnt == 2)) {
+ // check if command is used with permitted arguments
+ for (i = 0; root_commands[0].arguments[i] != NULL; i++) {
+ if (!strncmp(tokens[1], root_commands[0].arguments[i], strlen(tokens[1]))){
+ D("found permitted arguments :%s\n", tokens[1]);
+ ret = 1;
+ break;
}
- if (apply_sdb_rules(appid, SDBD_LABEL_NAME, "rwax") < 0) {
- D("unable to set %s %s rules\n", appid, SDBD_LABEL_NAME);
- } else {
- D("apply rule to '%s %s rwax' rules\n", appid, SDBD_LABEL_NAME);
- }
- //apply_app_process();
- free(appid);
}
- D("standalone launch for valgrind\n");
- }
-
- break;
- }
- case 2:
- case 3:
- { // in case of rm to remove the temporary package file
- if (is_cmd_suffix_denied(arg1)) {
- ret = 0;
- break;
- }
- if (is_pkg_file_path(tokens[1])) {
- ret = 1;
+ if (ret == 0) {
+ D("not found permitted arguments :%s\n", tokens[1]);
+ }
}
break;
}
return ret;
}
-int verify_app_path(const char* path) {
- char buf[PATH_MAX];
-
- snprintf(buf, sizeof buf, "^((%s)|(%s))/[a-zA-Z0-9]{%d}/bin/[a-zA-Z0-9_\\-]{1,}(\\.exe)?$", APP_INSTALL_PATH_PREFIX1, APP_INSTALL_PATH_PREFIX2, 10);
- int reg_cmp = regcmp(buf, path);
-
- return reg_cmp;
-}
-
int regcmp(const char* pattern, const char* str) {
regex_t regex;
int ret;
return 0;
}
-int env_verify(const char* arg) {
- int i;
- for (i=0; sdk_arg_permit_rule[i].name != NULL; i++) {
- if (sdk_arg_permit_rule[i].expression == 0) {
- if (!strcmp(sdk_arg_permit_rule[i].pattern, arg)) {
- D("success to set %s\n", arg);
- return 1;
- }
- } else if (sdk_arg_permit_rule[i].expression == 1) {
- if (regcmp(sdk_arg_permit_rule[i].pattern, arg)) {
- D("success to set %s\n", arg);
- return 1;
- }
- }
- }
- D("failed to set %s\n", arg);
- return 0;
-}
-
-int exec_app_standalone(const char* path) {
- char *tokens[MAX_TOKENS];
- int ret = 0;
- int cnt = 0;
- int flag = 1;
- int i=0;
-
- cnt = tokenize(path, " ", tokens, MAX_TOKENS);
- for (i=0; i<cnt; i++) {
- D("tokenize: %dth: %s\n", i, tokens[i]);
-
- if (!strcmp("export", tokens[i])) {
- flag = 0;
- i++;
- if (i>=cnt) break;
- if (env_verify(tokens[i])) {
- flag = 1;
- }
- i++;
- if (i>=cnt) break;
- if (!strcmp("&&", tokens[i])) {
- continue;
- }
- }
- if (flag == 0) {
- // TODO: check evn setting
- }
-
- if(!strcmp(tokens[i], SDK_LAUNCH_PATH)) {
- int pid = 0;
- char* pkg_id = NULL;
- char* executable = NULL;
- ++i;
- while( i < cnt ) {
- if(!strcmp(tokens[i], "-attach")) {
- if(++i < cnt) {
- char* pid_pattern = "[1-9][0-9]{2,5}";
- if (regcmp(pid_pattern, tokens[i])) {
- pid = atoi(tokens[i]);
- }
- }
- }
- else if(!strcmp(tokens[i], "-p")) {
- if(++i < cnt) {
- pkg_id = tokens[i];
- }
- }
- else if(!strcmp(tokens[i], "-e")) {
- if(++i < cnt) {
- executable = tokens[i];
- }
- }
- i++;
- }
- if(pid > 0) {
- char cmdline[128];
- if (pid) {
- snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
- int fd = unix_open(cmdline, O_RDONLY);
- if (fd >= 0) {
- if(read_line(fd, cmdline, sizeof(cmdline))) {
- if (set_smack_rules_for_gdbserver(cmdline, 1)) {
- ret = 1;
- }
- }
- sdb_close(fd);
- }
- }
- }
- break;
- }
- // TODO: i length check
- else if (!strcmp(tokens[i], GDBSERVER_PATH) || !strcmp(tokens[i], GDBSERVER_PLATFORM_PATH)) { //gdbserver :11 --attach 2332 (cnt=4,)
- char *gdb_attach_arg_pattern = "^:[1-9][0-9]{2,5} \\-\\-attach [1-9][0-9]{2,5}$";
- int argcnt = cnt-i-1;
- if (argcnt == 3 && !strcmp("--attach", tokens[i+2])) {
- char cmdline[128];
- int pid = 0;
- D("parsing.... debug attach mode\n");
- snprintf(cmdline, sizeof(cmdline), "%s %s %s",tokens[i+1], tokens[i+2], tokens[i+3]);
- if (regcmp(gdb_attach_arg_pattern, cmdline)) {
- char cmdline[128];
- pid = atoi(tokens[i+3]);
- if (pid) {
- snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
- int fd = unix_open(cmdline, O_RDONLY);
- if (fd >= 0) {
- if(read_line(fd, cmdline, sizeof(cmdline))) {
- if (set_smack_rules_for_gdbserver(cmdline, 1)) {
- ret = 1;
- }
- }
- sdb_close(fd);
- }
- }
- }
- }
- else if (argcnt >= 2) {
- if(should_drop_privileges() == 0 || verify_app_path(tokens[i+2])) {
- D("parsing.... debug run as mode\n");
- if (set_smack_rules_for_gdbserver(tokens[i+2], 0)) {
- ret = 1;
- }
- }
- }
- D("finished debug launch mode\n");
- } else {
- if (verify_app_path(tokens[i])) {
- char *path = tokens[i];
- char *appid = NULL;
- int rc = smack_lgetlabel(path, &appid, SMACK_LABEL_ACCESS);
- if (rc == 0 && appid != NULL) {
- if (apply_sdb_rules(SDBD_LABEL_NAME, appid, "rwax") < 0) {
- D("unable to set sdbd rules to %s %s rwax\n", SDBD_LABEL_NAME, appid);
- } else {
- D("set sdbd rules to %s %s rwax\n", SDBD_LABEL_NAME, appid);
- }
- if (apply_sdb_rules(appid, SDBD_LABEL_NAME, "rwax") < 0) {
- D("unable to set sdbd rules to %s %s rwax\n", appid, SDBD_LABEL_NAME);
- } else {
- D("set sdbd rules to %s %s rwax\n", appid, SDBD_LABEL_NAME);
- }
- if (smack_set_label_for_self(appid) != -1) {
- D("set smack lebel [%s] appid to %s\n", appid, SMACK_LEBEL_SUBJECT_PATH);
- apply_app_process();
- ret = 1;
- } else {
- D("unable to open %s due to (errno:%d)\n", SMACK_LEBEL_SUBJECT_PATH, errno);
- }
- free(appid);
- }
- D("standalone launch\n");
- }
- }
- // TODO: verify arguments
- break;
- }
-
- if (cnt) {
- free_strings(tokens, cnt);
- }
- return ret;
-}
-
-/**
- * free after use it
- */
-char* clone_gdbserver_label_from_app(const char* app_path) {
- char *new_appid = NULL;
- char appid[APPID_MAX_LENGTH+1];
- char *buffer = NULL;
-
-#if 0
- if (!verify_app_path(app_path)) {
- D("not be able to access %s\n", app_path);
- return NULL;
- }
-#endif
-
- int rc = smack_lgetlabel(app_path, &buffer, SMACK_LABEL_ACCESS);
-
- if (rc == 0 && buffer != NULL) {
- s_strncpy(appid, buffer, sizeof appid);
- free(buffer);
- } else {
- appid[0] = '_';
- appid[1] = '\0';
- }
- new_appid = (char *)malloc(sizeof(appid)+1);
- if (new_appid == NULL) {
- D("could not allocate buffer for new appid'\n");
- return NULL;
- }
- strncpy(new_appid, appid, APPID_MAX_LENGTH);
- // Do not label to gdbserver executable
-/*
- if (new_appid != NULL) {
- rc = smack_lsetlabel(GDBSERVER_PATH, new_appid, SMACK_LABEL_ACCESS);
- if (rc < 0) {
- D("unable to set access smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
- }
- D("set access smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
-
- rc = smack_lsetlabel(GDBSERVER_PATH, new_appid, SMACK_LABEL_EXEC);
- if (rc < 0) {
- D("unable to set execute smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
- }
- D("set execute smack label: %s to %s\n", GDBSERVER_PATH, new_appid);
- }
-*/
- return new_appid;
-}
-
-int set_smack_rules_for_gdbserver(const char* apppath, int mode) {
- // FIXME: set gdbfolder to 755 also
- if(sdb_chmod(GDBSERVER_PATH, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, 1) < 0)
- {
- D("unable to set 755 to %s", GDBSERVER_PATH);
- }
-
- // in case of debug as mode
- char *new_appid = clone_gdbserver_label_from_app(apppath);
- if (new_appid != NULL) {
- if (apply_sdb_rules(SDBD_LABEL_NAME, new_appid, "w") < 0) {
- D("unable to set sdbd rules\n");
- }
- if (apply_sdb_rules(new_appid, SDK_HOME_LABEL_NAME, "rx") < 0) {
- D("unable to set sdbd home rules\n");
- }
- if (smack_set_label_for_self(new_appid) != -1) {
- D("set smack lebel [%s] appid to %s\n", new_appid, SMACK_LEBEL_SUBJECT_PATH);
- // apply app precess only if not attach mode
- if (mode == 0) {
- apply_app_process();
- }
- } else {
- D("unable to open %s due to (errno:%d)\n", SMACK_LEBEL_SUBJECT_PATH, errno);
- }
- free(new_appid);
- return 1;
- }
- // TODO: in case of attach mode
- return 0;
-}
-
-int apply_sdb_rules(const char* subject, const char* object, const char* access_type) {
- struct smack_accesses *rules = NULL;
- int ret = 0;
-
- if (smack_accesses_new(&rules))
- return -1;
-
- if (smack_accesses_add(rules, subject, object, access_type)) {
- smack_accesses_free(rules);
- return -1;
- }
-
- ret = smack_accesses_apply(rules);
- smack_accesses_free(rules);
-
- return ret;
-}
-
-void apply_app_process() {
- set_appuser_groups();
-
- if (setgid(SID_APP) != 0) {
- //fprintf(stderr, "set group id failed errno: %d\n", errno);
- exit(1);
- }
-
- if (setuid(SID_APP) != 0) {
- //fprintf(stderr, "set user id failed errno: %d\n", errno);
- exit(1);
- }
-}
-
-void set_appuser_groups(void) {
-
- int fd = 0;
- char buffer[5];
- gid_t t_gid = -1;
- gid_t groups[APP_GROUPS_MAX]={0,};
- int cnt = 0;
-
- //groups[cnt++] = SID_DEVELOPER;
- fd = sdb_open(APP_GROUP_LIST, O_RDONLY);
- if (fd < 0) {
- D("cannot get app's group lists from %s", APP_GROUP_LIST);
- return;
- }
- for (;;) {
- if (read_line(fd, buffer, sizeof buffer) < 0) {
- break;
- }
- t_gid = strtoul(buffer, 0, 10);
- errno = 0;
- if(errno != 0)
- {
- D("cannot change string to integer: [%s]\n", buffer);
- continue;
- }
- if (t_gid) {
- if (cnt < APP_GROUPS_MAX) {
- groups[cnt++] = t_gid;
- } else {
- D("cannot add groups more than %d", APP_GROUPS_MAX);
- break;
- }
- }
- }
- if (cnt > 0) {
- if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) != 0) {
- sdb_close(fd);
- fprintf(stderr, "set groups failed errno: %d\n", errno);
- exit(1);
- }
- }
- sdb_close(fd);
-}
-
int is_root_commands(const char *command) {
int i = -1;
for(i = 0; root_commands[i].path != NULL; i++) {
extern "C" {
#endif
+#define PERMITTED_ARGUMENT_SIZE 20
struct sudo_command
{
const char *command;
const char *path;
- //const char *arguments;
+ const char *arguments[PERMITTED_ARGUMENT_SIZE];
//const char *regx;
//int permission; /* 0: root, 1: developer, 2: app*/
};
int verify_root_commands(const char *arg1);
int verify_app_path(const char* path);
int regcmp(const char* pattern, const char* str);
-int exec_app_standalone(const char* path);
-char* clone_gdbserver_label_from_app(const char* app_path);
-int set_smack_rules_for_gdbserver(const char* apppath, int mode);
-void apply_app_process();
-void set_appuser_groups(void);
int is_root_commands(const char *command);
-int apply_sdb_rules(const char* subject, const char* object, const char* access_type);
int is_pkg_file_path(const char* path);
#ifdef __cplusplus
#endif
#include "strutils.h"
-#include <system_info_internal.h>
+#include <system_info.h>
#include <vconf.h>
#include <limits.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
typedef struct stinfo stinfo;
struct stinfo {
}
#else
+static int is_support_interactive_shell()
+{
+ return (!strncmp(g_capabilities.intershell_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
#if 0
extern int recovery_mode;
}
#endif
+static int is_support_rootonoff()
+{
+ return (!strncmp(g_capabilities.rootonoff_support, SDBD_CAP_RET_ENABLED, strlen(SDBD_CAP_RET_ENABLED)));
+}
+
void rootshell_service(int fd, void *cookie)
{
char buf[100];
char *mode = (char*) cookie;
if (!strcmp(mode, "on")) {
- if (rootshell_mode == 1) {
- //snprintf(buf, sizeof(buf), "Already changed to developer mode\n");
- // do not show message
- } else {
- if (access("/bin/su", F_OK) == 0) {
- rootshell_mode = 1;
- //allows a permitted user to execute a command as the superuser
- snprintf(buf, sizeof(buf), "Switched to 'root' account mode\n");
+ if (getuid() == 0) {
+ if (rootshell_mode == 1) {
+ //snprintf(buf, sizeof(buf), "Already changed to developer mode\n");
+ // do not show message
} else {
- snprintf(buf, sizeof(buf), "Permission denied\n");
+ if (is_support_rootonoff()) {
+ rootshell_mode = 1;
+ //allows a permitted user to execute a command as the superuser
+ snprintf(buf, sizeof(buf), "Switched to 'root' account mode\n");
+ } else {
+ snprintf(buf, sizeof(buf), "Permission denied\n");
+ }
+ writex(fd, buf, strlen(buf));
}
+ } else {
+ D("need root permission for root shell: %d\n", getuid());
+ rootshell_mode = 0;
+ snprintf(buf, sizeof(buf), "Permission denied\n");
writex(fd, buf, strlen(buf));
}
} else if (!strcmp(mode, "off")) {
snprintf(buf, sizeof(buf), "Switched to 'developer' account mode\n");
writex(fd, buf, strlen(buf));
}
+ } else if ((!strcmp(mode, "hoston")) && (is_container_enabled())) {
+ if (hostshell_mode == 1) {
+ //snprintf(buf, sizeof(buf), "Already changed to hostshell mode\n");
+ // do not show message
+ } else {
+ if (is_support_rootonoff()) {
+ hostshell_mode = 1;
+ snprintf(buf, sizeof(buf), "Switched to host shell mode\n");
+ } else {
+ snprintf(buf, sizeof(buf), "Permission denied\n");
+ }
+ writex(fd, buf, strlen(buf));
+ }
+ } else if ((!strcmp(mode, "hostoff")) && (is_container_enabled())) {
+ if (hostshell_mode == 1) {
+ if(has_container()) {
+ hostshell_mode = 0;
+ snprintf(buf, sizeof(buf), "Switched to foreground zone shell mode\n");
+ writex(fd, buf, strlen(buf));
+ } else {
+ snprintf(buf, sizeof(buf), "No foreground zone exists\n");
+ writex(fd, buf, strlen(buf));
+ }
+ }
} else {
- snprintf(buf, sizeof(buf), "Unknown command option\n");
+ snprintf(buf, sizeof(buf), "Unknown command option : %s\n", mode);
writex(fd, buf, strlen(buf));
}
D("set rootshell to %s\n", rootshell_mode == 1 ? "root" : "developer");
ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg);
if (ret < 0) {
- snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno));
+ snprintf(buf, sizeof(buf), "reboot failed: %s errno:%d\n", errno);
writex(fd, buf, strlen(buf));
}
free(arg);
#endif
#endif
-void rndis_config_service(int fd, void *cookie)
-{
- char buf[100];
- int val = 0;
- char* mode = (char*) cookie;
-
- usb_mode = 0;
- if (vconf_get_int(DEBUG_MODE_KEY, &val)) {
- D("Failed to get debug mode\n");
- sdb_close(fd);
- free(mode);
- return;
- }
- if (!strcmp(mode, "on")) {
- if (val != 6) {
- usb_mode = 6;
- sdb_sleep_ms(500);
- if (vconf_set_int(DEBUG_MODE_KEY, 6)) {
- D("Failed to set rndis %s\n", mode);
- snprintf(buf, sizeof(buf), "Failed to set rndis %s\n", mode);
- writex(fd, buf, strlen(buf));
- }
- }
- } else if (!strcmp(mode, "off")) {
- if (val != 2) {
- usb_mode = 2;
- sdb_sleep_ms(500);
- if (vconf_set_int(DEBUG_MODE_KEY, 2)) {
- D("Failed to set rndis %s\n", mode);
- snprintf(buf, sizeof(buf), "Failed to set rndis %s\n", mode);
- writex(fd, buf, strlen(buf));
- }
- }
- } else {
- D("Unknown command option:(rndis %s)\n", mode);
- snprintf(buf, sizeof(buf), "Unknown command option:(rndis %s)\n", mode);
- writex(fd, buf, strlen(buf));
- }
- free(mode);
- sdb_close(fd);
-}
-
#if 0
static void echo_service(int fd, void *cookie)
{
static int create_subprocess(const char *cmd, pid_t *pid, const char *argv[], const char *envp[])
{
- char *devname;
+ char devname[64];
int ptm;
ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
if(ptm < 0){
- D("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
+ D("[ cannot open /dev/ptmx - errno:%d ]\n",errno);
return -1;
}
if (fcntl(ptm, F_SETFD, FD_CLOEXEC) < 0) {
- D("[ cannot set cloexec to /dev/ptmx - %s ]\n",strerror(errno));
+ D("[ cannot set cloexec to /dev/ptmx - errno:%d ]\n",errno);
}
if(grantpt(ptm) || unlockpt(ptm) ||
- ((devname = (char*) ptsname(ptm)) == 0)){
- D("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
+ ptsname_r(ptm, devname, sizeof(devname)) != 0 ){
+ D("[ trouble with /dev/ptmx - errno:%d ]\n", errno);
sdb_close(ptm);
return -1;
}
*pid = fork();
if(*pid < 0) {
- D("- fork failed: %s -\n", strerror(errno));
+ D("- fork failed: errno:%d -\n", errno);
sdb_close(ptm);
return -1;
}
sdb_close(fd);
} else {
// FIXME: not supposed to be here
- D("sdb: unable to open %s due to %s\n", text, strerror(errno));
+ D("sdb: unable to open %s due to errno:%d\n", text, errno);
}
}
- if (should_drop_privileges()) {
- if (argv[2] != NULL && verify_root_commands(argv[2])) {
- // do nothing
- D("sdb: executes root commands!!:%s\n", argv[2]);
- } else {
- set_developer_privileges();
+ if (hostshell_mode == 1) {
+ if (should_drop_privileges()) {
+ if (argv[2] != NULL && getuid() == 0 && request_plugin_verification(SDBD_CMD_VERIFY_ROOTCMD, argv[2])) {
+ // do nothing
+ D("sdb: executes root commands!!:%s\n", argv[2]);
+ } else {
+ set_developer_privileges();
+ }
}
- }
-
- redirect_and_exec(pts, cmd, argv, envp);
- fprintf(stderr, "- exec '%s' failed: (errno:%d) -\n",
- cmd, errno);
- exit(-1);
+ redirect_and_exec(pts, cmd, argv, envp);
+ } else {
+ char **pargv, **pargv_attach, sid[16];
+ char *argv_attach[16] = {
+ CMD_ATTACH,
+ "-f",
+ NULL,
+ };
+ pargv_attach = argv_attach + 2;
+
+ if (should_drop_privileges()) {
+ if (argv[2] != NULL && request_plugin_verification(SDBD_CMD_VERIFY_ROOTCMD, argv[2])) {
+ // do nothing
+ D("sdb: executes root commands!!:%s\n", argv[2]);
+ } else {
+ snprintf(sid, 16, "%d", SID_DEVELOPER);
+ *(pargv_attach++) = "--uid";
+ *(pargv_attach++) = sid;
+ *(pargv_attach++) = "--gid";
+ *(pargv_attach++) = sid;
+
+ if (chdir("/home/developer") < 0) {
+ D("sdbd: unable to change working directory to /home/developer\n");
+ } else {
+ if (chdir("/") < 0) {
+ D("sdbd: unable to change working directory to /\n");
+ }
+ }
+ // TODO: use pam later
+ //putenv("HOME=/home/developer");
+ setenv("HOME", "/home/developer", 1);
+ }
+ }
+ *(pargv_attach++) = "--";
+ pargv = argv;
+ while(*pargv) {
+ *(pargv_attach++) = *(pargv++);
+ }
+ redirect_and_exec(pts, CMD_ATTACH, argv_attach, envp);
+ }
+ fprintf(stderr, "- exec '%s' failed: (errno:%d) -\n",
+ cmd, errno);
+ exit(-1);
} else {
// Don't set child's OOM adjustment to zero.
// Let the child do it itself, as sometimes the parent starts
int ret_fd;
pid_t pid;
char *value = NULL;
- char lines_str[20] = {'\0',};
- char columns_str[20] = {'\0',};
+ char *trim_value = NULL;
+ char path[PATH_MAX];
+ memset(path, 0, sizeof(path));
char *envp[] = {
"TERM=linux", /* without this, some programs based on screen can't work, e.g. top */
NULL,
NULL
};
+
if (should_drop_privileges()) {
- envp[2] = "HOME=/home/developer";
- get_env("ENV_PATH", &value);
- } else {
- get_env("ENV_SUPATH", &value);
- envp[2] = "HOME=/root";
- }
+ envp[2] = "HOME=/home/developer";
+ get_env("ENV_PATH", &value);
+ } else {
+ get_env("ENV_SUPATH", &value);
+ if(value == NULL) {
+ get_env("ENV_ROOTPATH", &value);
+ }
+ envp[2] = "HOME=/root";
+ }
if (value != NULL) {
- envp[3] = value;
+ trim_value = str_trim(value);
+ if (trim_value != NULL) {
+ // if string is not including 'PATH=', append it.
+ if (strncmp(trim_value, "PATH", 4)) {
+ snprintf(path, sizeof(path), "PATH=%s", trim_value);
+ } else {
+ snprintf(path, sizeof(path), "%s", trim_value);
+ }
+ envp[3] = path;
+ free(trim_value);
+ } else {
+ envp[3] = value;
+ }
}
D("path env:%s,%s,%s,%s\n", envp[0], envp[1], envp[2], envp[3]);
- if (lines > 0 && columns > 0) {
- snprintf(lines_str, sizeof(lines_str), "LINES=%d", lines);
- snprintf(columns_str, sizeof(columns_str), "COLUMNS=%d", columns);
- envp[4] = lines_str;
- envp[5] = columns_str;
- D("shell size env:%s,%s\n", envp[4], envp[5]);
- }
-
if(name) { // in case of shell execution directly
+ // Check the shell command validation.
+ if (!request_plugin_verification(SDBD_CMD_VERIFY_SHELLCMD, name)) {
+ D("This shell command is invalid. (%s)\n", name);
+ return -1;
+ }
+
+ // Convert the shell command.
+ char *new_cmd = NULL;
+ new_cmd = malloc(SDBD_SHELL_CMD_MAX);
+ if(new_cmd == NULL) {
+ D("Cannot allocate the shell commnad buffer.");
+ return -1;
+ }
+
+ memset(new_cmd, 0, SDBD_SHELL_CMD_MAX);
+ if(!request_plugin_cmd(SDBD_CMD_CONV_SHELLCMD, name, new_cmd, SDBD_SHELL_CMD_MAX)) {
+ D("Failed to convert the shell command. (%s)\n", name);
+ free(new_cmd);
+ return -1;
+ }
+
+ D("converted cmd : %s\n", new_cmd);
+
char *args[] = {
SHELL_COMMAND,
"-c",
NULL,
- "-l",
- SUPER_USER,
NULL,
};
- args[2] = name;
+ args[2] = new_cmd;
ret_fd = create_subprocess(SHELL_COMMAND, &pid, args, envp);
+ free(new_cmd);
} else { // in case of shell interactively
+ // Check the capability for interactive shell support.
+ if (!is_support_interactive_shell()) {
+ D("This platform dose NOT support the interactive shell\n");
+ return -1;
+ }
+
char *args[] = {
SHELL_COMMAND,
"-",
D("cannot create service thread\n");
return -1;
}
+
+ if (lines > 0 && columns > 0) {
+ D("shell size lines=%d, columns=%d\n", lines, columns);
+ struct winsize win_sz;
+ win_sz.ws_row = lines;
+ win_sz.ws_col = columns;
+
+ if (ioctl(ret_fd, TIOCSWINSZ, &win_sz) < 0) {
+ D("failed to sync window size.\n");
+ }
+ }
+
sti = malloc(sizeof(stinfo));
if(sti == 0) fatal("cannot allocate stinfo");
sti->func = subproc_waiter_service;
//waitpid(pid, &ret, 0);
}
if (pid < 0) {
- D("- fork failed: (errno:%d) -\n", errno);
+ D("- fork failed: errno:%d -\n", errno);
sdb_close(s[0]);
sdb_close(s[1]);
D("cannot create sync service sub process\n");
#endif
-#define UNKNOWN "unknown"
-#define INFOBUF_MAXLEN 64
-#define INFO_VERSION "2.2.0"
-typedef struct platform_info {
-
- char platform_info_version[INFOBUF_MAXLEN];
- char model_name[INFOBUF_MAXLEN]; // Emulator
- char platform_name[INFOBUF_MAXLEN]; // Tizen
- char platform_version[INFOBUF_MAXLEN]; // 2.2.1
- char profile_name[INFOBUF_MAXLEN]; // 2.2.1
-} pinfo;
-
static void get_platforminfo(int fd, void *cookie) {
pinfo sysinfo;
char *value = NULL;
s_strncpy(sysinfo.platform_info_version, INFO_VERSION, strlen(INFO_VERSION));
- int r = system_info_get_value_string(SYSTEM_INFO_KEY_MODEL, &value);
+ int r = system_info_get_platform_string("http://tizen.org/system/model_name", &value);
if (r != SYSTEM_INFO_ERROR_NONE) {
s_strncpy(sysinfo.model_name, UNKNOWN, strlen(UNKNOWN));
D("fail to get system model:%d\n", errno);
}
}
- r = system_info_get_value_string(SYSTEM_INFO_KEY_PLATFORM_NAME, &value);
+ r = system_info_get_platform_string("http://tizen.org/system/platform.name", &value);
if (r != SYSTEM_INFO_ERROR_NONE) {
s_strncpy(sysinfo.platform_name, UNKNOWN, strlen(UNKNOWN));
D("fail to get platform name:%d\n", errno);
sdb_close(fd);
}
+static int put_key_value_string(char* buf, int offset, int buf_size, char* key, char* value) {
+ int len = 0;
+ if ((len = snprintf(buf+offset, buf_size-offset, "%s:%s\n", key, value)) > 0) {
+ return len;
+ }
+ return 0;
+}
+
+static void get_capability(int fd, void *cookie) {
+ char cap_buffer[CAPBUF_SIZE] = {0,};
+ uint16_t offset = 0;
+
+ // Secure protocol support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "secure_protocol", g_capabilities.secure_protocol);
+
+ // Interactive shell support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "intershell_support", g_capabilities.intershell_support);
+
+ // File push/pull support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "filesync_support", g_capabilities.filesync_support);
+
+ // USB protocol support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "usbproto_support", g_capabilities.usbproto_support);
+
+ // Socket protocol support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "sockproto_support", g_capabilities.sockproto_support);
+
+ // Root command support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "rootonoff_support", g_capabilities.rootonoff_support);
+
+ // Zone support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "zone_support", g_capabilities.zone_support);
+
+ // Multi-User support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "multiuser_support", g_capabilities.multiuser_support);
+
+ // CPU Architecture of model
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "cpu_arch", g_capabilities.cpu_arch);
+
+ // Profile name
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "profile_name", g_capabilities.profile_name);
+
+ // Vendor name
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "vendor_name", g_capabilities.vendor_name);
+
+ // Platform version
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "platform_version", g_capabilities.platform_version);
+
+ // Product version
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "product_version", g_capabilities.product_version);
+
+ // Sdbd version
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "sdbd_version", g_capabilities.sdbd_version);
+
+ // Sdbd plugin version
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "sdbd_plugin_version", g_capabilities.sdbd_plugin_version);
+
+ // Window size synchronization support
+ offset += put_key_value_string(cap_buffer, offset, CAPBUF_SIZE,
+ "syncwinsz_support", g_capabilities.syncwinsz_support);
+
+
+ offset++; // for '\0' character
+
+ writex(fd, &offset, sizeof(uint16_t));
+ writex(fd, cap_buffer, offset);
+
+ sdb_close(fd);
+}
+
+static void sync_windowsize(int fd, void *cookie) {
+ int id, lines, columns;
+ char *size_info = cookie;
+ asocket *s = NULL;
+
+ if (sscanf(size_info, "%d:%d:%d", &id, &lines, &columns) == 3) {
+ D("window size information: id=%d, lines=%d, columns=%d\n", id, lines, columns);
+ }
+ if((s = find_local_socket(id))) {
+ struct winsize win_sz;
+ win_sz.ws_row = lines;
+ win_sz.ws_col = columns;
+
+ if (ioctl(s->fd, TIOCSWINSZ, &win_sz) < 0) {
+ D("failed to sync window size.\n");
+ return;
+ }
+ D("success to sync window size.\n");
+ }
+}
+
+const unsigned COMMAND_TIMEOUT = 10000;
+void get_boot(int fd, void *cookie) {
+ char buf[2] = { 0, };
+ char *mode = (char*) cookie;
+ int time = 0;
+ int interval = 1000;
+ while (time < COMMAND_TIMEOUT) {
+ if (booting_done == 1) {
+ D("get_boot:platform booting is done\n");
+ snprintf(buf, sizeof(buf), "%s", "1");
+ break;
+ }
+ D("get_boot:platform booting is in progress\n");
+ sdb_sleep_ms(interval);
+ time += interval;
+ }
+ writex(fd, buf, strlen(buf));
+ sdb_close(fd);
+}
+
int service_to_fd(const char *name)
{
int ret = -1;
ret = socket_loopback_client(port, SOCK_STREAM);
}
if (ret >= 0) {
- if (disable_tcp_nagle(ret) < 0) {
- D("failed to disable_tcp_nagle\n");
- }
+ disable_tcp_nagle(ret);
}
} else {
#if SDB_HOST
#endif
} else if(!strncmp(name, "sysinfo:", 8)){
ret = create_service_thread(get_platforminfo, 0);
- } else if(!strncmp(name, "rndis:", 6)){
- char *service_name = NULL;
-
- service_name = strdup(name+6);
- ret = create_service_thread(rndis_config_service, (void *)(service_name));
+ } else if(!strncmp(name, "capability:", 11)){
+ ret = create_service_thread(get_capability, 0);
+ } else if(!strncmp(name, "boot:", 5)){
+ if (is_emulator()) {
+ ret = create_service_thread(get_boot, 0);
+ }
+ } else if(!strncmp(name, "shellconf:", 10)){
+ if(!strncmp(name+10, "syncwinsz:", 10)){
+ ret = create_service_thread(sync_windowsize, name+20);
+ }
}
+
if (ret >= 0) {
if (close_on_exec(ret) < 0) {
D("failed to close fd exec\n");
#endif
#include "strutils.h"
+extern int hostshell_mode;
/* Connect to port on the loopback IP interface. type is
* SOCK_STREAM or SOCK_DGRAM.
* return is a file descriptor or -1 on error
*/
int socket_loopback_client(int port, int type)
{
+ char zone_ipaddr[1025] = {0, };
+ char name_vsm[1025] = {0, };
+ int namelen;
struct sockaddr_in addr;
int s;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
- addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ if (hostshell_mode == 0) {
+ FILE *fp;
+ fp = popen("/usr/bin/vsm-foreground", "r");
+ if (fp == NULL) {
+ return 0;
+ }
+ fgets(name_vsm, 1025, fp);
+ pclose(fp);
+
+ snprintf(zone_ipaddr, 1025, "/usr/bin/vsm-info -i -n %s", name_vsm);
+ fp = popen(zone_ipaddr, "r");
+ if (fp == NULL) {
+ return 0;
+ }
+ fgets(zone_ipaddr, 1025, fp);
+ pclose(fp);
+
+ //trim zone ipaddr
+ namelen = strlen(zone_ipaddr);
+ while (zone_ipaddr[--namelen] == '\n')
+ ;
+ zone_ipaddr[namelen + 1] = '\0';
+
+ addr.sin_addr.s_addr = inet_addr(zone_ipaddr);
+ } else {
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ }
s = socket(AF_INET, type, 0);
if(s < 0) return -1;
return -1;
}
- addr.sin_addr.s_addr = inet_addr(inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
+ char buf[1025] = {0, };
+ inet_ntop(AF_INET, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, buf, sizeof(buf));
+ addr.sin_addr.s_addr = inet_addr(buf);
close(s);
ifr.ifr_flags |= ~IFF_UP;
}
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
- fprintf(stderr,"cannot set SIOCGIFFLAGS flags: (errno:%d)\n", errno);
+ fprintf(stderr,"cannot set SIOCGIFFLAGS flags: errno:%d\n", errno);
close(sockfd);
return -1;
}
// libs/cutils/socket_network_client.c
#include "sockets.h"
-#include <stdio.h>
+
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
tmphstbuf = malloc(hstbuflen);
if (tmphstbuf == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(-1);
+ return -1;
}
while ((res = gethostbyname_r(host, &hostbuf, tmphstbuf, hstbuflen, &hp, &herr)) == ERANGE) {
hstbuflen *= 2;
tmphstbuf = realloc(tmphstbuf, hstbuflen);
if (tmphstbuf == NULL) {
- fprintf(stderr, "out of memory\n");
- exit(-1);
+ return -1;
}
}
if (res || hp == NULL) {
return s;
}
+
static void local_socket_destroy(asocket *s)
{
apacket *p, *n;
- int exit_on_close = s->exit_on_close;
D("LS(%d): destroying fde.fd=%d\n", s->id, s->fde.fd);
}
remove_socket(s);
free(s);
-
- if (exit_on_close) {
- D("local_socket_destroy: exiting\n");
- exit(1);
- }
}
s = create_local_socket(fd);
D("LS(%d): bound to '%s' via %d\n", s->id, name, fd);
-#if !SDB_HOST
- if ((!strncmp(name, "root:", 5) && getuid() != 0)
- || !strncmp(name, "usb:", 4)
- || !strncmp(name, "tcpip:", 6)) {
- D("LS(%d): enabling exit_on_close\n", s->id);
- s->exit_on_close = 1;
- }
-#endif
-
return s;
}
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <string.h>
+#include <time.h>
#define OS_PATH_SEPARATOR '/'
#define OS_PATH_SEPARATOR_STR "/"
return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
}
-static __inline__ int disable_tcp_nagle(int fd)
+static __inline__ void disable_tcp_nagle(int fd)
{
- int on = 1;
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*) &on, sizeof(on)) < 0) {
- return -1;
- }
- return 0;
+ int on = 1;
+ setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) );
}
static __inline__ void sdb_sleep_ms( int mseconds )
{
- usleep( mseconds*1000 );
+ struct timespec ts;
+ ts.tv_sec = mseconds / 1000;
+ ts.tv_nsec = (mseconds % 1000) * 1000000;
+ nanosleep(&ts, NULL);
}
static __inline__ int sdb_mkdir(const char* path, int mode)
{
atransport *t = calloc(1, sizeof(atransport));
if (t == NULL) {
- D("could not allocate atransport'\n");
+ D("failed to allocate memory of transport struct\n");
return;
}
char buff[32];
void register_usb_transport(usb_handle *usb, const char *serial, unsigned writeable)
{
+ char device_name[256];
atransport *t = calloc(1, sizeof(atransport));
if (t == NULL) {
- D("cannot allocate atransport");
+ D("failed to allocate memory of transport struct\n");
return;
}
- char device_name[256];
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
serial ? serial : "");
p += r;
} else {
if (r < 0) {
- D("readx: fd=%d (errno:%d)\n", fd, errno);
+ D("readx: fd=%d error %d\n", fd, errno);
if (errno == EINTR)
continue;
} else {
if (close_on_exec(fd) < 0) {
D("failed to close fd exec\n");
}
- if (disable_tcp_nagle(fd) < 0) {
- D("failed to disable_tcp_nagle\n");
- }
+ disable_tcp_nagle(fd);
snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, console_port);
register_socket_transport(fd, buf, sdb_port, 1, device_name);
return 0;
if (shared_memory == (void *)-1)
{
- D("faild to get shdmem key (%d) : %s\n", port, strerror(errno));
+ D("faild to get shdmem key (%d) : errno:%d\n", port, errno);
return -1;
}
static void *server_socket_thread(void * arg)
{
int serverfd, fd;
- struct sockaddr addr;
+ struct sockaddr_in addr;
socklen_t alen;
int port = (int)arg;
pthread_cond_broadcast(¬i_cond);
}
- fd = sdb_socket_accept(serverfd, &addr, &alen);
+ fd = sdb_socket_accept(serverfd, (struct sockaddr *)&addr, &alen);
if(fd >= 0) {
D("server: new connection on fd %d\n", fd);
if (close_on_exec(fd) < 0) {
D("failed to close fd exec\n");
}
- if (disable_tcp_nagle(fd) < 0) {
- D("failed to disable_tcp_nagle\n");
+ disable_tcp_nagle(fd);
+
+ // Check the peer ip validation.
+ if (!is_emulator()
+ && !request_plugin_verification(SDBD_CMD_VERIFY_PEERIP, inet_ntoa(addr.sin_addr))) {
+ sdb_close(fd);
+ } else {
+ register_socket_transport(fd, "host", port, 1, NULL);
}
- register_socket_transport(fd, "host", port, 1, NULL);
}
}
D("transport: server_socket_thread() exiting\n");
flags = fcntl(sockfd, F_GETFL, 0);
if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
- D("failed to set file O_NONBLOCK status flag for socket %d: %s\n",
- sockfd, strerror(errno));
+ D("failed to set file O_NONBLOCK status flag for socket %d: errno:%d\n",
+ sockfd, errno);
}
error = 0;
done:
if(fcntl(sockfd, F_SETFL, flags) == -1) { /* restore file status flags */
- D("failed to restore file status flag for socket %d: (errno:%d)\n",
- sockfd, errno);
+ D("failed to restore file status flag for socket %d\n",
+ sockfd);
}
if (error) {
return (0);
}
-static int send_msg_to_localhost_from_guest(int local_port, char *request, int sock_type) {
+static int send_msg_to_localhost_from_guest(const char *host_ip, int local_port, char *request, int sock_type) {
int ret, s;
struct sockaddr_in server;
int connect_timeout = 1;
memset( &server, 0, sizeof(server) );
server.sin_family = AF_INET;
server.sin_port = htons(local_port);
- server.sin_addr.s_addr = inet_addr(QEMU_FORWARD_IP);
+ server.sin_addr.s_addr = inet_addr(host_ip);
- D("try to send notification to host(%s:%d) using %s:[%s]\n", QEMU_FORWARD_IP, local_port, (sock_type == 0) ? "tcp" : "udp", request);
+ D("try to send notification to host(%s:%d) using %s:[%s]\n", host_ip, local_port, (sock_type == 0) ? "tcp" : "udp", request);
if (sock_type == 0) {
s = socket(AF_INET, SOCK_STREAM, 0);
sdb_close(s);
return -1;
}
- // writex handles EINTR and returns 0 if success
if (writex(s, request, strlen(request)) != 0) {
D("could not send notification request to host\n");
sdb_close(s);
return 0;
}
+/*
static void notify_sdbd_startup() {
char buffer[512];
char request[512];
sleep(1);
}
}
+*/
// send the "emulator" request to sdbserver
static void notify_sdbd_startup_thread() {
char request[512];
char vm_name[256]={0,};
+ char host_ip[256] = {0,};
+ char guest_ip[256] = {0,};
int base_port = get_emulator_forward_port();
int r = get_emulator_name(vm_name, sizeof vm_name);
int time = 0;
- int try_limit_time = -1; // try_limit_time < 0 if unlimited
+ //int try_limit_time = -1; // try_limit_time < 0 if unlimited
if (base_port < 0 || r < 0) {
return;
}
-
+ if (get_emulator_hostip(host_ip, sizeof host_ip) == -1) {
+ D("failed to get emulator host ip\n");
+ return;
+ }
// XXX: Known issue - log collision
while (1) {
- /* XXX: Known issue - timing issue
- A request failure can happen at the starting up of a SDB server
- (with very little probability)
- If a SDB server establish a new connection and send a request
- between D1 and D2, the request will fail.
- Becuase when a SDB server gets a duplicated "emulator:" command,
- it closes the existing transport connection.
- */
-
- // If there is any connected (via TCP/IP) SDB server, sleep 10 secs (D1)
+ // Trial limitation reached. terminate notify thread.
+ /*if (0 <= try_limit_time && try_limit_time <= time) {
+ break;
+ }*/
+ // If there is any connected (via TCP/IP) SDB server, sleep 10 secs
if (get_connected_count(kTransportLocal) > 0) {
if (time >= 0) {
time = 0;
- D("notify_sdbd_startup() success after %d trial(s)", time);
+ D("notify_sdbd_startup() success after %d trial(s)\n", time);
}
sleep(10);
continue;
}
+ if (get_emulator_guestip(guest_ip, sizeof guest_ip) == -1) {
+ D("failed to get emulator guest ip\n");
+ goto sleep_and_continue;
+ }
+
// tell qemu sdbd is just started with udp
- if (send_msg_to_localhost_from_guest(base_port + 3, "2\n", 1) < 0) {
+ if (send_msg_to_localhost_from_guest(host_ip, base_port + 3, "2\n", 1) < 0) {
D("could not send sensord noti request, try again %dth\n", time+1);
goto sleep_and_continue;
}
- // tell sdb server emulator's vms name (D2)
- snprintf(request, sizeof request, "host:emulator:%d:%s",base_port + 1, vm_name);
- snprintf(buffer, sizeof buffer, "%04x%s", strlen(request), request );
+ // tell sdb server emulator's vms name
+ // TODO: should we use host:emulator request? let's talk about this!
- if (get_connected_count(kTransportLocal) > 0) continue; // See comment above
+ if (!strncmp(host_ip, QEMU_FORWARD_IP, sizeof host_ip)) {
+ snprintf(request, sizeof request, "host:emulator:%d:%s",base_port + 1, vm_name);
+ } else {
+ snprintf(request, sizeof request, "host:connect:%s:%d", guest_ip, DEFAULT_SDB_LOCAL_TRANSPORT_PORT);
+ }
+ snprintf(buffer, sizeof buffer, "%04x%s", strlen(request), request );
- if (send_msg_to_localhost_from_guest(DEFAULT_SDB_PORT, buffer, 0) <0) {
+ if (send_msg_to_localhost_from_guest(host_ip, DEFAULT_SDB_PORT, buffer, 0) <0) {
D("could not send sdbd noti request. it might sdb server has not been started yet.\n");
goto sleep_and_continue;
}
-
//LOGI("sdbd noti request sent.\n");
sleep_and_continue:
// thread start
if(sdb_thread_create(&thr, notify_sdbd_startup_thread, NULL)) {
fatal("cannot create notify_sdbd_startup_thread");
- notify_sdbd_startup(); // defensive code
+ //notify_sdbd_startup(); // defensive code
}
sdb_mutex_unlock(®ister_noti_lock);
}
n = usb_bulk_write(h, data, xfer);
if(n != xfer) {
- D("ERROR: n = %d, errno = %d (%s)\n",
- n, errno, strerror(errno));
+ D("ERROR: n = %d, errno = %d\n",
+ n, errno);
return -1;
}
}
continue;
}
- D("ERROR: n = %d, errno = %d (%s)\n",
- n, errno, strerror(errno));
+ D("ERROR: n = %d, errno = %d \n",
+ n, errno);
return -1;
}
return;
fail:
- D("[ usb open %s error=%d, err_str = %s]\n",
- usb->fname, errno, strerror(errno));
+ D("[ usb open %s error=%d]\n",
+ usb->fname, errno);
if(usb->desc >= 0) {
sdb_close(usb->desc);
}
return 0;
}
-int usb_read(usb_handle *h, void *data, int len)
+int usb_read(usb_handle *h, void *data, unsigned len)
{
int n;
h = calloc(1, sizeof(usb_handle));
if (h == NULL) {
- D("cannot allocate usb handle");
+ D("failed to allocate memory of usb_handle\n");
return;
}
+
h->fd = -1;
sdb_cond_init(&h->notify, 0);
sdb_mutex_init(&h->lock, 0);
e--;
ret = strdup(s);
- if (ret == NULL) {
- fprintf(stderr, "failed to strdup");
+ if(ret == NULL) {
return NULL;
}
ret[e - s + 1] = 0;
return pid;
}
+char** str_split(char* a_str, const char a_delim) {
+ char** result = 0;
+ size_t count = 0;
+ char* tmp = a_str;
+ char* last_comma = 0;
+ char delim[2];
+ delim[0] = a_delim;
+ delim[1] = 0;
+ char *ptr;
+
+ /* Count how many elements will be extracted. */
+ while (*tmp) {
+ if (a_delim == *tmp) {
+ count++;
+ last_comma = tmp;
+ }
+ tmp++;
+ }
+
+ /* Add space for trailing token. */
+ count += last_comma < (a_str + strlen(a_str) - 1);
+
+ /* Add space for terminating null string so caller
+ knows where the list of returned strings ends. */
+ count++;
+
+ result = malloc(sizeof(char*) * count);
+
+ if (result) {
+ size_t idx = 0;
+ char* token = strtok_r(a_str, delim, &ptr);
+
+ while (token) {
+ //assert(idx < count);
+ *(result + idx++) = strdup(token);
+ token = strtok_r(0, delim, &ptr);
+ }
+ //assert(idx == count - 1);
+ *(result + idx) = 0;
+ }
+
+ return result;
+}
+
*/
int spawn(char* program, char** arg_list);
+char** str_split(char* a_str, const char a_delim);
+
#endif /* _SDB_UTILS_H */