PageRenderTime 39ms CodeModel.GetById 21ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/TeXmacs-1.0.7.11-src/src/System/Link/tm_link.cpp

#
C++ | 100 lines | 74 code | 11 blank | 15 comment | 36 complexity | 81f09c543c8206c3d848af39bc420394 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception
  1
  2/******************************************************************************
  3* MODULE     : tm_link.cpp
  4* DESCRIPTION: Links between TeXmacs and extern programs
  5* COPYRIGHT  : (C) 2007  Joris van der Hoeven
  6*******************************************************************************
  7* This software falls under the GNU general public license version 3 or later.
  8* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
  9* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
 10******************************************************************************/
 11
 12#include "tm_link.hpp"
 13#include "../Plugins/Openssl/openssl.hpp"
 14#include "timer.hpp"
 15
 16/******************************************************************************
 17* Sending data by packets
 18******************************************************************************/
 19
 20static bool
 21message_complete (string s) {
 22  int start= 0;
 23  int i, n= N(s);
 24  if (n>0 && s[0] == '!') start= 1;
 25  for (i=start; i<n; i++)
 26    if (s[i] == '\n') break;
 27  if (i == n) return false;
 28  return (n - (i+1)) >= as_int (s (start, i));
 29}
 30
 31static string
 32message_receive (string& s) {
 33  int start= 0;
 34  int i, n= N(s);
 35  if (n>0 && s[0] == '!') start= 1;
 36  for (i=start; i<n; i++)
 37    if (s[i] == '\n') break;
 38  if (i == n) return "";
 39  int l= as_int (s (start, i++));
 40  string r= s (i, i+l);
 41  s= s (i+l, n);
 42  return r;
 43}
 44
 45void
 46tm_link_rep::write_packet (string s, int channel) {
 47  if (secret != "") s= secret_encode (s, secret);
 48  write ((as_string (N (s)) * "\n") * s, channel);
 49}
 50
 51bool
 52tm_link_rep::complete_packet (int channel) {
 53  return message_complete (watch (channel));
 54}
 55
 56string
 57tm_link_rep::read_packet (int channel, int timeout, bool& success) {
 58  success= false;
 59  string& r= watch (channel);
 60  time_t start= texmacs_time ();
 61  while (!message_complete (r)) {
 62    int n= N(r);
 63    if (timeout > 0) listen (timeout);
 64    if (N(r) == n && (texmacs_time () - start >= timeout)) return "";
 65  }
 66  if (channel == LINK_OUT && N(r) > 0 && r[0] == '!') {
 67    secure_server (message_receive (r));
 68    return "";
 69  }
 70  else {
 71    string back= message_receive (r);
 72    if (secret != "") back= secret_decode (back, secret);
 73    success= true;
 74    return back;
 75  }
 76}
 77
 78/******************************************************************************
 79* Data encryption
 80******************************************************************************/
 81
 82void
 83tm_link_rep::secure_server (string client_public) {
 84  if (secret != "") return;
 85  string k= secret_generate ();
 86  string s= rsa_encode (k, client_public);
 87  write_packet (s, LINK_IN);
 88  secret= k;
 89}
 90
 91void
 92tm_link_rep::secure_client () {
 93  if (secret != "") return;
 94  write ("!", LINK_IN);
 95  write_packet (rsa_my_public_key (), LINK_IN);
 96  bool success;
 97  string r= read_packet (LINK_OUT, 10000, success);
 98  if (!success) { stop (); return; }
 99  secret= rsa_decode (r, rsa_my_private_key ());
100}