Back to index

texmacs  1.0.7.15
tm_link.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tm_link.cpp
00004 * DESCRIPTION: Links between TeXmacs and extern programs
00005 * COPYRIGHT  : (C) 2007  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "tm_link.hpp"
00013 #include "../Plugins/Openssl/openssl.hpp"
00014 #include "timer.hpp"
00015 
00016 /******************************************************************************
00017 * Sending data by packets
00018 ******************************************************************************/
00019 
00020 static bool
00021 message_complete (string s) {
00022   int start= 0;
00023   int i, n= N(s);
00024   if (n>0 && s[0] == '!') start= 1;
00025   for (i=start; i<n; i++)
00026     if (s[i] == '\n') break;
00027   if (i == n) return false;
00028   return (n - (i+1)) >= as_int (s (start, i));
00029 }
00030 
00031 static string
00032 message_receive (string& s) {
00033   int start= 0;
00034   int i, n= N(s);
00035   if (n>0 && s[0] == '!') start= 1;
00036   for (i=start; i<n; i++)
00037     if (s[i] == '\n') break;
00038   if (i == n) return "";
00039   int l= as_int (s (start, i++));
00040   string r= s (i, i+l);
00041   s= s (i+l, n);
00042   return r;
00043 }
00044 
00045 void
00046 tm_link_rep::write_packet (string s, int channel) {
00047   if (secret != "") s= secret_encode (s, secret);
00048   write ((as_string (N (s)) * "\n") * s, channel);
00049 }
00050 
00051 bool
00052 tm_link_rep::complete_packet (int channel) {
00053   return message_complete (watch (channel));
00054 }
00055 
00056 string
00057 tm_link_rep::read_packet (int channel, int timeout, bool& success) {
00058   success= false;
00059   string& r= watch (channel);
00060   time_t start= texmacs_time ();
00061   while (!message_complete (r)) {
00062     int n= N(r);
00063     if (timeout > 0) listen (timeout);
00064     if (N(r) == n && (texmacs_time () - start >= timeout)) return "";
00065   }
00066   if (channel == LINK_OUT && N(r) > 0 && r[0] == '!') {
00067     secure_server (message_receive (r));
00068     return "";
00069   }
00070   else {
00071     string back= message_receive (r);
00072     if (secret != "") back= secret_decode (back, secret);
00073     success= true;
00074     return back;
00075   }
00076 }
00077 
00078 /******************************************************************************
00079 * Data encryption
00080 ******************************************************************************/
00081 
00082 void
00083 tm_link_rep::secure_server (string client_public) {
00084   if (secret != "") return;
00085   string k= secret_generate ();
00086   string s= rsa_encode (k, client_public);
00087   write_packet (s, LINK_IN);
00088   secret= k;
00089 }
00090 
00091 void
00092 tm_link_rep::secure_client () {
00093   if (secret != "") return;
00094   write ("!", LINK_IN);
00095   write_packet (rsa_my_public_key (), LINK_IN);
00096   bool success;
00097   string r= read_packet (LINK_OUT, 10000, success);
00098   if (!success) { stop (); return; }
00099   secret= rsa_decode (r, rsa_my_private_key ());
00100 }