From 86444c0d7aab461396a95911cfe9f8b9b4680402 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Tue, 1 Jun 2010 19:47:47 +0000 Subject: [PATCH] Finally introducing the encryption plug-in (*not* functional yet) --- Makefile | 1 + src/gsm.c | 35 ++++++++--- src/gsm.h | 9 ++- src/modem.c | 58 +++++++++++++----- src/modem.h | 8 ++- src/phone.c | 45 ++++++++------ src/plugins/Makefile | 17 +++++- src/plugins/project.conf | 10 +++- src/plugins/smscrypt.c | 126 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 261 insertions(+), 48 deletions(-) create mode 100644 src/plugins/smscrypt.c diff --git a/Makefile b/Makefile index 616c2d4..e319d71 100644 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ dist: $(PACKAGE)-$(VERSION)/src/project.conf \ $(PACKAGE)-$(VERSION)/src/plugins/openmoko.c \ $(PACKAGE)-$(VERSION)/src/plugins/profiles.c \ + $(PACKAGE)-$(VERSION)/src/plugins/smscrypt.c \ $(PACKAGE)-$(VERSION)/src/plugins/Makefile \ $(PACKAGE)-$(VERSION)/src/plugins/project.conf \ $(PACKAGE)-$(VERSION)/COPYING \ diff --git a/src/gsm.c b/src/gsm.c index e16c03e..d6fcff1 100644 --- a/src/gsm.c +++ b/src/gsm.c @@ -905,21 +905,38 @@ int gsm_reset(GSM * gsm, unsigned int delay) /* gsm_send_message */ -int gsm_send_message(GSM * gsm, char const * number, char const * text) +static int _send_message_utf8(GSM * gsm, char const * number, char const * text, + size_t length); + +int gsm_send_message(GSM * gsm, char const * number, GSMEncoding encoding, + char const * text, size_t length) +{ + switch(encoding) + { + case GSM_ENCODING_UTF8: + return _send_message_utf8(gsm, number, text, length); + case GSM_ENCODING_RAW_DATA: + return gsm_modem_send_message(gsm->modem, number, + GSM_MODEM_ALPHABET_DATA, text, length); + } + return 1; /* should not be reached */ +} + +static int _send_message_utf8(GSM * gsm, char const * number, char const * text, + size_t length) { int ret; - size_t len; - char * p; + gchar * p; size_t i; - len = strlen(text); - if((p = malloc(len)) == NULL) + if((p = g_convert(text, length, "ISO-8859-1", "UTF-8", NULL, &length, + NULL)) == NULL) return 1; /* XXX report error */ - /* XXX support more alphabets */ - for(i = 0; i < len; i++) + for(i = 0; i < length; i++) p[i] = _gsm_convert_from_iso(text[i]); - ret = gsm_modem_send_message(gsm->modem, number, text, len); - free(p); + ret = gsm_modem_send_message(gsm->modem, number, + GSM_MODEM_ALPHABET_DEFAULT, text, length); + g_free(p); return ret; } diff --git a/src/gsm.h b/src/gsm.h index 0526fa1..7783746 100644 --- a/src/gsm.h +++ b/src/gsm.h @@ -43,6 +43,12 @@ typedef enum _GSMCallType typedef struct _GSMCommand GSMCommand; typedef void (*GSMCommandCallback)(GSM * gsm); +typedef enum _GSMEncoding +{ + GSM_ENCODING_UTF8 = 0, + GSM_ENCODING_RAW_DATA +} GSMEncoding; + typedef enum _GSMEventType { GSM_EVENT_TYPE_ERROR = 0, @@ -382,6 +388,7 @@ int gsm_queue_with_error(GSM * gsm, char const * command, GSMError error); int gsm_reset(GSM * gsm, unsigned int delay); -int gsm_send_message(GSM * gsm, char const * number, char const * text); +int gsm_send_message(GSM * gsm, char const * number, GSMEncoding encoding, + char const * text, size_t length); #endif /* !PHONE_GSM_H */ diff --git a/src/modem.c b/src/modem.c index 1796ee4..b41f791 100644 --- a/src/modem.c +++ b/src/modem.c @@ -443,10 +443,11 @@ int gsm_modem_reset(GSMModem * gsmm) /* gsm_modem_send_message */ static char * _number_to_address(char const * number); +static char * _text_to_data(char const * text, size_t length); static char * _text_to_sept(char const * text, size_t length); int gsm_modem_send_message(GSMModem * gsmm, char const * number, - char const * text, size_t length) + GSMModemAlphabet alphabet, char const * text, size_t length) { int ret = 1; char const cmd1[] = "AT+CMGS="; @@ -456,9 +457,9 @@ int gsm_modem_send_message(GSMModem * gsmm, char const * number, char * buf2; unsigned long len2; char * addr; - char * sept; + char * data = NULL; char const pid[] = "00"; - char const dcs[] = "00"; + char dcs[] = "0X"; char const vp[] = "AA"; GSMCommand * gsmc; @@ -467,29 +468,40 @@ int gsm_modem_send_message(GSMModem * gsmm, char const * number, GSM_MESSAGE_FORMAT_PDU) != 0) return gsm_event(gsmm->gsm, GSM_EVENT_TYPE_ERROR, GSM_ERROR_MESSAGE_SEND_FAILED, NULL); + switch(alphabet) + { + case GSM_MODEM_ALPHABET_DEFAULT: + dcs[1] = '0'; + data = _text_to_sept(text, length); + break; + case GSM_MODEM_ALPHABET_DATA: + dcs[1] = '4'; + data = _text_to_data(text, length); + break; + } addr = _number_to_address(number); - sept = _text_to_sept(text, length); len2 = sizeof(cmd2) + 2 + strlen(addr ? addr : "") + sizeof(pid) - + sizeof(dcs) + 2 + strlen(sept ? sept : "") + 1; + + sizeof(dcs) + sizeof(vp) + 2 + strlen(data ? data : "") + 1; buf2 = malloc(len2); - len1 = sizeof(cmd1) + 2; + len1 = sizeof(cmd1) + 3; buf1 = malloc(len1); - if(addr == NULL || sept == NULL || buf1 == NULL || buf2 == NULL) + if(addr == NULL || data == NULL || buf1 == NULL || buf2 == NULL) { free(addr); - free(sept); + free(data); free(buf1); free(buf2); return gsm_event(gsmm->gsm, GSM_EVENT_TYPE_ERROR, GSM_ERROR_MESSAGE_SEND_FAILED, NULL); } - snprintf(buf2, len2, "%s%02lX%s%s%s%s%02lX%s\x1a", cmd2, - (unsigned long)((number[0] == '+') - ? strlen(number) - 1 : strlen(number)), - addr, pid, dcs, vp, (unsigned long)strlen(text), sept); + fprintf(stderr, "DEBUG: len2=%lu\n", len2); + if(number[0] == '+') + number++; + snprintf(buf2, len2, "%s%02lX%s%s%s%s%02lX%s\x1a", cmd2, strlen(number), + addr, pid, dcs, vp, length, data); snprintf(buf1, len1, "%s%lu", cmd1, (len2 - 1) / 2); free(addr); - free(sept); + free(data); if((gsmc = gsm_command_new(buf1)) != NULL && (ret = gsm_queue_command(gsmm->gsm, gsmc)) == 0) { @@ -544,10 +556,27 @@ static char * _number_to_address(char const * number) return buf; } +static char * _text_to_data(char const * text, size_t length) +{ + char const tab[16] = "0123456789ABCDEF"; + char * buf; + size_t i; + + if((buf = malloc((length * 2) + 1)) == NULL) + return NULL; + for(i = 0; i < length; i++) + { + buf[i * 2] = tab[text[i] & 0x0f]; + buf[(i * 2) + 1] = tab[((text[i] & 0xf0) >> 4) & 0x0f]; + } + buf[i * 2] = '\0'; + return buf; +} + /* this function is heavily inspired from gsmd, (c) 2007 OpenMoko, Inc. */ static char * _text_to_sept(char const * text, size_t length) { - char const tab[] = "0123456789ABCDEF"; + char const tab[16] = "0123456789ABCDEF"; unsigned char const * t = (unsigned char const *)text; char * buf; char * p; @@ -556,7 +585,6 @@ static char * _text_to_sept(char const * text, size_t length) unsigned char ch2; int shift = 0; - length = strlen(text); if((buf = malloc((length * 2) + 1)) == NULL) return NULL; p = buf; diff --git a/src/modem.h b/src/modem.h index c64e395..c3e1ac7 100644 --- a/src/modem.h +++ b/src/modem.h @@ -26,6 +26,12 @@ /* types */ typedef struct _GSMModem GSMModem; +typedef enum _GSMModemAlphabet +{ + GSM_MODEM_ALPHABET_DEFAULT = 0, + GSM_MODEM_ALPHABET_DATA +} GSMModemAlphabet; + typedef enum _GSMModemQuirk { GSM_MODEM_QUIRK_NONE = 0, @@ -74,7 +80,7 @@ int gsm_modem_is_registered(GSMModem * gsmm); int gsm_modem_reset(GSMModem * gsmm); int gsm_modem_send_message(GSMModem * gsmm, char const * number, - char const * text, size_t len); + GSMModemAlphabet alphabet, char const * text, size_t length); int gsm_modem_set_call_presentation(GSMModem * gsmm, gboolean set); int gsm_modem_set_call_waiting_control(GSMModem * gsmm, gboolean unsollicited); diff --git a/src/phone.c b/src/phone.c index 8537d58..0c1f0d5 100644 --- a/src/phone.c +++ b/src/phone.c @@ -683,9 +683,13 @@ void phone_event(Phone * phone, PhoneEvent event, ...) size_t i; PhonePlugin * plugin; va_list ap; - char * buf; + GSMEncoding * encoding; + char ** buf; size_t * len; +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(%u)\n", __func__, event); +#endif for(i = 0; i < phone->plugins_cnt; i++) { plugin = phone->plugins[i].pp; @@ -696,9 +700,11 @@ void phone_event(Phone * phone, PhoneEvent event, ...) case PHONE_EVENT_SMS_RECEIVING: case PHONE_EVENT_SMS_SENDING: va_start(ap, event); - buf = va_arg(ap, char *); + encoding = va_arg(ap, GSMEncoding *); + buf = va_arg(ap, char **); len = va_arg(ap, size_t *); - plugin->event(plugin, event, buf, len); + plugin->event(plugin, event, encoding, buf, + len); va_end(ap); break; /* no arguments */ @@ -1925,8 +1931,8 @@ void phone_write_send(Phone * phone) GtkTextBuffer * tbuf; GtkTextIter start; GtkTextIter end; - size_t len; - gchar * p; + size_t length; + GSMEncoding encoding = GSM_ENCODING_UTF8; phone_show_write(phone, TRUE); number = gtk_entry_get_text(GTK_ENTRY(phone->wr_entry)); @@ -1937,18 +1943,12 @@ void phone_write_send(Phone * phone) FALSE); if(number == NULL || number[0] == '\0' || text == NULL) return; - if((p = g_convert(text, -1, "ISO-8859-1", "UTF-8", NULL, NULL, NULL)) - != NULL) - { - g_free(text); - text = p; - } phone->wr_progress = _phone_create_progress(phone->wr_window, _("Sending message...")); _phone_track(phone, PHONE_TRACK_MESSAGE_SENT, TRUE); - len = strlen(text); - phone_event(phone, PHONE_EVENT_SMS_SENDING, text, &len); - gsm_send_message(phone->gsm, number, text); + length = strlen(text); + phone_event(phone, PHONE_EVENT_SMS_SENDING, &encoding, &text, &length); + gsm_send_message(phone->gsm, number, encoding, text, length); g_free(text); } @@ -2307,6 +2307,8 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) { Phone * phone = data; GSMRegistrationReport report; + GSMEncoding encoding; + char * content; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d)\n", __func__, event->type); @@ -2369,13 +2371,18 @@ static int _phone_gsm_event(GSMEvent * event, gpointer data) event->incoming_message.index); return 0; case GSM_EVENT_TYPE_MESSAGE: - phone_event(phone, PHONE_EVENT_SMS_RECEIVING, - event->message.content, - &event->message.length); + encoding = PHONE_ENCODING_UTF8; /* XXX may not be */ + if((content = malloc(event->message.length)) == NULL) + return 1; /* XXX report error */ + memcpy(content, event->message.content, + event->message.length); + phone_event(phone, PHONE_EVENT_SMS_RECEIVING, &encoding, + &content, &event->message.length); + phone_event(phone, PHONE_EVENT_SMS_RECEIVED); phone_messages_set(phone, event->message.index, event->message.number, - event->message.date, - event->message.content); + event->message.date, content); + free(content); return 0; case GSM_EVENT_TYPE_MESSAGE_LIST: _phone_fetch_messages(phone, event->message_list.start, diff --git a/src/plugins/Makefile b/src/plugins/Makefile index ff2a046..6b8eb6a 100644 --- a/src/plugins/Makefile +++ b/src/plugins/Makefile @@ -1,4 +1,4 @@ -TARGETS = openmoko.so profiles.so +TARGETS = openmoko.so profiles.so smscrypt.so PREFIX = /usr/local DESTDIR = LIBDIR = $(PREFIX)/lib @@ -32,14 +32,24 @@ profiles_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) `pkg-config --libs libpulse` profiles.so: $(profiles_OBJS) $(LD) -o profiles.so $(profiles_OBJS) `pkg-config --libs libpulse` +smscrypt_OBJS = smscrypt.o +smscrypt_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS) +smscrypt_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) + +smscrypt.so: $(smscrypt_OBJS) + $(LD) -o smscrypt.so $(smscrypt_OBJS) + openmoko.o: openmoko.c ../../include/Phone.h $(CC) $(openmoko_CFLAGS) -c openmoko.c profiles.o: profiles.c ../../include/Phone.h $(CC) $(profiles_CFLAGS) -c profiles.c +smscrypt.o: smscrypt.c ../../include/Phone.h + $(CC) $(smscrypt_CFLAGS) -c smscrypt.c + clean: - $(RM) $(openmoko_OBJS) $(profiles_OBJS) + $(RM) $(openmoko_OBJS) $(profiles_OBJS) $(smscrypt_OBJS) distclean: clean $(RM) $(TARGETS) @@ -49,9 +59,12 @@ install: all $(INSTALL) -m 0644 openmoko.so $(DESTDIR)$(LIBDIR)/Phone/plugins/openmoko.so $(MKDIR) $(DESTDIR)$(LIBDIR)/Phone/plugins $(INSTALL) -m 0644 profiles.so $(DESTDIR)$(LIBDIR)/Phone/plugins/profiles.so + $(MKDIR) $(DESTDIR)$(LIBDIR)/Phone/plugins + $(INSTALL) -m 0644 smscrypt.so $(DESTDIR)$(LIBDIR)/Phone/plugins/smscrypt.so uninstall: $(RM) $(DESTDIR)$(LIBDIR)/Phone/plugins/openmoko.so $(RM) $(DESTDIR)$(LIBDIR)/Phone/plugins/profiles.so + $(RM) $(DESTDIR)$(LIBDIR)/Phone/plugins/smscrypt.so .PHONY: all clean distclean install uninstall diff --git a/src/plugins/project.conf b/src/plugins/project.conf index 4e045f8..7163306 100644 --- a/src/plugins/project.conf +++ b/src/plugins/project.conf @@ -1,4 +1,4 @@ -targets=openmoko,profiles +targets=openmoko,profiles,smscrypt cppflags_force=-I ../../include cppflags=-I $(PREFIX)/include cflags_force=-W @@ -13,6 +13,14 @@ install=$(LIBDIR)/Phone/plugins [openmoko.c] depends=../../include/Phone.h +[smscrypt] +type=plugin +sources=smscrypt.c +install=$(LIBDIR)/Phone/plugins + +[smscrypt.c] +depends=../../include/Phone.h + [profiles] type=plugin sources=profiles.c diff --git a/src/plugins/smscrypt.c b/src/plugins/smscrypt.c new file mode 100644 index 0000000..9828d0d --- /dev/null +++ b/src/plugins/smscrypt.c @@ -0,0 +1,126 @@ +/* $Id$ */ +/* Copyright (c) 2010 Pierre Pronchery */ +/* This file is part of DeforaOS Desktop Phone */ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + + + +#include +#include +#include "Phone.h" + + +/* SMSCrypt */ +/* private */ +static int _smscrypt_init(PhonePlugin * plugin); +static int _smscrypt_event(PhonePlugin * plugin, PhoneEvent event, ...); +static void _smscrypt_settings(PhonePlugin * plugin); + + +/* public */ +/* variables */ +PhonePlugin plugin = +{ + NULL, + "SMS encryption", + NULL, + _smscrypt_init, + NULL, + _smscrypt_event, + _smscrypt_settings, + NULL +}; + + +/* private */ +/* functions */ +/* smscrypt_init */ +static int _smscrypt_init(PhonePlugin * plugin) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s() secret=\"%s\"\n", __func__, + plugin->helper->config_get(plugin->helper->phone, + "smscrypt", "secret")); +#endif + return 0; +} + + +/* smscrypt_event */ +static void _smscrypt_event_sms_received(PhoneEncoding * encoding, char ** buf, + size_t * len); +static void _smscrypt_event_sms_sending(PhoneEncoding * encoding, char ** buf, + size_t * len); + +static int _smscrypt_event(PhonePlugin * plugin, PhoneEvent event, ...) +{ + va_list ap; + PhoneEncoding * encoding; + char ** buf; + size_t * len; + + va_start(ap, event); + switch(event) + { + /* our deal */ + case PHONE_EVENT_SMS_RECEIVING: + encoding = va_arg(ap, PhoneEncoding *); + buf = va_arg(ap, char **); + len = va_arg(ap, size_t *); + _smscrypt_event_sms_received(encoding, buf, len); + break; + case PHONE_EVENT_SMS_SENDING: + encoding = va_arg(ap, PhoneEncoding *); + buf = va_arg(ap, char **); + len = va_arg(ap, size_t *); + _smscrypt_event_sms_sending(encoding, buf, len); + break; + /* ignore the rest */ + default: + break; + } + va_end(ap); + return 0; +} + +static void _smscrypt_event_sms_received(PhoneEncoding * encoding, char ** buf, + size_t * len) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(%u, buf, %lu)\n", __func__, *encoding, + *len); +#endif + if(*encoding == PHONE_ENCODING_UTF8) + return; /* not for us */ + /* FIXME really implement */ + *encoding = PHONE_ENCODING_UTF8; +} + +static void _smscrypt_event_sms_sending(PhoneEncoding * encoding, char ** buf, + size_t * len) +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: %s(%u, buf, %lu)\n", __func__, *encoding, *len); +#endif + if(*encoding != PHONE_ENCODING_UTF8) + return; /* not for us */ + /* FIXME really implement */ + *encoding = PHONE_ENCODING_DATA; +} + + +/* smscrypt_settings */ +static void _smscrypt_settings(PhonePlugin * plugin) +{ + /* FIXME implement */ +}