summaryrefslogtreecommitdiffstats
path: root/sesman
diff options
context:
space:
mode:
Diffstat (limited to 'sesman')
-rw-r--r--sesman/chansrv/Makefile.am6
-rw-r--r--sesman/chansrv/chansrv_common.c73
-rw-r--r--sesman/chansrv/chansrv_common.h27
-rw-r--r--sesman/chansrv/pulse/module-xrdp-source.c38
-rw-r--r--sesman/chansrv/sound.c153
-rw-r--r--sesman/session.c10
-rw-r--r--sesman/verify_user.c9
-rw-r--r--sesman/verify_user_pam.c28
8 files changed, 272 insertions, 72 deletions
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 81218db1..7a97c136 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -9,7 +9,8 @@ EXTRA_DIST = \
rail.h \
sound.h \
xcommon.h \
- mlog.h
+ mlog.h \
+ chansrv_common.h
EXTRA_DEFINES =
EXTRA_INCLUDES =
@@ -48,7 +49,8 @@ xrdp_chansrv_SOURCES = \
drdynvc.c \
chansrv_fuse.c \
irp.c \
- fifo.c
+ fifo.c \
+ chansrv_common.c
xrdp_chansrv_LDFLAGS = \
$(EXTRA_FLAGS)
diff --git a/sesman/chansrv/chansrv_common.c b/sesman/chansrv/chansrv_common.c
new file mode 100644
index 00000000..fd26da7c
--- /dev/null
+++ b/sesman/chansrv/chansrv_common.c
@@ -0,0 +1,73 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Laxmikant Rashinkar 2009-2014
+ *
+ * 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.
+ */
+
+#include "chansrv_common.h"
+
+/**
+ * Assemble fragmented incoming packets into one stream
+ *
+ * @param src stream that contains partial data
+ * @param dest stream that contains entire data
+ * @param chan_flags fragmentation flags
+ * @param length bytes in this packet
+ * @param total_length total length of assembled packet
+ *
+ * @return 1 when all data has been assembled, 0 otherwise
+ *
+ * NOTE: it is the responsibility of the caller to free dest stream
+ ****************************************************************************/
+int
+read_entire_packet(struct stream *src, struct stream **dest, int chan_flags,
+ int length, int total_length)
+{
+ struct stream *ls;
+
+ if ((chan_flags & 3) == 3)
+ {
+ /* packet not fragmented */
+ xstream_new(ls, total_length);
+ xstream_copyin(ls, src->p, length);
+ ls->p = ls->data;
+ *dest = ls;
+ return 1;
+ }
+
+ /* is this the first fragmented packet? */
+ if (chan_flags & 1)
+ {
+ xstream_new(ls, total_length);
+ *dest = ls;
+ }
+ else
+ {
+ ls = *dest;
+ }
+
+ xstream_copyin(ls, src->p, length);
+
+ /* in last packet, chan_flags & 0x02 will be true */
+ if (chan_flags & 0x02)
+ {
+ /* rewind stream */
+ ls->p = ls->data;
+ return 1;
+ }
+
+ return 0;
+}
+
diff --git a/sesman/chansrv/chansrv_common.h b/sesman/chansrv/chansrv_common.h
new file mode 100644
index 00000000..833e3359
--- /dev/null
+++ b/sesman/chansrv/chansrv_common.h
@@ -0,0 +1,27 @@
+/**
+ * xrdp: A Remote Desktop Protocol server.
+ *
+ * Copyright (C) Laxmikant Rashinkar 2009-2014
+ *
+ * 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 _CHANSRV_COMMON_H
+#define _CHANSRV_COMMON_H
+
+#include "parse.h"
+
+int read_entire_packet(struct stream *src, struct stream **dest, int chan_flags, int length, int total_length);
+
+#endif
+
diff --git a/sesman/chansrv/pulse/module-xrdp-source.c b/sesman/chansrv/pulse/module-xrdp-source.c
index 1c03b069..3d73fd03 100644
--- a/sesman/chansrv/pulse/module-xrdp-source.c
+++ b/sesman/chansrv/pulse/module-xrdp-source.c
@@ -71,7 +71,7 @@ PA_MODULE_USAGE(
#define DEFAULT_SOURCE_NAME "xrdp-source"
#define DEFAULT_LATENCY_TIME 10
-#define MAX_LATENCY_USEC (PA_USEC_PER_SEC * 2)
+#define MAX_LATENCY_USEC 1000
#define CHANSRV_PORT_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d"
struct userdata {
@@ -144,6 +144,32 @@ static void source_update_requested_latency_cb(pa_source *s) {
u->block_usec = pa_source_get_requested_latency_within_thread(s);
}
+static int lsend(int fd, char *data, int bytes) {
+ int sent = 0;
+ int error;
+ while (sent < bytes) {
+ error = send(fd, data + sent, bytes - sent, 0);
+ if (error < 1) {
+ return error;
+ }
+ sent += error;
+ }
+ return sent;
+}
+
+static int lrecv(int fd, char *data, int bytes) {
+ int recved = 0;
+ int error;
+ while (recved < bytes) {
+ error = recv(fd, data + recved, bytes - recved, 0);
+ if (error < 1) {
+ return error;
+ }
+ recved += error;
+ }
+ return recved;
+}
+
static int data_get(struct userdata *u, pa_memchunk *chunk) {
int fd;
@@ -190,7 +216,7 @@ static int data_get(struct userdata *u, pa_memchunk *chunk) {
buf[9] = 0;
buf[10] = 0;
- send(u->fd, buf, 11, 0);
+ lsend(u->fd, buf, 11);
u->want_src_data = 1;
pa_log_debug("###### started recording");
}
@@ -208,10 +234,10 @@ static int data_get(struct userdata *u, pa_memchunk *chunk) {
buf[9] = (unsigned char) chunk->length;
buf[10] = (unsigned char) ((chunk->length >> 8) & 0xff);
- send(u->fd, buf, 11, 0);
+ lsend(u->fd, buf, 11);
/* read length of data available */
- recv(u->fd, ubuf, 2, 0);
+ lrecv(u->fd, (char *) ubuf, 2);
bytes = ((ubuf[1] << 8) & 0xff00) | (ubuf[0] & 0xff);
if (bytes == 0) {
@@ -220,7 +246,7 @@ static int data_get(struct userdata *u, pa_memchunk *chunk) {
}
/* get data */
- bytes = recv(u->fd, data, bytes, 0);
+ bytes = lrecv(u->fd, data, bytes);
pa_memblock_release(chunk->memblock);
@@ -272,7 +298,7 @@ static void thread_func(void *userdata) {
buf[9] = 0;
buf[10] = 0;
- send(u->fd, buf, 11, 0);
+ lsend(u->fd, buf, 11);
u->want_src_data = 0;
pa_log_debug("###### stopped recording");
}
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index f5e17fef..9943a15b 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -43,9 +43,11 @@ static struct trans *g_audio_c_trans_in = 0; /* connection */
static int g_training_sent_time = 0;
static int g_cBlockNo = 0;
static int g_bytes_in_stream = 0;
-static FIFO in_fifo;
+static FIFO g_in_fifo;
+static int g_bytes_in_fifo = 0;
static struct stream *g_stream_inp = NULL;
+static struct stream *g_stream_incoming_packet = NULL;
#define BBUF_SIZE (1024 * 8)
char g_buffer[BBUF_SIZE];
@@ -145,23 +147,18 @@ static int g_client_input_format_index = 0;
static int g_server_input_format_index = 0;
/* microphone related */
-static int APP_CC
-sound_send_server_input_formats(void);
-static int APP_CC
-sound_process_input_format(int aindex, int wFormatTag,
+static int APP_CC sound_send_server_input_formats(void);
+static int APP_CC sound_process_input_format(int aindex, int wFormatTag,
int nChannels, int nSamplesPerSec,
int nAvgBytesPerSec, int nBlockAlign,
int wBitsPerSample, int cbSize, char *data);
-static int APP_CC
-sound_process_input_formats(struct stream *s, int size);
-static int APP_CC
-sound_input_start_recording(void);
-static int APP_CC
-sound_input_stop_recording(void);
-static int APP_CC
-sound_process_input_data(struct stream *s, int bytes);
-static int DEFAULT_CC
-sound_sndsrvr_source_data_in(struct trans *trans);
+static int APP_CC sound_process_input_formats(struct stream *s, int size);
+static int APP_CC sound_input_start_recording(void);
+static int APP_CC sound_input_stop_recording(void);
+static int APP_CC sound_process_input_data(struct stream *s, int bytes);
+static int DEFAULT_CC sound_sndsrvr_source_data_in(struct trans *trans);
+static int APP_CC sound_start_source_listener();
+static int APP_CC sound_start_sink_listener();
/*****************************************************************************/
static int APP_CC
@@ -681,36 +678,21 @@ sound_sndsrvr_source_conn_in(struct trans *trans, struct trans *new_trans)
int APP_CC
sound_init(void)
{
- char port[256];
-
LOG(0, ("sound_init:"));
g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
+ g_stream_incoming_packet = NULL;
/* init sound output */
sound_send_server_output_formats();
-
- g_audio_l_trans_out = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
- g_audio_l_trans_out->is_term = g_is_term;
- g_snprintf(port, 255, CHANSRV_PORT_OUT_STR, g_display_num);
- g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in;
-
- if (trans_listen(g_audio_l_trans_out, port) != 0)
- LOG(0, ("sound_init: trans_listen failed"));
+ sound_start_sink_listener();
/* init sound input */
sound_send_server_input_formats();
-
- g_audio_l_trans_in = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
- g_audio_l_trans_in->is_term = g_is_term;
- g_snprintf(port, 255, CHANSRV_PORT_IN_STR, g_display_num);
- g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in;
-
- if (trans_listen(g_audio_l_trans_in, port) != 0)
- LOG(0, ("sound_init: trans_listen failed"));
+ sound_start_source_listener();
/* save data from sound_server_source */
- fifo_init(&in_fifo, 100);
+ fifo_init(&g_in_fifo, 100);
return 0;
}
@@ -744,7 +726,7 @@ sound_deinit(void)
g_audio_c_trans_in = 0;
}
- fifo_deinit(&in_fifo);
+ fifo_deinit(&g_in_fifo);
return 0;
}
@@ -759,31 +741,39 @@ sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
{
int code;
int size;
+ int ok_to_free = 1;
- in_uint8(s, code);
- in_uint8s(s, 1);
- in_uint16_le(s, size);
+ if (!read_entire_packet(s, &g_stream_incoming_packet, chan_flags,
+ length, total_length))
+ {
+ return 0;
+ }
+
+ in_uint8(g_stream_incoming_packet, code);
+ in_uint8s(g_stream_incoming_packet, 1);
+ in_uint16_le(g_stream_incoming_packet, size);
switch (code)
{
case SNDC_WAVECONFIRM:
- sound_process_wave_confirm(s, size);
+ sound_process_wave_confirm(g_stream_incoming_packet, size);
break;
case SNDC_TRAINING:
- sound_process_training(s, size);
+ sound_process_training(g_stream_incoming_packet, size);
break;
case SNDC_FORMATS:
- sound_process_output_formats(s, size);
+ sound_process_output_formats(g_stream_incoming_packet, size);
break;
case SNDC_REC_NEGOTIATE:
- sound_process_input_formats(s, size);
+ sound_process_input_formats(g_stream_incoming_packet, size);
break;
case SNDC_REC_DATA:
- sound_process_input_data(s, size);
+ sound_process_input_data(g_stream_incoming_packet, size);
+ ok_to_free = 0;
break;
default:
@@ -791,6 +781,12 @@ sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
break;
}
+ if (ok_to_free && g_stream_incoming_packet)
+ {
+ xstream_free(g_stream_incoming_packet);
+ g_stream_incoming_packet = NULL;
+ }
+
return 0;
}
@@ -834,7 +830,6 @@ sound_get_wait_objs(tbus *objs, int *count, int *timeout)
int APP_CC
sound_check_wait_objs(void)
{
-
if (g_audio_l_trans_out != 0)
{
if (trans_check_wait_objs(g_audio_l_trans_out) != 0)
@@ -852,6 +847,7 @@ sound_check_wait_objs(void)
LOG(10, ("sound_check_wait_objs: g_audio_c_trans_out returned non-zero"));
trans_delete(g_audio_c_trans_out);
g_audio_c_trans_out = 0;
+ sound_start_sink_listener();
}
}
@@ -872,6 +868,7 @@ sound_check_wait_objs(void)
LOG(10, ("sound_check_wait_objs: g_audio_c_trans_in returned non-zero"));
trans_delete(g_audio_c_trans_in);
g_audio_c_trans_in = 0;
+ sound_start_source_listener();
}
}
@@ -1045,9 +1042,12 @@ sound_input_start_recording(void)
{
struct stream* s;
+ LOG(10, ("sound_input_start_recording:"));
+
/* if there is any data in FIFO, discard it */
- while ((s = (struct stream *) fifo_remove(&in_fifo)) != NULL)
+ while ((s = (struct stream *) fifo_remove(&g_in_fifo)) != NULL)
xstream_free(s);
+ g_bytes_in_fifo = 0;
xstream_new(s, 1024);
@@ -1079,6 +1079,8 @@ sound_input_stop_recording(void)
{
struct stream* s;
+ LOG(10, ("sound_input_stop_recording:"));
+
xstream_new(s, 1024);
/*
@@ -1102,19 +1104,25 @@ sound_input_stop_recording(void)
* Process data: xrdp <- client
*****************************************************************************/
-static unsigned char data = 0;
-
static int APP_CC
sound_process_input_data(struct stream *s, int bytes)
{
struct stream *ls;
+ LOG(0, ("sound_process_input_data: bytes %d g_bytes_in_fifo %d",
+ bytes, g_bytes_in_fifo));
+
+ /* cap data in fifo */
+ if (g_bytes_in_fifo > 8 * 1024)
+ {
+ return 0;
+ }
xstream_new(ls, bytes);
- memcpy(ls->data, s->p, bytes);
+ g_memcpy(ls->data, s->p, bytes);
ls->p += bytes;
s_mark_end(ls);
-
- fifo_insert(&in_fifo, (void *) ls);
+ fifo_insert(&g_in_fifo, (void *) ls);
+ g_bytes_in_fifo += bytes;
return 0;
}
@@ -1147,6 +1155,7 @@ sound_sndsrvr_source_data_in(struct trans *trans)
ts->p = ts->data + 8;
in_uint8(ts, cmd);
in_uint16_le(ts, bytes_req);
+ LOG(10, ("sound_sndsrvr_source_data_in: bytes_req %d", bytes_req));
xstream_new(s, bytes_req + 2);
@@ -1158,7 +1167,14 @@ sound_sndsrvr_source_data_in(struct trans *trans)
while (bytes_read < bytes_req)
{
if (g_stream_inp == NULL)
- g_stream_inp = (struct stream *) fifo_remove(&in_fifo);
+ {
+ g_stream_inp = (struct stream *) fifo_remove(&g_in_fifo);
+ if (g_stream_inp != NULL)
+ {
+ g_bytes_in_fifo -= g_stream_inp->size;
+ LOG(10, (" g_bytes_in_fifo %d", g_bytes_in_fifo));
+ }
+ }
if (g_stream_inp == NULL)
{
@@ -1212,3 +1228,38 @@ sound_sndsrvr_source_data_in(struct trans *trans)
return 0;
}
+
+/**
+ * Start a listener for microphone redirection connections
+ *****************************************************************************/
+static int APP_CC
+sound_start_source_listener()
+{
+ char port[1024];
+
+ g_audio_l_trans_in = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
+ g_audio_l_trans_in->is_term = g_is_term;
+ g_snprintf(port, 255, CHANSRV_PORT_IN_STR, g_display_num);
+ g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in;
+ if (trans_listen(g_audio_l_trans_in, port) != 0)
+ LOG(0, ("trans_listen failed"));
+ return 0;
+}
+
+/**
+ * Start a listener for speaker redirection connections
+ *****************************************************************************/
+static int APP_CC
+sound_start_sink_listener()
+{
+ char port[1024];
+
+ g_audio_l_trans_out = trans_create(TRANS_MODE_UNIX, 128 * 1024, 8192);
+ g_audio_l_trans_out->is_term = g_is_term;
+ g_snprintf(port, 255, CHANSRV_PORT_OUT_STR, g_display_num);
+ g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in;
+ if (trans_listen(g_audio_l_trans_out, port) != 0)
+ LOG(0, ("trans_listen failed"));
+ return 0;
+}
+
diff --git a/sesman/session.c b/sesman/session.c
index 856c969e..4ea48d35 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -460,6 +460,7 @@ session_start_fork(int width, int height, int bpp, char *username,
char screen[32];
char text[256];
char passwd_file[256];
+ char *pfile;
char **pp1 = (char **)NULL;
struct session_chain *temp = (struct session_chain *)NULL;
struct list *xserver_params = (struct list *)NULL;
@@ -633,10 +634,14 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (xpid == 0) /* child */
{
- env_set_user(username, passwd_file, display,
+ pfile = 0;
+ if (type == SESMAN_SESSION_TYPE_XVNC)
+ {
+ pfile = passwd_file;
+ }
+ env_set_user(username, pfile, display,
g_cfg->session_variables1,
g_cfg->session_variables2);
- env_check_password_file(passwd_file, password);
g_snprintf(text, 255, "%d", g_cfg->sess.max_idle_time);
g_setenv("XRDP_SESMAN_MAX_IDLE_TIME", text, 1);
@@ -676,6 +681,7 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (type == SESMAN_SESSION_TYPE_XVNC)
{
+ env_check_password_file(passwd_file, password);
xserver_params = list_create();
xserver_params->auto_free = 1;
diff --git a/sesman/verify_user.c b/sesman/verify_user.c
index 98d3dd32..49c475c6 100644
--- a/sesman/verify_user.c
+++ b/sesman/verify_user.c
@@ -51,6 +51,7 @@ long DEFAULT_CC
auth_userpass(char *user, char *pass, int *errorcode)
{
const char *encr;
+ const char *epass;
struct passwd *spw;
struct spwd *stp;
@@ -84,8 +85,12 @@ auth_userpass(char *user, char *pass, int *errorcode)
/* old system with only passwd */
encr = spw->pw_passwd;
}
-
- return (strcmp(encr, crypt(pass, encr)) == 0);
+ epass = crypt(pass, encr);
+ if (epass == 0)
+ {
+ return 0;
+ }
+ return (strcmp(encr, epass) == 0);
}
/******************************************************************************/
diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c
index eec12c66..a2b3f93a 100644
--- a/sesman/verify_user_pam.c
+++ b/sesman/verify_user_pam.c
@@ -118,22 +118,31 @@ auth_userpass(char *user, char *pass, int *errorcode)
if (error != PAM_SUCCESS)
{
- if(errorcode!=NULL){
- *errorcode = error ;
- }
+ if (errorcode != NULL)
+ {
+ *errorcode = error;
+ }
g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
}
+ error = pam_set_item(auth_info->ph, PAM_TTY, service_name);
+ if (error != PAM_SUCCESS)
+ {
+ g_printf("pam_set_item failed: %s\r\n",
+ pam_strerror(auth_info->ph, error));
+ }
+
error = pam_authenticate(auth_info->ph, 0);
if (error != PAM_SUCCESS)
{
- if(errorcode!=NULL){
- *errorcode = error ;
- }
+ if (errorcode != NULL)
+ {
+ *errorcode = error;
+ }
g_printf("pam_authenticate failed: %s\r\n",
pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);
@@ -150,9 +159,10 @@ auth_userpass(char *user, char *pass, int *errorcode)
if (error != PAM_SUCCESS)
{
- if(errorcode!=NULL){
- *errorcode = error ;
- }
+ if (errorcode != NULL)
+ {
+ *errorcode = error;
+ }
g_printf("pam_acct_mgmt failed: %s\r\n",
pam_strerror(auth_info->ph, error));
pam_end(auth_info->ph, error);