MAN3 = tlspool_socket tlspool_starttls \
tlspool_ping tlspool_prng \
tlspool_pin_service tlspool_localid_service \
- tlspool_control_detach tlspool_control_reattach
+ tlspool_control_detach tlspool_control_reattach \
+ tlspool_configvar
MAN8 = tlspool tlstunnel
--- /dev/null
+.TH TLSPOOL_CONFIGVAR 3 "August 2016" "ARPA2.net" "Library Calls"
+.SH NAME
+tlspool_configvar \- Retrieve a TLS Pool configuration variable value
+.SH SYNOPSIS
+.B #include <tlspool/starttls.h>
+.sp
+.B char *tlspool_configvar (char *\fIcfgfile\fB, char *\fIvarname\fB);
+.SH DESCRIPTION
+.PP
+.BR tlspool_configvar ()
+fetches the value of a configuration file variable as setup for the
+TLS Pool. The configuration file can be provided in the
+.IR cfgfile parameter
+or, if it is NULL, then first the environment variable
+.BR TLSPOOL_CFGFILE
+and, failing to find that, it tries the compile-time setting
+.BR TLSPOOL_DEFAULT_CONFIG_PATH .
+
+.SH "RETURN VALUE"
+The value returned is NULL when the requested variable was not
+found, but also when the configuration file did not load. The
+error output may hold further hints on the cause of problems.
+.SH AUTHOR
+.PP
+Written by Rick van Rein of OpenFortress.nl, for the ARPA2.net project.
+.SH "REPORTING BUGS"
+.PP
+For any discussion, including about bugs, please use the mailing list
+found on
+.IR http://lists.arpa2.org/mailman/listinfo/tls-pool .
+.PP
+Please read the software distribution's
+.IR README ", " INSTALL " and " TODO " files"
+for information about the
+.I tlspool
+implementation status.
+.SH COPYRIGHT
+.PP
+Copyright \(co 2016 Rick van Rein, ARPA2.net.
+.PP
+ARPA2 is funded from InternetWide.org, which in turns receives donations
+from various funding sources with an interest in a private and secure
+Internet that gives users control over their online presence. This particular
+project has been sponsored in part by NCSC.
+.SH "SEE ALSO"
+.IR tlspool "(8)"
+.PP
+The TLS Pool API is documented in the include file
+.IR <tlspool/commands.h> " and " <tlspool/starttls.h>
+for C, and the
+.I tlspool.py
+module for Python.
+.PP
+Online resources may be found on the project home page,
+.IR http://tlspool.arpa2.net .
argument is used as a path to the UNIX domain socket to use; during later
calls, the argument is ignored but the returned file descriptor is instead
the same one as before. A NULL value for the argument is replaced with
+the value of the
+.BR socket_name configuration
+file as returned by
+.IR tlspool_configvar()
+or, if that fails, the statically compiled value in
.BR TLSPOOL_DEFAULT_SOCKET_PATH .
.PP
All of the
Internet that gives users control over their online presence. This particular
project has been sponsored in part by NCSC.
.SH "SEE ALSO"
-.IR tlspool "(8)"
+.IR tlspool "(8)."
+.IR tlspool_configvar "(3)"
.PP
The configuration file option
.I socket_name
#ifdef WINDOWS_PORT
+#define TLSPOOL_DEFAULT_CONFIG_PATH "/etc/tlspool.conf.windows"
#define TLSPOOL_DEFAULT_SOCKET_PATH "\\\\.\\pipe\\tlspool"
#define TLSPOOL_DEFAULT_PIDFILE_PATH "/var/run/tlspool.pid"
#else
+#define TLSPOOL_DEFAULT_CONFIG_PATH "/etc/tlspool.conf"
#define TLSPOOL_DEFAULT_SOCKET_PATH "/var/run/tlspool.sock"
#define TLSPOOL_DEFAULT_PIDFILE_PATH "/var/run/tlspool.pid"
#endif /* WINDOWS_PORT */
uint16_t prng_len, uint8_t *prng_buf,
uint8_t *ctlkey);
+
+/* Fetch a configuration variable value from the configuration file. This is not
+ * an efficient procedure, at best suited for startup of tools or daemons; it
+ * will iterate over the config file until it reads the desired value. The value
+ * returned is allocated and should be freed by the caller using free().
+ *
+ * When cfgfile is NULL, the environment variable TLSPOOL_CONFIGFILE is
+ * tried first, followed by the default setting from the macro
+ * TLSPOOL_DEFAULT_SOCKET_PATH as defined in <tlspool/starttls.h>.
+ *
+ * The value returned is NULL when the variable is not found, including when this
+ * is due to errors such as not being able to open the file.
+ */
+char *tlspool_configvar (char *cfgfile, char *varname);
+
+
#ifdef __cplusplus
}
#endif
}
+_gostring_ _wrap_tlspool_configvar_tlspool_03ad2d7a43d805c7(_gostring_ _swig_go_0, _gostring_ _swig_go_1) {
+ char *arg1 = (char *) 0 ;
+ char *arg2 = (char *) 0 ;
+ char *result = 0 ;
+ _gostring_ _swig_go_result;
+
+
+ arg1 = (char *)malloc(_swig_go_0.n + 1);
+ memcpy(arg1, _swig_go_0.p, _swig_go_0.n);
+ arg1[_swig_go_0.n] = '\0';
+
+
+ arg2 = (char *)malloc(_swig_go_1.n + 1);
+ memcpy(arg2, _swig_go_1.p, _swig_go_1.n);
+ arg2[_swig_go_1.n] = '\0';
+
+
+ result = (char *)tlspool_configvar(arg1,arg2);
+ _swig_go_result = Swig_AllocateString((char*)result, result ? strlen((char*)result) : 0);
+ free(arg1);
+ free(arg2);
+ return _swig_go_result;
+}
+
+
intgo _wrap_PIOC_LOCAL_tlspool_03ad2d7a43d805c7() {
int result;
intgo _swig_go_result;
typedef _gostring_ swig_type_14;
typedef _gostring_ swig_type_15;
typedef _gostring_ swig_type_16;
+typedef _gostring_ swig_type_17;
+typedef _gostring_ swig_type_18;
+typedef _gostring_ swig_type_19;
extern void _wrap_Swig_free_tlspool_03ad2d7a43d805c7(uintptr_t arg1);
extern uintptr_t _wrap_Swig_malloc_tlspool_03ad2d7a43d805c7(swig_intgo arg1);
extern void _wrap_error_data_tlserrno_set_tlspool_03ad2d7a43d805c7(uintptr_t arg1, swig_intgo arg2);
extern swig_intgo _wrap_Internal_control_detach_tlspool_03ad2d7a43d805c7(swig_voidp arg1);
extern swig_intgo _wrap_Internal_control_reattach_tlspool_03ad2d7a43d805c7(swig_voidp arg1);
extern swig_intgo _wrap_Internal_prng_tlspool_03ad2d7a43d805c7(swig_type_15 arg1, swig_type_16 arg2, short arg3, swig_voidp arg4, swig_voidp arg5);
+extern swig_type_17 _wrap_tlspool_configvar_tlspool_03ad2d7a43d805c7(swig_type_18 arg1, swig_type_19 arg2);
extern swig_intgo _wrap_PIOC_LOCAL_tlspool_03ad2d7a43d805c7(void);
#undef intgo
*/
return swig_r
}
+func Tlspool_configvar(arg1 string, arg2 string) (_swig_ret string) {
+ var swig_r string
+ _swig_i_0 := arg1
+ _swig_i_1 := arg2
+ swig_r_p := C._wrap_tlspool_configvar_tlspool_03ad2d7a43d805c7(*(*C.swig_type_18)(unsafe.Pointer(&_swig_i_0)), *(*C.swig_type_19)(unsafe.Pointer(&_swig_i_1)))
+ swig_r = *(*string)(unsafe.Pointer(&swig_r_p))
+ if Swig_escape_always_false {
+ Swig_escape_val = arg1
+ }
+ if Swig_escape_always_false {
+ Swig_escape_val = arg2
+ }
+ var swig_r_1 string
+ swig_r_1 = swigCopyString(swig_r)
+ return swig_r_1
+}
+
unsigned long pid;
if (opt_pidfile == NULL) {
+ opt_pidfile = tlspool_configvar (NULL, "daemon_pidfile");
+ }
+ if (opt_pidfile == NULL) {
opt_pidfile = TLSPOOL_DEFAULT_PIDFILE_PATH;
}
+ assert (opt_pidfile != NULL);
fd = open (opt_pidfile, O_RDONLY);
if (fd != -1) {
len = read (fd, str_pid, sizeof (str_pid) -1);
unsigned int seed;
pid_t me;
if (!path) {
+ path = tlspool_configvar (NULL, "socket_name");
+ }
+ if (!path) {
path = TLSPOOL_DEFAULT_SOCKET_PATH;
}
+ assert (path != NULL);
+ fprintf (stderr, "DEBUG: Opening TLS Pool on socket path %s\n", path);
#ifndef WINDOWS_PORT
if (strlen(path) + 1 > sizeof(((struct sockaddr_un *) NULL)->sun_path)) {
syslog(LOG_ERR, "TLS Pool path name too long for UNIX domain socket");
return -1;
}
}
+
+
+/* Fetch a configuration variable value from the configuration file. This is not
+ * an efficient procedure, at best suited for startup of tools or daemons; it
+ * will iterate over the config file until it reads the desired value. The value
+ * returned is allocated and should be freed by the caller using free().
+ *
+ * When cfgfile is NULL, the environment variable TLSPOOL_CONFIGFILE is
+ * tried first, followed by the default setting from the macro
+ * TLSPOOL_DEFAULT_CONFIG_PATH as defined in <tlspool/starttls.h>.
+ *
+ * The value returned is NULL when the variable is not found, including when this
+ * is due to errors such as not being able to open the file.
+ */
+char *tlspool_configvar (char *cfgfile, char *varname) {
+ FILE *cf;
+ char line [514];
+ int linelen;
+ int eof = 0;
+ char *here;
+ struct cfgopt *curopt;
+ int found;
+ char *retval = NULL;
+
+ if (cfgfile == NULL) {
+ cfgfile = getenv ("TLSPOOL_CFGFILE");
+ }
+ if (cfgfile == NULL) {
+ cfgfile = TLSPOOL_DEFAULT_CONFIG_PATH;
+ }
+
+ assert (cfgfile != NULL);
+ assert (varname != NULL);
+
+ cf = fopen (cfgfile, "r");
+ if (cf == NULL) {
+ perror ("Failed to open configuration file");
+ goto cleanup;
+ }
+
+ while (!eof) {
+ if (!fgets (line, sizeof (line)-1, cf)) {
+ if (feof (cf)) {
+ eof = 1;
+ continue;
+ } else {
+ perror ("Error while reading configuration file");
+ exit (1);
+ }
+ }
+ linelen = strlen (line);
+ if (linelen == 0) {
+ eof = 1;
+ continue;
+ }
+ if (line [linelen-1] == (char) EOF) {
+ linelen--;
+ eof = 1;
+ }
+ if (line [linelen-1] != '\n') {
+ fprintf (stderr, "Configuration line too long\n");
+ goto cleanup;
+ }
+ line [--linelen] = 0;
+ if (linelen == 0) {
+ continue;
+ }
+ if (line [0] == '#') {
+ continue;
+ }
+ here = line;
+ while ((*here) && isspace (*here)) {
+ here++;
+ }
+ if (!*here) {
+ continue;
+ }
+ if (here != line) {
+ fprintf (stderr, "Configuration line starts with whitespace:\n%s\n", line);
+ goto cleanup;
+ }
+ while ((*here) && (*here != ' ')) {
+ here++;
+ }
+ if (!*here) {
+ fprintf (stderr, "Configuration line misses space after keyword:\n%s\n", line);
+ goto cleanup;
+ }
+ *here++ = '\0';
+ if (strcmp (varname, line) == 0) {
+ // Success! We set the return value and end the loop
+ retval = here;
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ if (cf != NULL) {
+ fclose (cf);
+ cf = NULL;
+ }
+ return retval;
+}
+
These files map the TLS Pool library to Python. Use import tlspool
and describe connections with the class tlspool.Connection.
+setup.py
+ Uses the Python dist-utils to install the package. Some day we should
+ also add PIP support (but not sure how, by we lay an egg already).
+
webdemo.py
A simple demonstration downloading a web page using the TLS Pool port
to Python. Assumes IPv6 connectivity.
}
%typemap(out) ctlkey_t {
- if ($result == NULL) {
- $1 = Py_None;
+ if ($1 == NULL) {
+ $result = Py_None;
} else {
- $1 = PyString_FromStringAndSize ($result, TLSPOOL_CTLKEYLEN);
+ $result = PyString_FromStringAndSize ($1, TLSPOOL_CTLKEYLEN);
}
}
// helper function to raise OSError with the parameter set to C-reachable errno
+%nothread raise_errno;
+
%inline %{
PyObject *raise_errno (void) {
def make_tlsdata (localid='', remoteid='',
flags=0, local_flags=0,
ipproto=socket.IPPROTO_TCP, streamid=0, service='',
- timeout=0, ctlkey=None):
+ timeout=0, ctlkey='TODOTODOTODOTODO'):
"""Make a new tlsdata structure, based the fields that may be supplied
as flags, or otherwise as defaults. Note that the field "local" is
renamed to "local_flags" for reasons of clarity. This helper function
The procedure has been described in RFC 5705.
#TODO# Find a way to return the random bytes, and use the length
"""
+ assert (length > 0)
+ assert (1 <= len (label) <= 254)
+ assert (1 <= len (ctxvalue or 'X') <= 254)
buf = prng_data ()
- rv = _prng (label, ctxvalue, length, buf, self.tlsdata.ctlkey)
+ # buf.in1_len = len (label)
+ # buf.in2_len = len (ctxvalue) if ctxvalue is not None else 255
+ # buf.prng_len = length
+ rv = _prng (label, ctxvalue, length, buf.buffer, self.tlsdata.ctlkey)
if rv < 0:
_tlspool.raise_errno ()
else:
- return buf
+ return buf.buffer [:length]
def control_detach (self):
"""Detach control of this connection. Although the connection
else:
self.request = sox2
self.handle_secure ()
+ sox2.close ()
def startssh (self):
raise NotImplementedError ("Python wrapper does not implement STARTSSH")
does nothing but invoke starttls(), which in turn invokes
handle_secure() after the TLS handshake has succeeded.
"""
- print 'STARTTLS.BEGIN'
self.starttls ()
- print 'STARTTLS.END'
def handle_secure (self):
"""This method may be overridden to handle the secure part of the
-
-PyObject *raise_errno (void) {
- return PyErr_SetFromErrno (PyExc_OSError);
-}
-
-
-
SWIGINTERNINLINE PyObject *
SWIG_FromCharPtr(const char *cptr)
{
return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
}
+
+
+PyObject *raise_errno (void) {
+ return PyErr_SetFromErrno (PyExc_OSError);
+}
+
+
#ifdef __cplusplus
extern "C" {
#endif
SWIG_PYTHON_THREAD_END_ALLOW;
}
{
- if (resultobj == NULL) {
- result = Py_None;
+ if (result == NULL) {
+ resultobj = Py_None;
} else {
- result = PyString_FromStringAndSize (resultobj, TLSPOOL_CTLKEYLEN);
+ resultobj = PyString_FromStringAndSize (result, TLSPOOL_CTLKEYLEN);
}
}
return resultobj;
SWIG_PYTHON_THREAD_END_ALLOW;
}
{
- if (resultobj == NULL) {
- result = Py_None;
+ if (result == NULL) {
+ resultobj = Py_None;
} else {
- result = PyString_FromStringAndSize (resultobj, TLSPOOL_CTLKEYLEN);
+ resultobj = PyString_FromStringAndSize (result, TLSPOOL_CTLKEYLEN);
}
}
return resultobj;
}
-SWIGINTERN PyObject *_wrap_raise_errno(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_tlspool_configvar(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
- PyObject *result = 0 ;
+ char *arg1 = (char *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ char *result = 0 ;
- if (!PyArg_ParseTuple(args,(char *)":raise_errno")) SWIG_fail;
+ if (!PyArg_ParseTuple(args,(char *)"OO:tlspool_configvar",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "tlspool_configvar" "', argument " "1"" of type '" "char *""'");
+ }
+ arg1 = (char *)(buf1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "tlspool_configvar" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
{
SWIG_PYTHON_THREAD_BEGIN_ALLOW;
- result = (PyObject *)raise_errno();
+ result = (char *)tlspool_configvar(arg1,arg2);
SWIG_PYTHON_THREAD_END_ALLOW;
}
+ resultobj = SWIG_FromCharPtr((const char *)result);
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_raise_errno(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ PyObject *result = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)":raise_errno")) SWIG_fail;
+ result = (PyObject *)raise_errno();
resultobj = result;
return resultobj;
fail:
{ (char *)"_control_detach", _wrap__control_detach, METH_VARARGS, NULL},
{ (char *)"_control_reattach", _wrap__control_reattach, METH_VARARGS, NULL},
{ (char *)"_prng", _wrap__prng, METH_VARARGS, NULL},
+ { (char *)"tlspool_configvar", _wrap_tlspool_configvar, METH_VARARGS, NULL},
{ (char *)"raise_errno", _wrap_raise_errno, METH_VARARGS, NULL},
{ NULL, NULL, 0, NULL }
};
return _tlspool._prng(label, opt_ctxvalue, prng_len, prng_buf, ctlkey)
_prng = _tlspool._prng
+def tlspool_configvar(cfgfile, varname):
+ return _tlspool.tlspool_configvar(cfgfile, varname)
+tlspool_configvar = _tlspool.tlspool_configvar
+
def raise_errno():
return _tlspool.raise_errno()
raise_errno = _tlspool.raise_errno
def make_tlsdata (localid='', remoteid='',
flags=0, local_flags=0,
ipproto=socket.IPPROTO_TCP, streamid=0, service='',
- timeout=0, ctlkey=None):
+ timeout=0, ctlkey='TODOTODOTODOTODO'):
"""Make a new tlsdata structure, based the fields that may be supplied
as flags, or otherwise as defaults. Note that the field "local" is
renamed to "local_flags" for reasons of clarity. This helper function
The procedure has been described in RFC 5705.
#TODO# Find a way to return the random bytes, and use the length
"""
+ assert (length > 0)
+ assert (1 <= len (label) <= 254)
+ assert (1 <= len (ctxvalue or 'X') <= 254)
buf = prng_data ()
- rv = _prng (label, ctxvalue, length, buf, self.tlsdata.ctlkey)
+# buf.in1_len = len (label)
+# buf.in2_len = len (ctxvalue) if ctxvalue is not None else 255
+# buf.prng_len = length
+ rv = _prng (label, ctxvalue, length, buf.buffer, self.tlsdata.ctlkey)
if rv < 0:
_tlspool.raise_errno ()
else:
- return buf
+ return buf.buffer [:length]
def control_detach (self):
"""Detach control of this connection. Although the connection
else:
self.request = sox2
self.handle_secure ()
+ sox2.close ()
def startssh (self):
raise NotImplementedError ("Python wrapper does not implement STARTSSH")
does nothing but invoke starttls(), which in turn invokes
handle_secure() after the TLS handshake has succeeded.
"""
- print 'STARTTLS.BEGIN'
self.starttls ()
- print 'STARTTLS.END'
def handle_secure (self):
"""This method may be overridden to handle the secure part of the
uint16_t prng_len, uint8_t *prng_buf,
ctlkey_t ctlkey);
+char *tlspool_configvar (char *cfgfile, char *varname);
// libtlspool_pinentry.c