harden ipc and frontend recovery
This commit is contained in:
102
gtk/main.c
102
gtk/main.c
@@ -12,7 +12,7 @@ struct Im
|
||||
{
|
||||
GtkIMContext parent;
|
||||
int fd;
|
||||
char pre[256];
|
||||
char pre[Ipcfieldmax+1];
|
||||
int prelen;
|
||||
};
|
||||
|
||||
@@ -36,52 +36,61 @@ srvconnect(Im *im)
|
||||
return;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
snprintf(addr.sun_path, sizeof(addr.sun_path), "/tmp/strans.%d", getuid());
|
||||
snprintf(addr.sun_path, sizeof(addr.sun_path), IPCPATH, getuid());
|
||||
if(connect(im->fd, (struct sockaddr*)&addr, sizeof(addr)) < 0){
|
||||
close(im->fd);
|
||||
im->fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
srvclose(Im *im)
|
||||
{
|
||||
int was;
|
||||
|
||||
if(im->fd >= 0)
|
||||
close(im->fd);
|
||||
im->fd = -1;
|
||||
was = im->prelen;
|
||||
im->pre[0] = '\0';
|
||||
im->prelen = 0;
|
||||
if(was > 0){
|
||||
g_signal_emit_by_name(im, "preedit-changed");
|
||||
g_signal_emit_by_name(im, "preedit-end");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
readresp(Im *im, char *buf, int bufsz)
|
||||
{
|
||||
unsigned char hdr[2], pl;
|
||||
int n, was;
|
||||
Ipcresp resp;
|
||||
int was;
|
||||
|
||||
if(read(im->fd, hdr, 2) != 2)
|
||||
return -1;
|
||||
n = hdr[1];
|
||||
buf[0] = '\0';
|
||||
if(n > 0 && n < bufsz){
|
||||
if(read(im->fd, buf, n) != n)
|
||||
return -1;
|
||||
buf[n] = '\0';
|
||||
}
|
||||
if(read(im->fd, &pl, 1) != 1)
|
||||
return -1;
|
||||
if(pl >= sizeof(im->pre))
|
||||
return -1;
|
||||
was = im->prelen;
|
||||
if(pl > 0 && read(im->fd, im->pre, pl) != pl)
|
||||
if(ipcreadresp(im->fd, 1, buf, bufsz, im->pre,
|
||||
sizeof(im->pre), &resp) < 0)
|
||||
return -1;
|
||||
im->pre[pl] = '\0';
|
||||
im->prelen = pl;
|
||||
if(was == 0 && pl > 0)
|
||||
im->prelen = resp.npreedit;
|
||||
if(was == 0 && im->prelen > 0)
|
||||
g_signal_emit_by_name(im, "preedit-start");
|
||||
if(was != 0 || pl != 0)
|
||||
if(was != 0 || im->prelen != 0)
|
||||
g_signal_emit_by_name(im, "preedit-changed");
|
||||
if(was > 0 && pl == 0)
|
||||
if(was > 0 && im->prelen == 0)
|
||||
g_signal_emit_by_name(im, "preedit-end");
|
||||
return hdr[0];
|
||||
return resp.eaten;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
kget(uint32_t gdk)
|
||||
{
|
||||
if(gdk >= 0xff00)
|
||||
uint32_t u;
|
||||
|
||||
u = gdk_keyval_to_unicode(gdk);
|
||||
if((gdk & 0xff000000) == 0x01000000 && u != 0)
|
||||
return u;
|
||||
if(gdk >= 0xff00 && gdk <= 0xffff)
|
||||
return Kspec + (gdk - 0xff00);
|
||||
return gdk_keyval_to_unicode(gdk);
|
||||
return u;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
@@ -104,17 +113,17 @@ mget(uint32_t state)
|
||||
static void
|
||||
sendreset(Im *im)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
char resp[64];
|
||||
unsigned char buf[Ipcreqsz];
|
||||
char resp[Ipcfieldmax+1];
|
||||
|
||||
if(im->fd < 0)
|
||||
if(im->fd < 0){
|
||||
srvclose(im);
|
||||
return;
|
||||
buf[0] = 1;
|
||||
buf[1] = 0;
|
||||
buf[2] = Kesc & 0xff;
|
||||
buf[3] = Kesc >> 8;
|
||||
if(send(im->fd, buf, 4, MSG_NOSIGNAL) == 4)
|
||||
readresp(im, resp, sizeof(resp));
|
||||
}
|
||||
ipcpackreq(buf, 1, 0, Kesc);
|
||||
if(ipcsend(im->fd, buf, sizeof buf) < 0 ||
|
||||
readresp(im, resp, sizeof(resp)) < 0)
|
||||
srvclose(im);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -137,8 +146,8 @@ static gboolean
|
||||
kpress(GtkIMContext *ctx, GdkEventKey *ev)
|
||||
{
|
||||
Im *im;
|
||||
unsigned char buf[4];
|
||||
char resp[64];
|
||||
unsigned char buf[Ipcreqsz];
|
||||
char resp[Ipcfieldmax+1];
|
||||
uint32_t key, mod;
|
||||
int r;
|
||||
GtkInputPurpose purpose;
|
||||
@@ -154,21 +163,18 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev)
|
||||
if(purpose == GTK_INPUT_PURPOSE_PASSWORD || purpose == GTK_INPUT_PURPOSE_PIN)
|
||||
return plaincommit(ctx, key, mod);
|
||||
srvconnect(im);
|
||||
if(im->fd < 0)
|
||||
if(im->fd < 0){
|
||||
srvclose(im);
|
||||
return plaincommit(ctx, key, mod);
|
||||
buf[0] = 1;
|
||||
buf[1] = mod;
|
||||
buf[2] = key & 0xff;
|
||||
buf[3] = key >> 8;
|
||||
if(send(im->fd, buf, 4, MSG_NOSIGNAL) != 4){
|
||||
close(im->fd);
|
||||
im->fd = -1;
|
||||
}
|
||||
ipcpackreq(buf, 1, mod, key);
|
||||
if(ipcsend(im->fd, buf, sizeof buf) < 0){
|
||||
srvclose(im);
|
||||
return plaincommit(ctx, key, mod);
|
||||
}
|
||||
r = readresp(im, resp, sizeof(resp));
|
||||
if(r < 0){
|
||||
close(im->fd);
|
||||
im->fd = -1;
|
||||
srvclose(im);
|
||||
return plaincommit(ctx, key, mod);
|
||||
}
|
||||
if(resp[0] != '\0')
|
||||
@@ -228,6 +234,8 @@ static void
|
||||
init(Im *im)
|
||||
{
|
||||
im->fd = -1;
|
||||
im->pre[0] = '\0';
|
||||
im->prelen = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user