diff options
| author | Ted Zlatanov | 2010-09-26 01:06:28 -0500 |
|---|---|---|
| committer | Ted Zlatanov | 2010-09-26 01:06:28 -0500 |
| commit | 8af55556e6cc093641dde5205aa5e295039b809f (patch) | |
| tree | 2f0bebd6d170687acc470e4a1a030abd18daf651 /src | |
| parent | 8ccbef23ea624d892bada3c66ef2339ada342997 (diff) | |
| download | emacs-8af55556e6cc093641dde5205aa5e295039b809f.tar.gz emacs-8af55556e6cc093641dde5205aa5e295039b809f.zip | |
Set up GnuTLS support.
* configure.in: Set up GnuTLS.
* lisp/net/gnutls.el: GnuTLS glue code to set up a connection.
* src/Makefile.in (LIBGNUTLS_LIBS, LIBGNUTLS_CFLAGS, ALL_CFLAGS)
(obj, LIBES): Set up GnuTLS support.
* src/config.in: Set up GnuTLS support.
* src/emacs.c: Set up GnuTLS support and call syms_of_gnutls.
* src/gnutls.c: The source code for GnuTLS support in Emacs.
* src/gnutls.h: The GnuTLS glue for Emacs, macros and enums.
* src/process.c (make_process, Fstart_process)
(read_process_output, send_process): Set up GnuTLS support for
process input/output file descriptors.
* src/process.h: Set up GnuTLS support.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 19 | ||||
| -rw-r--r-- | src/Makefile.in | 7 | ||||
| -rw-r--r-- | src/config.in | 9 | ||||
| -rw-r--r-- | src/emacs.c | 8 | ||||
| -rw-r--r-- | src/gnutls.c | 551 | ||||
| -rw-r--r-- | src/gnutls.h | 60 | ||||
| -rw-r--r-- | src/process.c | 38 | ||||
| -rw-r--r-- | src/process.h | 15 |
8 files changed, 703 insertions, 4 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d43853e7baa..e6bf911952e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,22 @@ | |||
| 1 | 2010-09-26 Teodor Zlatanov <tzz@lifelogs.com> | ||
| 2 | |||
| 3 | * process.h: Set up GnuTLS support. | ||
| 4 | |||
| 5 | * process.c (make_process, Fstart_process) | ||
| 6 | (read_process_output, send_process): Set up GnuTLS support for | ||
| 7 | process input/output file descriptors. | ||
| 8 | |||
| 9 | * gnutls.h: The GnuTLS glue for Emacs, macros and enums. | ||
| 10 | |||
| 11 | * gnutls.c: The source code for GnuTLS support in Emacs. | ||
| 12 | |||
| 13 | * emacs.c: Set up GnuTLS support and call syms_of_gnutls. | ||
| 14 | |||
| 15 | * config.in: Set up GnuTLS support. | ||
| 16 | |||
| 17 | * Makefile.in (LIBGNUTLS_LIBS, LIBGNUTLS_CFLAGS, ALL_CFLAGS) | ||
| 18 | (obj, LIBES): Set up GnuTLS support. | ||
| 19 | |||
| 1 | 2010-09-26 Juanma Barranquero <lekktu@gmail.com> | 20 | 2010-09-26 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 21 | ||
| 3 | * w32.c (get_emacs_configuration_options): Fix previous change. | 22 | * w32.c (get_emacs_configuration_options): Fix previous change. |
diff --git a/src/Makefile.in b/src/Makefile.in index 7fe3fe0ae81..00706460d25 100644 --- a/src/Makefile.in +++ b/src/Makefile.in | |||
| @@ -286,6 +286,9 @@ LIBRESOLV = @LIBRESOLV@ | |||
| 286 | 286 | ||
| 287 | LIBSELINUX_LIBS = @LIBSELINUX_LIBS@ | 287 | LIBSELINUX_LIBS = @LIBSELINUX_LIBS@ |
| 288 | 288 | ||
| 289 | LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ | ||
| 290 | LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ | ||
| 291 | |||
| 289 | INTERVALS_H = dispextern.h intervals.h composite.h | 292 | INTERVALS_H = dispextern.h intervals.h composite.h |
| 290 | 293 | ||
| 291 | GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ | 294 | GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ |
| @@ -325,6 +328,7 @@ ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} \ | |||
| 325 | ${LIBXML2_CFLAGS} ${DBUS_CFLAGS} \ | 328 | ${LIBXML2_CFLAGS} ${DBUS_CFLAGS} \ |
| 326 | ${GCONF_CFLAGS} ${FREETYPE_CFLAGS} ${FONTCONFIG_CFLAGS} \ | 329 | ${GCONF_CFLAGS} ${FREETYPE_CFLAGS} ${FONTCONFIG_CFLAGS} \ |
| 327 | ${LIBOTF_CFLAGS} ${M17N_FLT_CFLAGS} ${DEPFLAGS} ${PROFILING_CFLAGS} \ | 330 | ${LIBOTF_CFLAGS} ${M17N_FLT_CFLAGS} ${DEPFLAGS} ${PROFILING_CFLAGS} \ |
| 331 | $(LIBGNUTLS_CFLAGS) \ | ||
| 328 | ${C_WARNINGS_SWITCH} ${CFLAGS} | 332 | ${C_WARNINGS_SWITCH} ${CFLAGS} |
| 329 | ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS) | 333 | ALL_OBJC_CFLAGS=$(ALL_CFLAGS) $(GNU_OBJC_CFLAGS) |
| 330 | 334 | ||
| @@ -349,7 +353,7 @@ obj= dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \ | |||
| 349 | alloc.o data.o doc.o editfns.o callint.o \ | 353 | alloc.o data.o doc.o editfns.o callint.o \ |
| 350 | eval.o floatfns.o fns.o font.o print.o lread.o \ | 354 | eval.o floatfns.o fns.o font.o print.o lread.o \ |
| 351 | syntax.o $(UNEXEC_OBJ) bytecode.o \ | 355 | syntax.o $(UNEXEC_OBJ) bytecode.o \ |
| 352 | process.o callproc.o \ | 356 | process.o gnutls.o callproc.o \ |
| 353 | region-cache.o sound.o atimer.o \ | 357 | region-cache.o sound.o atimer.o \ |
| 354 | doprnt.o strftime.o intervals.o textprop.o composite.o md5.o xml.o \ | 358 | doprnt.o strftime.o intervals.o textprop.o composite.o md5.o xml.o \ |
| 355 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) | 359 | $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) |
| @@ -601,6 +605,7 @@ LIBES = $(LIBS) $(LIBX_BASE) $(LIBX_OTHER) $(LIBSOUND) \ | |||
| 601 | ${LIBXML2_LIBS} $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ | 605 | ${LIBXML2_LIBS} $(LIBGPM) $(LIBRESOLV) $(LIBS_SYSTEM) \ |
| 602 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) ${GCONF_LIBS} ${LIBSELINUX_LIBS} \ | 606 | $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) ${GCONF_LIBS} ${LIBSELINUX_LIBS} \ |
| 603 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ | 607 | $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ |
| 608 | $(LIBGNUTLS_LIBS) \ | ||
| 604 | $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) | 609 | $(LIB_GCC) $(LIB_MATH) $(LIB_STANDARD) $(LIB_GCC) |
| 605 | 610 | ||
| 606 | all: emacs${EXEEXT} $(OTHER_FILES) | 611 | all: emacs${EXEEXT} $(OTHER_FILES) |
diff --git a/src/config.in b/src/config.in index 199afbd78ba..43ebb756215 100644 --- a/src/config.in +++ b/src/config.in | |||
| @@ -255,6 +255,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 255 | /* Define to 1 if you have a gif (or ungif) library. */ | 255 | /* Define to 1 if you have a gif (or ungif) library. */ |
| 256 | #undef HAVE_GIF | 256 | #undef HAVE_GIF |
| 257 | 257 | ||
| 258 | /* Define if we have the GNU TLS library. */ | ||
| 259 | #undef HAVE_GNUTLS | ||
| 260 | |||
| 258 | /* Define to 1 if you have the gpm library (-lgpm). */ | 261 | /* Define to 1 if you have the gpm library (-lgpm). */ |
| 259 | #undef HAVE_GPM | 262 | #undef HAVE_GPM |
| 260 | 263 | ||
| @@ -1094,6 +1097,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 1094 | #include config_opsysfile | 1097 | #include config_opsysfile |
| 1095 | #include config_machfile | 1098 | #include config_machfile |
| 1096 | 1099 | ||
| 1100 | #if HAVE_GNUTLS | ||
| 1101 | #define LIBGNUTLS $(LIBGNUTLS_LIBS) | ||
| 1102 | #else /* not HAVE_GNUTLS */ | ||
| 1103 | #define LIBGNUTLS | ||
| 1104 | #endif /* not HAVE_GNUTLS */ | ||
| 1105 | |||
| 1097 | /* Set up some defines, C and LD flags for NeXTstep interface on GNUstep. | 1106 | /* Set up some defines, C and LD flags for NeXTstep interface on GNUstep. |
| 1098 | (There is probably a better place to do this, but right now the Cocoa | 1107 | (There is probably a better place to do this, but right now the Cocoa |
| 1099 | side does this in s/darwin.h and we cannot | 1108 | side does this in s/darwin.h and we cannot |
diff --git a/src/emacs.c b/src/emacs.c index 5e7efb64226..397b6d1ce88 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -59,6 +59,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 59 | #include "keyboard.h" | 59 | #include "keyboard.h" |
| 60 | #include "keymap.h" | 60 | #include "keymap.h" |
| 61 | 61 | ||
| 62 | #ifdef HAVE_GNUTLS | ||
| 63 | #include "gnutls.h" | ||
| 64 | #endif | ||
| 65 | |||
| 62 | #ifdef HAVE_NS | 66 | #ifdef HAVE_NS |
| 63 | #include "nsterm.h" | 67 | #include "nsterm.h" |
| 64 | #endif | 68 | #endif |
| @@ -1569,6 +1573,10 @@ main (int argc, char **argv) | |||
| 1569 | syms_of_fontset (); | 1573 | syms_of_fontset (); |
| 1570 | #endif /* HAVE_NS */ | 1574 | #endif /* HAVE_NS */ |
| 1571 | 1575 | ||
| 1576 | #ifdef HAVE_GNUTLS | ||
| 1577 | syms_of_gnutls (); | ||
| 1578 | #endif | ||
| 1579 | |||
| 1572 | #ifdef HAVE_DBUS | 1580 | #ifdef HAVE_DBUS |
| 1573 | syms_of_dbusbind (); | 1581 | syms_of_dbusbind (); |
| 1574 | #endif /* HAVE_DBUS */ | 1582 | #endif /* HAVE_DBUS */ |
diff --git a/src/gnutls.c b/src/gnutls.c new file mode 100644 index 00000000000..50bf7940119 --- /dev/null +++ b/src/gnutls.c | |||
| @@ -0,0 +1,551 @@ | |||
| 1 | /* GnuTLS glue for GNU Emacs. | ||
| 2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation, either version 3 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #include <config.h> | ||
| 20 | #include <errno.h> | ||
| 21 | #include <setjmp.h> | ||
| 22 | |||
| 23 | #include "lisp.h" | ||
| 24 | #include "process.h" | ||
| 25 | |||
| 26 | #ifdef HAVE_GNUTLS | ||
| 27 | #include <gnutls/gnutls.h> | ||
| 28 | |||
| 29 | Lisp_Object Qgnutls_code; | ||
| 30 | Lisp_Object Qgnutls_anon, Qgnutls_x509pki; | ||
| 31 | Lisp_Object Qgnutls_e_interrupted, Qgnutls_e_again, | ||
| 32 | Qgnutls_e_invalid_session, Qgnutls_e_not_ready_for_handshake; | ||
| 33 | int global_initialized; | ||
| 34 | |||
| 35 | int | ||
| 36 | emacs_gnutls_write (int fildes, gnutls_session_t state, char *buf, | ||
| 37 | unsigned int nbyte) | ||
| 38 | { | ||
| 39 | register int rtnval, bytes_written; | ||
| 40 | |||
| 41 | bytes_written = 0; | ||
| 42 | |||
| 43 | while (nbyte > 0) | ||
| 44 | { | ||
| 45 | rtnval = gnutls_write (state, buf, nbyte); | ||
| 46 | |||
| 47 | if (rtnval == -1) | ||
| 48 | { | ||
| 49 | if (errno == EINTR) | ||
| 50 | continue; | ||
| 51 | else | ||
| 52 | return (bytes_written ? bytes_written : -1); | ||
| 53 | } | ||
| 54 | |||
| 55 | buf += rtnval; | ||
| 56 | nbyte -= rtnval; | ||
| 57 | bytes_written += rtnval; | ||
| 58 | } | ||
| 59 | fsync (STDOUT_FILENO); | ||
| 60 | |||
| 61 | return (bytes_written); | ||
| 62 | } | ||
| 63 | |||
| 64 | int | ||
| 65 | emacs_gnutls_read (int fildes, gnutls_session_t state, char *buf, | ||
| 66 | unsigned int nbyte) | ||
| 67 | { | ||
| 68 | register int rtnval; | ||
| 69 | |||
| 70 | do { | ||
| 71 | rtnval = gnutls_read (state, buf, nbyte); | ||
| 72 | } while (rtnval == GNUTLS_E_INTERRUPTED || rtnval == GNUTLS_E_AGAIN); | ||
| 73 | fsync (STDOUT_FILENO); | ||
| 74 | |||
| 75 | return (rtnval); | ||
| 76 | } | ||
| 77 | |||
| 78 | /* convert an integer error to a Lisp_Object; it will be either a | ||
| 79 | known symbol like `gnutls_e_interrupted' and `gnutls_e_again' or | ||
| 80 | simply the integer value of the error. GNUTLS_E_SUCCESS is mapped | ||
| 81 | to Qt. */ | ||
| 82 | Lisp_Object gnutls_make_error (int error) | ||
| 83 | { | ||
| 84 | switch (error) | ||
| 85 | { | ||
| 86 | case GNUTLS_E_SUCCESS: | ||
| 87 | return Qt; | ||
| 88 | case GNUTLS_E_AGAIN: | ||
| 89 | return Qgnutls_e_again; | ||
| 90 | case GNUTLS_E_INTERRUPTED: | ||
| 91 | return Qgnutls_e_interrupted; | ||
| 92 | case GNUTLS_E_INVALID_SESSION: | ||
| 93 | return Qgnutls_e_invalid_session; | ||
| 94 | } | ||
| 95 | |||
| 96 | return make_number (error); | ||
| 97 | } | ||
| 98 | |||
| 99 | DEFUN ("gnutls-get-initstage", Fgnutls_get_initstage, Sgnutls_get_initstage, 1, 1, 0, | ||
| 100 | doc: /* Return the GnuTLS init stage of PROCESS. | ||
| 101 | See also `gnutls-boot'. */) | ||
| 102 | (Lisp_Object proc) | ||
| 103 | { | ||
| 104 | CHECK_PROCESS (proc); | ||
| 105 | |||
| 106 | return make_number (GNUTLS_INITSTAGE (proc)); | ||
| 107 | } | ||
| 108 | |||
| 109 | DEFUN ("gnutls-errorp", Fgnutls_errorp, Sgnutls_errorp, 1, 1, 0, | ||
| 110 | doc: /* Returns t if ERROR (as generated by gnutls_make_error) | ||
| 111 | indicates a GnuTLS problem. */) | ||
| 112 | (Lisp_Object error) | ||
| 113 | { | ||
| 114 | if (EQ (error, Qt)) return Qnil; | ||
| 115 | |||
| 116 | return Qt; | ||
| 117 | } | ||
| 118 | |||
| 119 | DEFUN ("gnutls-error-fatalp", Fgnutls_error_fatalp, Sgnutls_error_fatalp, 1, 1, 0, | ||
| 120 | doc: /* Checks if ERROR is fatal. | ||
| 121 | ERROR is an integer or a symbol with an integer `gnutls-code' property. */) | ||
| 122 | (Lisp_Object err) | ||
| 123 | { | ||
| 124 | Lisp_Object code; | ||
| 125 | |||
| 126 | if (EQ (err, Qt)) return Qnil; | ||
| 127 | |||
| 128 | if (SYMBOLP (err)) | ||
| 129 | { | ||
| 130 | code = Fget (err, Qgnutls_code); | ||
| 131 | if (NUMBERP (code)) | ||
| 132 | { | ||
| 133 | err = code; | ||
| 134 | } | ||
| 135 | else | ||
| 136 | { | ||
| 137 | error ("Symbol has no numeric gnutls-code property"); | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | if (!NUMBERP (err)) | ||
| 142 | error ("Not an error symbol or code"); | ||
| 143 | |||
| 144 | if (0 == gnutls_error_is_fatal (XINT (err))) | ||
| 145 | return Qnil; | ||
| 146 | |||
| 147 | return Qt; | ||
| 148 | } | ||
| 149 | |||
| 150 | DEFUN ("gnutls-error-string", Fgnutls_error_string, Sgnutls_error_string, 1, 1, 0, | ||
| 151 | doc: /* Returns a description of ERROR. | ||
| 152 | ERROR is an integer or a symbol with an integer `gnutls-code' property. */) | ||
| 153 | (Lisp_Object err) | ||
| 154 | { | ||
| 155 | Lisp_Object code; | ||
| 156 | |||
| 157 | if (EQ (err, Qt)) return build_string ("Not an error"); | ||
| 158 | |||
| 159 | if (SYMBOLP (err)) | ||
| 160 | { | ||
| 161 | code = Fget (err, Qgnutls_code); | ||
| 162 | if (NUMBERP (code)) | ||
| 163 | { | ||
| 164 | err = code; | ||
| 165 | } | ||
| 166 | else | ||
| 167 | { | ||
| 168 | return build_string ("Symbol has no numeric gnutls-code property"); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | if (!NUMBERP (err)) | ||
| 173 | return build_string ("Not an error symbol or code"); | ||
| 174 | |||
| 175 | return build_string (gnutls_strerror (XINT (err))); | ||
| 176 | } | ||
| 177 | |||
| 178 | DEFUN ("gnutls-deinit", Fgnutls_deinit, Sgnutls_deinit, 1, 1, 0, | ||
| 179 | doc: /* Deallocate GNU TLS resources associated with PROCESS. | ||
| 180 | See also `gnutls-init'. */) | ||
| 181 | (Lisp_Object proc) | ||
| 182 | { | ||
| 183 | gnutls_session_t state; | ||
| 184 | |||
| 185 | CHECK_PROCESS (proc); | ||
| 186 | state = XPROCESS (proc)->gnutls_state; | ||
| 187 | |||
| 188 | if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT) | ||
| 189 | { | ||
| 190 | gnutls_deinit (state); | ||
| 191 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT - 1; | ||
| 192 | } | ||
| 193 | |||
| 194 | return Qt; | ||
| 195 | } | ||
| 196 | |||
| 197 | /* Initializes global GNU TLS state to defaults. | ||
| 198 | Call `gnutls-global-deinit' when GNU TLS usage is no longer needed. | ||
| 199 | Returns zero on success. */ | ||
| 200 | Lisp_Object gnutls_emacs_global_init (void) | ||
| 201 | { | ||
| 202 | int ret = GNUTLS_E_SUCCESS; | ||
| 203 | |||
| 204 | if (!global_initialized) | ||
| 205 | ret = gnutls_global_init (); | ||
| 206 | |||
| 207 | global_initialized = 1; | ||
| 208 | |||
| 209 | return gnutls_make_error (ret); | ||
| 210 | } | ||
| 211 | |||
| 212 | /* Deinitializes global GNU TLS state. | ||
| 213 | See also `gnutls-global-init'. */ | ||
| 214 | Lisp_Object gnutls_emacs_global_deinit (void) | ||
| 215 | { | ||
| 216 | if (global_initialized) | ||
| 217 | gnutls_global_deinit (); | ||
| 218 | |||
| 219 | global_initialized = 0; | ||
| 220 | |||
| 221 | return gnutls_make_error (GNUTLS_E_SUCCESS); | ||
| 222 | } | ||
| 223 | |||
| 224 | DEFUN ("gnutls-boot", Fgnutls_boot, Sgnutls_boot, 3, 6, 0, | ||
| 225 | doc: /* Initializes client-mode GnuTLS for process PROC. | ||
| 226 | Currently only client mode is supported. Returns a success/failure | ||
| 227 | value you can check with `gnutls-errorp'. | ||
| 228 | |||
| 229 | PRIORITY_STRING is a string describing the priority. | ||
| 230 | TYPE is either `gnutls-anon' or `gnutls-x509pki'. | ||
| 231 | TRUSTFILE is a PEM encoded trust file for `gnutls-x509pki'. | ||
| 232 | KEYFILE is ... for `gnutls-x509pki' (TODO). | ||
| 233 | CALLBACK is ... for `gnutls-x509pki' (TODO). | ||
| 234 | |||
| 235 | Note that the priority is set on the client. The server does not use | ||
| 236 | the protocols's priority except for disabling protocols that were not | ||
| 237 | specified. | ||
| 238 | |||
| 239 | Processes must be initialized with this function before other GNU TLS | ||
| 240 | functions are used. This function allocates resources which can only | ||
| 241 | be deallocated by calling `gnutls-deinit' or by calling it again. | ||
| 242 | |||
| 243 | Each authentication type may need additional information in order to | ||
| 244 | work. For X.509 PKI (`gnutls-x509pki'), you need TRUSTFILE and | ||
| 245 | KEYFILE and optionally CALLBACK. */) | ||
| 246 | (Lisp_Object proc, Lisp_Object priority_string, Lisp_Object type, | ||
| 247 | Lisp_Object trustfile, Lisp_Object keyfile, Lisp_Object callback) | ||
| 248 | { | ||
| 249 | int ret = GNUTLS_E_SUCCESS; | ||
| 250 | |||
| 251 | /* TODO: GNUTLS_X509_FMT_DER is also an option. */ | ||
| 252 | int file_format = GNUTLS_X509_FMT_PEM; | ||
| 253 | |||
| 254 | gnutls_session_t state; | ||
| 255 | gnutls_certificate_credentials_t x509_cred; | ||
| 256 | gnutls_anon_client_credentials_t anon_cred; | ||
| 257 | gnutls_srp_client_credentials_t srp_cred; | ||
| 258 | gnutls_datum_t data; | ||
| 259 | Lisp_Object global_init; | ||
| 260 | |||
| 261 | CHECK_PROCESS (proc); | ||
| 262 | CHECK_SYMBOL (type); | ||
| 263 | CHECK_STRING (priority_string); | ||
| 264 | |||
| 265 | state = XPROCESS (proc)->gnutls_state; | ||
| 266 | |||
| 267 | /* always initialize globals. */ | ||
| 268 | global_init = gnutls_emacs_global_init (); | ||
| 269 | if (! NILP (Fgnutls_errorp (global_init))) | ||
| 270 | return global_init; | ||
| 271 | |||
| 272 | /* deinit and free resources. */ | ||
| 273 | if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_CRED_ALLOC) | ||
| 274 | { | ||
| 275 | message ("gnutls: deallocating certificates"); | ||
| 276 | |||
| 277 | if (EQ (type, Qgnutls_x509pki)) | ||
| 278 | { | ||
| 279 | message ("gnutls: deallocating x509 certificates"); | ||
| 280 | |||
| 281 | x509_cred = XPROCESS (proc)->x509_cred; | ||
| 282 | gnutls_certificate_free_credentials (x509_cred); | ||
| 283 | } | ||
| 284 | else if (EQ (type, Qgnutls_anon)) | ||
| 285 | { | ||
| 286 | message ("gnutls: deallocating anon certificates"); | ||
| 287 | |||
| 288 | anon_cred = XPROCESS (proc)->anon_cred; | ||
| 289 | gnutls_anon_free_client_credentials (anon_cred); | ||
| 290 | } | ||
| 291 | else | ||
| 292 | { | ||
| 293 | error ("unknown credential type"); | ||
| 294 | ret = GNUTLS_EMACS_ERROR_INVALID_TYPE; | ||
| 295 | } | ||
| 296 | |||
| 297 | if (GNUTLS_INITSTAGE (proc) >= GNUTLS_STAGE_INIT) | ||
| 298 | { | ||
| 299 | message ("gnutls: deinitializing"); | ||
| 300 | |||
| 301 | Fgnutls_deinit (proc); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | |||
| 305 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_EMPTY; | ||
| 306 | |||
| 307 | message ("gnutls: allocating credentials"); | ||
| 308 | |||
| 309 | if (EQ (type, Qgnutls_x509pki)) | ||
| 310 | { | ||
| 311 | message ("gnutls: allocating x509 credentials"); | ||
| 312 | |||
| 313 | x509_cred = XPROCESS (proc)->x509_cred; | ||
| 314 | if (gnutls_certificate_allocate_credentials (&x509_cred) < 0) | ||
| 315 | memory_full (); | ||
| 316 | } | ||
| 317 | else if (EQ (type, Qgnutls_anon)) | ||
| 318 | { | ||
| 319 | message ("gnutls: allocating anon credentials"); | ||
| 320 | |||
| 321 | anon_cred = XPROCESS (proc)->anon_cred; | ||
| 322 | if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0) | ||
| 323 | memory_full (); | ||
| 324 | } | ||
| 325 | else | ||
| 326 | { | ||
| 327 | error ("unknown credential type"); | ||
| 328 | ret = GNUTLS_EMACS_ERROR_INVALID_TYPE; | ||
| 329 | } | ||
| 330 | |||
| 331 | if (ret < GNUTLS_E_SUCCESS) | ||
| 332 | return gnutls_make_error (ret); | ||
| 333 | |||
| 334 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_ALLOC; | ||
| 335 | |||
| 336 | message ("gnutls: setting the trustfile"); | ||
| 337 | |||
| 338 | if (EQ (type, Qgnutls_x509pki)) | ||
| 339 | { | ||
| 340 | if (STRINGP (trustfile)) | ||
| 341 | { | ||
| 342 | ret = gnutls_certificate_set_x509_trust_file | ||
| 343 | (x509_cred, | ||
| 344 | XSTRING (trustfile)->data, | ||
| 345 | file_format); | ||
| 346 | |||
| 347 | if (ret < GNUTLS_E_SUCCESS) | ||
| 348 | return gnutls_make_error (ret); | ||
| 349 | |||
| 350 | message ("gnutls: processed %d CA certificates", ret); | ||
| 351 | } | ||
| 352 | |||
| 353 | message ("gnutls: setting the keyfile"); | ||
| 354 | |||
| 355 | if (STRINGP (keyfile)) | ||
| 356 | { | ||
| 357 | ret = gnutls_certificate_set_x509_crl_file | ||
| 358 | (x509_cred, | ||
| 359 | XSTRING (keyfile)->data, | ||
| 360 | file_format); | ||
| 361 | |||
| 362 | if (ret < GNUTLS_E_SUCCESS) | ||
| 363 | return gnutls_make_error (ret); | ||
| 364 | |||
| 365 | message ("gnutls: processed %d CRL(s)", ret); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | |||
| 369 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_FILES; | ||
| 370 | |||
| 371 | message ("gnutls: gnutls_init"); | ||
| 372 | |||
| 373 | ret = gnutls_init (&state, GNUTLS_CLIENT); | ||
| 374 | |||
| 375 | if (ret < GNUTLS_E_SUCCESS) | ||
| 376 | return gnutls_make_error (ret); | ||
| 377 | |||
| 378 | XPROCESS (proc)->gnutls_state = state; | ||
| 379 | |||
| 380 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_INIT; | ||
| 381 | |||
| 382 | message ("gnutls: setting the priority string"); | ||
| 383 | |||
| 384 | ret = gnutls_priority_set_direct(state, | ||
| 385 | (char*) SDATA (priority_string), | ||
| 386 | NULL); | ||
| 387 | |||
| 388 | if (ret < GNUTLS_E_SUCCESS) | ||
| 389 | return gnutls_make_error (ret); | ||
| 390 | |||
| 391 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_PRIORITY; | ||
| 392 | |||
| 393 | message ("gnutls: setting the credentials"); | ||
| 394 | |||
| 395 | if (EQ (type, Qgnutls_x509pki)) | ||
| 396 | { | ||
| 397 | message ("gnutls: setting the x509 credentials"); | ||
| 398 | |||
| 399 | ret = gnutls_cred_set (state, GNUTLS_CRD_CERTIFICATE, x509_cred); | ||
| 400 | } | ||
| 401 | else if (EQ (type, Qgnutls_anon)) | ||
| 402 | { | ||
| 403 | message ("gnutls: setting the anon credentials"); | ||
| 404 | |||
| 405 | ret = gnutls_cred_set (state, GNUTLS_CRD_ANON, anon_cred); | ||
| 406 | } | ||
| 407 | else | ||
| 408 | { | ||
| 409 | error ("unknown credential type"); | ||
| 410 | ret = GNUTLS_EMACS_ERROR_INVALID_TYPE; | ||
| 411 | } | ||
| 412 | |||
| 413 | if (ret < GNUTLS_E_SUCCESS) | ||
| 414 | return gnutls_make_error (ret); | ||
| 415 | |||
| 416 | XPROCESS (proc)->anon_cred = anon_cred; | ||
| 417 | XPROCESS (proc)->x509_cred = x509_cred; | ||
| 418 | XPROCESS (proc)->gnutls_cred_type = type; | ||
| 419 | |||
| 420 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_CRED_SET; | ||
| 421 | |||
| 422 | return gnutls_make_error (GNUTLS_E_SUCCESS); | ||
| 423 | } | ||
| 424 | |||
| 425 | DEFUN ("gnutls-bye", Fgnutls_bye, | ||
| 426 | Sgnutls_bye, 2, 2, 0, | ||
| 427 | doc: /* Terminate current GNU TLS connection for PROCESS. | ||
| 428 | The connection should have been initiated using `gnutls-handshake'. | ||
| 429 | |||
| 430 | If CONT is not nil the TLS connection gets terminated and further | ||
| 431 | receives and sends will be disallowed. If the return value is zero you | ||
| 432 | may continue using the connection. If CONT is nil, GnuTLS actually | ||
| 433 | sends an alert containing a close request and waits for the peer to | ||
| 434 | reply with the same message. In order to reuse the connection you | ||
| 435 | should wait for an EOF from the peer. | ||
| 436 | |||
| 437 | This function may also return `gnutls-e-again', or | ||
| 438 | `gnutls-e-interrupted'. */) | ||
| 439 | (Lisp_Object proc, Lisp_Object cont) | ||
| 440 | { | ||
| 441 | gnutls_session_t state; | ||
| 442 | int ret; | ||
| 443 | |||
| 444 | CHECK_PROCESS (proc); | ||
| 445 | |||
| 446 | state = XPROCESS (proc)->gnutls_state; | ||
| 447 | |||
| 448 | ret = gnutls_bye (state, | ||
| 449 | NILP (cont) ? GNUTLS_SHUT_RDWR : GNUTLS_SHUT_WR); | ||
| 450 | |||
| 451 | return gnutls_make_error (ret); | ||
| 452 | } | ||
| 453 | |||
| 454 | DEFUN ("gnutls-handshake", Fgnutls_handshake, | ||
| 455 | Sgnutls_handshake, 1, 1, 0, | ||
| 456 | doc: /* Perform GNU TLS handshake for PROCESS. | ||
| 457 | The identity of the peer is checked automatically. This function will | ||
| 458 | fail if any problem is encountered, and will return a negative error | ||
| 459 | code. In case of a client, if it has been asked to resume a session, | ||
| 460 | but the server didn't, then a full handshake will be performed. | ||
| 461 | |||
| 462 | If the error `gnutls-e-not-ready-for-handshake' is returned, you | ||
| 463 | didn't call `gnutls-boot' first. | ||
| 464 | |||
| 465 | This function may also return the non-fatal errors `gnutls-e-again', | ||
| 466 | or `gnutls-e-interrupted'. In that case you may resume the handshake | ||
| 467 | (by calling this function again). */) | ||
| 468 | (Lisp_Object proc) | ||
| 469 | { | ||
| 470 | gnutls_session_t state; | ||
| 471 | int ret; | ||
| 472 | |||
| 473 | CHECK_PROCESS (proc); | ||
| 474 | state = XPROCESS (proc)->gnutls_state; | ||
| 475 | |||
| 476 | if (GNUTLS_INITSTAGE (proc) < GNUTLS_STAGE_HANDSHAKE_CANDO) | ||
| 477 | return Qgnutls_e_not_ready_for_handshake; | ||
| 478 | |||
| 479 | |||
| 480 | if (GNUTLS_INITSTAGE (proc) < GNUTLS_STAGE_TRANSPORT_POINTERS_SET) | ||
| 481 | { | ||
| 482 | /* for a network process in Emacs infd and outfd are the same | ||
| 483 | but this shows our intent more clearly. */ | ||
| 484 | message ("gnutls: handshake: setting the transport pointers to %d/%d", | ||
| 485 | XPROCESS (proc)->infd, XPROCESS (proc)->outfd); | ||
| 486 | |||
| 487 | gnutls_transport_set_ptr2 (state, XPROCESS (proc)->infd, | ||
| 488 | XPROCESS (proc)->outfd); | ||
| 489 | |||
| 490 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; | ||
| 491 | } | ||
| 492 | |||
| 493 | message ("gnutls: handshake: handshaking"); | ||
| 494 | ret = gnutls_handshake (state); | ||
| 495 | |||
| 496 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_HANDSHAKE_TRIED; | ||
| 497 | |||
| 498 | if (GNUTLS_E_SUCCESS == ret) | ||
| 499 | { | ||
| 500 | /* here we're finally done. */ | ||
| 501 | GNUTLS_INITSTAGE (proc) = GNUTLS_STAGE_READY; | ||
| 502 | } | ||
| 503 | |||
| 504 | return gnutls_make_error (ret); | ||
| 505 | } | ||
| 506 | |||
| 507 | void | ||
| 508 | syms_of_gnutls (void) | ||
| 509 | { | ||
| 510 | global_initialized = 0; | ||
| 511 | |||
| 512 | Qgnutls_code = intern_c_string ("gnutls-code"); | ||
| 513 | staticpro (&Qgnutls_code); | ||
| 514 | |||
| 515 | Qgnutls_anon = intern_c_string ("gnutls-anon"); | ||
| 516 | staticpro (&Qgnutls_anon); | ||
| 517 | |||
| 518 | Qgnutls_x509pki = intern_c_string ("gnutls-x509pki"); | ||
| 519 | staticpro (&Qgnutls_x509pki); | ||
| 520 | |||
| 521 | Qgnutls_e_interrupted = intern_c_string ("gnutls-e-interrupted"); | ||
| 522 | staticpro (&Qgnutls_e_interrupted); | ||
| 523 | Fput (Qgnutls_e_interrupted, Qgnutls_code, | ||
| 524 | make_number (GNUTLS_E_INTERRUPTED)); | ||
| 525 | |||
| 526 | Qgnutls_e_again = intern_c_string ("gnutls-e-again"); | ||
| 527 | staticpro (&Qgnutls_e_again); | ||
| 528 | Fput (Qgnutls_e_again, Qgnutls_code, | ||
| 529 | make_number (GNUTLS_E_AGAIN)); | ||
| 530 | |||
| 531 | Qgnutls_e_invalid_session = intern_c_string ("gnutls-e-invalid-session"); | ||
| 532 | staticpro (&Qgnutls_e_invalid_session); | ||
| 533 | Fput (Qgnutls_e_invalid_session, Qgnutls_code, | ||
| 534 | make_number (GNUTLS_E_INVALID_SESSION)); | ||
| 535 | |||
| 536 | Qgnutls_e_not_ready_for_handshake = | ||
| 537 | intern_c_string ("gnutls-e-not-ready-for-handshake"); | ||
| 538 | staticpro (&Qgnutls_e_not_ready_for_handshake); | ||
| 539 | Fput (Qgnutls_e_not_ready_for_handshake, Qgnutls_code, | ||
| 540 | make_number (GNUTLS_E_APPLICATION_ERROR_MIN)); | ||
| 541 | |||
| 542 | defsubr (&Sgnutls_get_initstage); | ||
| 543 | defsubr (&Sgnutls_errorp); | ||
| 544 | defsubr (&Sgnutls_error_fatalp); | ||
| 545 | defsubr (&Sgnutls_error_string); | ||
| 546 | defsubr (&Sgnutls_boot); | ||
| 547 | defsubr (&Sgnutls_deinit); | ||
| 548 | defsubr (&Sgnutls_handshake); | ||
| 549 | defsubr (&Sgnutls_bye); | ||
| 550 | } | ||
| 551 | #endif | ||
diff --git a/src/gnutls.h b/src/gnutls.h new file mode 100644 index 00000000000..3a9030ba454 --- /dev/null +++ b/src/gnutls.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /* GnuTLS glue for GNU Emacs. | ||
| 2 | Copyright (C) 2010 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation, either version 3 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 18 | |||
| 19 | #ifndef EMACS_GNUTLS_DEFINED | ||
| 20 | #define EMACS_GNUTLS_DEFINED | ||
| 21 | |||
| 22 | #ifdef HAVE_GNUTLS | ||
| 23 | #include <gnutls/gnutls.h> | ||
| 24 | |||
| 25 | typedef enum | ||
| 26 | { | ||
| 27 | /* Initialization stages. */ | ||
| 28 | GNUTLS_STAGE_EMPTY = 0, | ||
| 29 | GNUTLS_STAGE_CRED_ALLOC, | ||
| 30 | GNUTLS_STAGE_FILES, | ||
| 31 | GNUTLS_STAGE_INIT, | ||
| 32 | GNUTLS_STAGE_PRIORITY, | ||
| 33 | GNUTLS_STAGE_CRED_SET, | ||
| 34 | |||
| 35 | /* Handshake stages. */ | ||
| 36 | GNUTLS_STAGE_HANDSHAKE_CANDO = GNUTLS_STAGE_CRED_SET, | ||
| 37 | GNUTLS_STAGE_TRANSPORT_POINTERS_SET, | ||
| 38 | GNUTLS_STAGE_HANDSHAKE_TRIED, | ||
| 39 | |||
| 40 | GNUTLS_STAGE_READY, | ||
| 41 | } gnutls_initstage_t; | ||
| 42 | |||
| 43 | #define GNUTLS_EMACS_ERROR_INVALID_TYPE GNUTLS_E_APPLICATION_ERROR_MIN | ||
| 44 | |||
| 45 | #define GNUTLS_INITSTAGE(proc) (XPROCESS (proc)->gnutls_initstage) | ||
| 46 | |||
| 47 | #define GNUTLS_PROCESS_USABLE(proc) (GNUTLS_INITSTAGE(proc) >= GNUTLS_STAGE_READY) | ||
| 48 | |||
| 49 | int | ||
| 50 | emacs_gnutls_write (int fildes, gnutls_session_t state, char *buf, | ||
| 51 | unsigned int nbyte); | ||
| 52 | int | ||
| 53 | emacs_gnutls_read (int fildes, gnutls_session_t state, char *buf, | ||
| 54 | unsigned int nbyte); | ||
| 55 | |||
| 56 | extern void syms_of_gnutls (void); | ||
| 57 | |||
| 58 | #endif | ||
| 59 | |||
| 60 | #endif | ||
diff --git a/src/process.c b/src/process.c index 048e2858e9f..ef086914704 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -105,6 +105,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 105 | #include "sysselect.h" | 105 | #include "sysselect.h" |
| 106 | #include "syssignal.h" | 106 | #include "syssignal.h" |
| 107 | #include "syswait.h" | 107 | #include "syswait.h" |
| 108 | #ifdef HAVE_GNUTLS | ||
| 109 | #include "gnutls.h" | ||
| 110 | #endif | ||
| 108 | 111 | ||
| 109 | #if defined (USE_GTK) || defined (HAVE_GCONF) | 112 | #if defined (USE_GTK) || defined (HAVE_GCONF) |
| 110 | #include "xgselect.h" | 113 | #include "xgselect.h" |
| @@ -583,6 +586,10 @@ make_process (Lisp_Object name) | |||
| 583 | p->read_output_skip = 0; | 586 | p->read_output_skip = 0; |
| 584 | #endif | 587 | #endif |
| 585 | 588 | ||
| 589 | #ifdef HAVE_GNUTLS | ||
| 590 | p->gnutls_initstage = GNUTLS_STAGE_EMPTY; | ||
| 591 | #endif | ||
| 592 | |||
| 586 | /* If name is already in use, modify it until it is unused. */ | 593 | /* If name is already in use, modify it until it is unused. */ |
| 587 | 594 | ||
| 588 | name1 = name; | 595 | name1 = name; |
| @@ -1526,6 +1533,12 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */) | |||
| 1526 | XPROCESS (proc)->filter = Qnil; | 1533 | XPROCESS (proc)->filter = Qnil; |
| 1527 | XPROCESS (proc)->command = Flist (nargs - 2, args + 2); | 1534 | XPROCESS (proc)->command = Flist (nargs - 2, args + 2); |
| 1528 | 1535 | ||
| 1536 | #ifdef HAVE_GNUTLS | ||
| 1537 | /* AKA GNUTLS_INITSTAGE(proc). */ | ||
| 1538 | XPROCESS (proc)->gnutls_initstage = GNUTLS_STAGE_EMPTY; | ||
| 1539 | XPROCESS (proc)->gnutls_cred_type = Qnil; | ||
| 1540 | #endif | ||
| 1541 | |||
| 1529 | #ifdef ADAPTIVE_READ_BUFFERING | 1542 | #ifdef ADAPTIVE_READ_BUFFERING |
| 1530 | XPROCESS (proc)->adaptive_read_buffering | 1543 | XPROCESS (proc)->adaptive_read_buffering |
| 1531 | = (NILP (Vprocess_adaptive_read_buffering) ? 0 | 1544 | = (NILP (Vprocess_adaptive_read_buffering) ? 0 |
| @@ -5099,7 +5112,13 @@ read_process_output (Lisp_Object proc, register int channel) | |||
| 5099 | #endif | 5112 | #endif |
| 5100 | if (proc_buffered_char[channel] < 0) | 5113 | if (proc_buffered_char[channel] < 0) |
| 5101 | { | 5114 | { |
| 5102 | nbytes = emacs_read (channel, chars + carryover, readmax); | 5115 | #ifdef HAVE_GNUTLS |
| 5116 | if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc)) | ||
| 5117 | nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state, | ||
| 5118 | chars + carryover, readmax); | ||
| 5119 | else | ||
| 5120 | #endif | ||
| 5121 | nbytes = emacs_read (channel, chars + carryover, readmax); | ||
| 5103 | #ifdef ADAPTIVE_READ_BUFFERING | 5122 | #ifdef ADAPTIVE_READ_BUFFERING |
| 5104 | if (nbytes > 0 && p->adaptive_read_buffering) | 5123 | if (nbytes > 0 && p->adaptive_read_buffering) |
| 5105 | { | 5124 | { |
| @@ -5132,7 +5151,13 @@ read_process_output (Lisp_Object proc, register int channel) | |||
| 5132 | { | 5151 | { |
| 5133 | chars[carryover] = proc_buffered_char[channel]; | 5152 | chars[carryover] = proc_buffered_char[channel]; |
| 5134 | proc_buffered_char[channel] = -1; | 5153 | proc_buffered_char[channel] = -1; |
| 5135 | nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1); | 5154 | #ifdef HAVE_GNUTLS |
| 5155 | if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc)) | ||
| 5156 | nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state, | ||
| 5157 | chars + carryover + 1, readmax - 1); | ||
| 5158 | else | ||
| 5159 | #endif | ||
| 5160 | nbytes = emacs_read (channel, chars + carryover + 1, readmax - 1); | ||
| 5136 | if (nbytes < 0) | 5161 | if (nbytes < 0) |
| 5137 | nbytes = 1; | 5162 | nbytes = 1; |
| 5138 | else | 5163 | else |
| @@ -5542,7 +5567,14 @@ send_process (volatile Lisp_Object proc, const unsigned char *volatile buf, | |||
| 5542 | else | 5567 | else |
| 5543 | #endif | 5568 | #endif |
| 5544 | { | 5569 | { |
| 5545 | rv = emacs_write (outfd, (char *) buf, this); | 5570 | #ifdef HAVE_GNUTLS |
| 5571 | if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc)) | ||
| 5572 | rv = emacs_gnutls_write (outfd, | ||
| 5573 | XPROCESS (proc)->gnutls_state, | ||
| 5574 | (char *) buf, this); | ||
| 5575 | else | ||
| 5576 | #endif | ||
| 5577 | rv = emacs_write (outfd, (char *) buf, this); | ||
| 5546 | #ifdef ADAPTIVE_READ_BUFFERING | 5578 | #ifdef ADAPTIVE_READ_BUFFERING |
| 5547 | if (p->read_output_delay > 0 | 5579 | if (p->read_output_delay > 0 |
| 5548 | && p->adaptive_read_buffering == 1) | 5580 | && p->adaptive_read_buffering == 1) |
diff --git a/src/process.h b/src/process.h index 35b01aba6a4..562d888f93f 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -24,6 +24,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 24 | #include <unistd.h> | 24 | #include <unistd.h> |
| 25 | #endif | 25 | #endif |
| 26 | 26 | ||
| 27 | #ifdef HAVE_GNUTLS | ||
| 28 | #include "gnutls.h" | ||
| 29 | #endif | ||
| 30 | |||
| 27 | /* This structure records information about a subprocess | 31 | /* This structure records information about a subprocess |
| 28 | or network connection. | 32 | or network connection. |
| 29 | 33 | ||
| @@ -76,6 +80,10 @@ struct Lisp_Process | |||
| 76 | /* Working buffer for encoding. */ | 80 | /* Working buffer for encoding. */ |
| 77 | Lisp_Object encoding_buf; | 81 | Lisp_Object encoding_buf; |
| 78 | 82 | ||
| 83 | #ifdef HAVE_GNUTLS | ||
| 84 | Lisp_Object gnutls_cred_type; | ||
| 85 | #endif | ||
| 86 | |||
| 79 | /* After this point, there are no Lisp_Objects any more. */ | 87 | /* After this point, there are no Lisp_Objects any more. */ |
| 80 | /* alloc.c assumes that `pid' is the first such non-Lisp slot. */ | 88 | /* alloc.c assumes that `pid' is the first such non-Lisp slot. */ |
| 81 | 89 | ||
| @@ -121,6 +129,13 @@ struct Lisp_Process | |||
| 121 | needs to be synced to `status'. */ | 129 | needs to be synced to `status'. */ |
| 122 | unsigned int raw_status_new : 1; | 130 | unsigned int raw_status_new : 1; |
| 123 | int raw_status; | 131 | int raw_status; |
| 132 | |||
| 133 | #ifdef HAVE_GNUTLS | ||
| 134 | gnutls_initstage_t gnutls_initstage; | ||
| 135 | gnutls_session_t gnutls_state; | ||
| 136 | gnutls_certificate_client_credentials x509_cred; | ||
| 137 | gnutls_anon_client_credentials_t anon_cred; | ||
| 138 | #endif | ||
| 124 | }; | 139 | }; |
| 125 | 140 | ||
| 126 | /* Every field in the preceding structure except for the first two | 141 | /* Every field in the preceding structure except for the first two |