2014-02-08 19:34:00 -05:00
/*
2014-02-13 18:07:09 -05:00
* otrlibv4 . c
2014-02-08 19:34:00 -05:00
*
2015-02-10 18:16:09 -05:00
* Copyright ( C ) 2012 - 2015 James Booth < boothj5 @ gmail . com >
2014-02-08 19:34:00 -05:00
*
* This file is part of Profanity .
*
* Profanity is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* Profanity 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 Profanity . If not , see < http : //www.gnu.org/licenses/>.
*
2014-08-24 15:57:39 -04:00
* In addition , as a special exception , the copyright holders give permission to
* link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file , and
* distribute linked combinations including the two .
*
* You must obey the GNU General Public License in all respects for all of the
* code used other than OpenSSL . If you modify file ( s ) with this exception , you
* may extend this exception to your version of the file ( s ) , but you are not
* obligated to do so . If you do not wish to do so , delete this exception
* statement from your version . If you delete this exception statement from all
* source files in the program , then also delete it here .
*
2014-02-08 19:34:00 -05:00
*/
# include <libotr/proto.h>
# include <libotr/privkey.h>
# include <libotr/message.h>
2014-04-16 15:52:14 -04:00
# include "ui/ui.h"
2015-10-26 19:22:59 -04:00
# include "window_list.h"
2014-04-30 17:01:37 -04:00
# include "log.h"
2014-04-27 13:46:40 -04:00
# include "otr/otr.h"
# include "otr/otrlib.h"
2014-04-16 15:52:14 -04:00
2014-04-28 17:23:39 -04:00
static GTimer * timer ;
static unsigned int current_interval ;
2014-02-13 18:07:09 -05:00
OtrlPolicy
otrlib_policy ( void )
2014-02-08 19:34:00 -05:00
{
2014-03-24 17:02:10 -04:00
return OTRL_POLICY_ALLOW_V1 | OTRL_POLICY_ALLOW_V2 ;
2014-02-08 19:34:00 -05:00
}
2014-04-28 17:23:39 -04:00
void
otrlib_init_timer ( void )
{
OtrlUserState user_state = otr_userstate ( ) ;
timer = g_timer_new ( ) ;
current_interval = otrl_message_poll_get_default_interval ( user_state ) ;
}
void
otrlib_poll ( void )
{
gdouble elapsed = g_timer_elapsed ( timer , NULL ) ;
if ( current_interval ! = 0 & & elapsed > current_interval ) {
OtrlUserState user_state = otr_userstate ( ) ;
OtrlMessageAppOps * ops = otr_messageops ( ) ;
otrl_message_poll ( user_state , ops , NULL ) ;
g_timer_start ( timer ) ;
}
}
2015-10-25 18:40:09 -04:00
char *
2014-02-18 17:31:27 -05:00
otrlib_start_query ( void )
{
2014-04-22 13:07:19 -04:00
return " ?OTR?v2? This user has requested an Off-the-Record private conversation. However, you do not have a plugin to support that. See http://otr.cypherpunks.ca/ for more information. " ;
2014-02-18 17:31:27 -05:00
}
2014-02-08 21:24:47 -05:00
static const char *
2015-10-25 18:40:09 -04:00
cb_otr_error_message ( void * opdata , ConnContext * context , OtrlErrorCode err_code )
2014-02-08 21:24:47 -05:00
{
switch ( err_code )
{
case OTRL_ERRCODE_ENCRYPTION_ERROR :
2014-08-11 12:54:20 -04:00
return strdup ( " OTR Error: occurred while encrypting a message " ) ;
2014-02-08 21:24:47 -05:00
case OTRL_ERRCODE_MSG_NOT_IN_PRIVATE :
return strdup ( " OTR Error: Sent encrypted message to somebody who is not in a mutual OTR session " ) ;
case OTRL_ERRCODE_MSG_UNREADABLE :
return strdup ( " OTR Error: sent an unreadable encrypted message " ) ;
case OTRL_ERRCODE_MSG_MALFORMED :
return strdup ( " OTR Error: message sent is malformed " ) ;
default :
return strdup ( " OTR Error: unknown " ) ;
}
}
static void
cb_otr_error_message_free ( void * opdata , const char * err_msg )
{
2014-02-08 21:53:07 -05:00
free ( ( char * ) err_msg ) ;
2014-02-08 21:24:47 -05:00
}
2014-04-28 17:23:39 -04:00
static void
cb_timer_control ( void * opdata , unsigned int interval )
{
2014-06-17 19:32:36 -04:00
current_interval = interval ;
2014-04-28 17:23:39 -04:00
}
2014-02-08 21:24:47 -05:00
static void
cb_handle_msg_event ( void * opdata , OtrlMessageEvent msg_event ,
ConnContext * context , const char * message ,
gcry_error_t err )
2014-02-08 19:34:00 -05:00
{
2015-03-14 21:26:09 -04:00
GString * err_msg ;
switch ( msg_event )
{
case OTRL_MSGEVENT_ENCRYPTION_REQUIRED :
ui_handle_otr_error ( context - > username , " OTR: Policy requires encryption, but attempting to send an unencrypted message. " ) ;
break ;
case OTRL_MSGEVENT_ENCRYPTION_ERROR :
ui_handle_otr_error ( context - > username , " OTR: Error occured while encrypting a message, message not sent. " ) ;
break ;
case OTRL_MSGEVENT_CONNECTION_ENDED :
ui_handle_otr_error ( context - > username , " OTR: Message not sent because contact has ended the private conversation. " ) ;
break ;
case OTRL_MSGEVENT_SETUP_ERROR :
ui_handle_otr_error ( context - > username , " OTR: A private conversation could not be set up. " ) ;
break ;
case OTRL_MSGEVENT_MSG_REFLECTED :
ui_handle_otr_error ( context - > username , " OTR: Received our own OTR message. " ) ;
break ;
case OTRL_MSGEVENT_MSG_RESENT :
ui_handle_otr_error ( context - > username , " OTR: The previous message was resent. " ) ;
break ;
case OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE :
ui_handle_otr_error ( context - > username , " OTR: Received an encrypted message but no private connection established. " ) ;
break ;
case OTRL_MSGEVENT_RCVDMSG_UNREADABLE :
ui_handle_otr_error ( context - > username , " OTR: Cannot read the received message. " ) ;
break ;
case OTRL_MSGEVENT_RCVDMSG_MALFORMED :
ui_handle_otr_error ( context - > username , " OTR: The message received contains malformed data. " ) ;
break ;
case OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR :
err_msg = g_string_new ( " OTR: Received error: " ) ;
g_string_append ( err_msg , message ) ;
g_string_append ( err_msg , " . " ) ;
ui_handle_otr_error ( context - > username , err_msg - > str ) ;
g_string_free ( err_msg , TRUE ) ;
break ;
case OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED :
err_msg = g_string_new ( " OTR: Received an unencrypted message: " ) ;
g_string_append ( err_msg , message ) ;
ui_handle_otr_error ( context - > username , err_msg - > str ) ;
g_string_free ( err_msg , TRUE ) ;
break ;
case OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED :
ui_handle_otr_error ( context - > username , " OTR: Cannot recognize the type of message received. " ) ;
break ;
case OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE :
ui_handle_otr_error ( context - > username , " OTR: Received and discarded a message intended for another instance. " ) ;
break ;
default :
break ;
2014-02-11 16:21:33 -05:00
}
2014-02-08 19:34:00 -05:00
}
2014-04-27 13:46:40 -04:00
static void
cb_handle_smp_event ( void * opdata , OtrlSMPEvent smp_event ,
ConnContext * context , unsigned short progress_percent ,
char * question )
{
NextExpectedSMP nextMsg = context - > smstate - > nextExpected ;
OtrlUserState user_state = otr_userstate ( ) ;
OtrlMessageAppOps * ops = otr_messageops ( ) ;
GHashTable * smp_initiators = otr_smpinitators ( ) ;
2015-10-26 19:22:59 -04:00
ProfChatWin * chatwin = wins_get_chat ( context - > username ) ;
2014-04-27 13:46:40 -04:00
switch ( smp_event )
{
case OTRL_SMPEVENT_ASK_FOR_SECRET :
2015-10-26 19:22:59 -04:00
if ( chatwin ) {
ui_smp_recipient_initiated ( chatwin ) ;
}
2014-04-27 13:46:40 -04:00
g_hash_table_insert ( smp_initiators , strdup ( context - > username ) , strdup ( context - > username ) ) ;
break ;
2014-05-07 16:15:28 -04:00
case OTRL_SMPEVENT_ASK_FOR_ANSWER :
2015-10-26 19:29:01 -04:00
if ( chatwin ) {
ui_smp_recipient_initiated_q ( chatwin , question ) ;
}
2014-05-07 16:15:28 -04:00
break ;
2014-04-27 13:46:40 -04:00
case OTRL_SMPEVENT_SUCCESS :
2014-05-07 16:15:28 -04:00
if ( context - > smstate - > received_question = = 0 ) {
ui_smp_successful ( context - > username ) ;
ui_trust ( context - > username ) ;
} else {
ui_smp_answer_success ( context - > username ) ;
}
2014-04-27 13:46:40 -04:00
break ;
2014-06-17 19:32:36 -04:00
2014-04-27 13:46:40 -04:00
case OTRL_SMPEVENT_FAILURE :
2014-05-07 16:15:28 -04:00
if ( context - > smstate - > received_question = = 0 ) {
if ( nextMsg = = OTRL_SMP_EXPECT3 ) {
ui_smp_unsuccessful_sender ( context - > username ) ;
} else if ( nextMsg = = OTRL_SMP_EXPECT4 ) {
ui_smp_unsuccessful_receiver ( context - > username ) ;
}
2014-04-27 13:46:40 -04:00
ui_untrust ( context - > username ) ;
2014-05-07 16:15:28 -04:00
} else {
ui_smp_answer_failure ( context - > username ) ;
2014-04-27 13:46:40 -04:00
}
break ;
case OTRL_SMPEVENT_ERROR :
otrl_message_abort_smp ( user_state , ops , NULL , context ) ;
break ;
case OTRL_SMPEVENT_CHEATED :
otrl_message_abort_smp ( user_state , ops , NULL , context ) ;
break ;
case OTRL_SMPEVENT_ABORT :
ui_smp_aborted ( context - > username ) ;
ui_untrust ( context - > username ) ;
break ;
case OTRL_SMPEVENT_IN_PROGRESS :
break ;
default :
break ;
}
}
2014-02-08 19:34:00 -05:00
void
2014-02-13 18:07:09 -05:00
otrlib_init_ops ( OtrlMessageAppOps * ops )
2014-02-08 19:34:00 -05:00
{
2014-02-13 18:07:09 -05:00
ops - > otr_error_message = cb_otr_error_message ;
ops - > otr_error_message_free = cb_otr_error_message_free ;
ops - > handle_msg_event = cb_handle_msg_event ;
2014-04-27 13:46:40 -04:00
ops - > handle_smp_event = cb_handle_smp_event ;
2014-04-28 17:23:39 -04:00
ops - > timer_control = cb_timer_control ;
2014-02-08 19:34:00 -05:00
}
2015-10-25 18:40:09 -04:00
ConnContext *
otrlib_context_find ( OtrlUserState user_state , const char * const recipient , char * jid )
2014-02-08 19:34:00 -05:00
{
2014-02-13 18:07:09 -05:00
return otrl_context_find ( user_state , recipient , jid , " xmpp " , OTRL_INSTAG_MASTER , 0 , NULL , NULL , NULL ) ;
2014-02-08 19:34:00 -05:00
}
void
2015-10-25 18:40:09 -04:00
otrlib_end_session ( OtrlUserState user_state , const char * const recipient , char * jid , OtrlMessageAppOps * ops )
2014-02-08 19:34:00 -05:00
{
ConnContext * context = otrl_context_find ( user_state , recipient , jid , " xmpp " ,
2014-02-11 18:03:07 -05:00
OTRL_INSTAG_MASTER , 0 , NULL , NULL , NULL ) ;
2014-02-08 19:34:00 -05:00
2015-05-04 17:55:28 -04:00
if ( context ) {
2014-02-13 18:07:09 -05:00
otrl_message_disconnect ( user_state , ops , NULL , jid , " xmpp " , recipient , 0 ) ;
2014-02-08 19:34:00 -05:00
}
}
2014-02-13 18:07:09 -05:00
gcry_error_t
2015-10-25 18:40:09 -04:00
otrlib_encrypt_message ( OtrlUserState user_state , OtrlMessageAppOps * ops , char * jid , const char * const to ,
const char * const message , char * * newmessage )
2014-02-08 19:34:00 -05:00
{
gcry_error_t err ;
err = otrl_message_sending (
user_state ,
2014-02-13 18:07:09 -05:00
ops ,
2014-02-08 19:34:00 -05:00
NULL ,
jid ,
" xmpp " ,
to ,
2014-02-11 18:03:07 -05:00
OTRL_INSTAG_MASTER ,
2014-02-08 19:34:00 -05:00
message ,
0 ,
2014-02-13 18:07:09 -05:00
newmessage ,
2014-02-11 18:03:07 -05:00
OTRL_FRAGMENT_SEND_SKIP ,
2014-02-08 21:53:07 -05:00
NULL ,
2014-02-08 19:34:00 -05:00
NULL ,
NULL ) ;
2014-02-08 21:53:07 -05:00
2014-02-13 18:07:09 -05:00
return err ;
2014-02-08 19:34:00 -05:00
}
2014-02-13 18:07:09 -05:00
int
2015-10-25 18:40:09 -04:00
otrlib_decrypt_message ( OtrlUserState user_state , OtrlMessageAppOps * ops , char * jid , const char * const from ,
const char * const message , char * * decrypted , OtrlTLV * * tlvs )
2014-02-08 19:34:00 -05:00
{
2014-02-13 18:07:09 -05:00
return otrl_message_receiving (
2014-02-08 21:53:07 -05:00
user_state ,
2014-02-13 18:07:09 -05:00
ops ,
2014-02-08 21:53:07 -05:00
NULL ,
jid ,
" xmpp " ,
from ,
message ,
2014-02-13 18:07:09 -05:00
decrypted ,
tlvs ,
2014-02-08 21:53:07 -05:00
NULL ,
NULL ,
NULL ) ;
2014-02-08 19:34:00 -05:00
}
2014-04-27 13:46:40 -04:00
void
otrlib_handle_tlvs ( OtrlUserState user_state , OtrlMessageAppOps * ops , ConnContext * context , OtrlTLV * tlvs , GHashTable * smp_initiators )
{
}