[pve-devel] r5407 - vncterm/pve2/vncpatches
svn-commits at proxmox.com
svn-commits at proxmox.com
Fri Jan 21 08:31:10 CET 2011
Author: dietmar
Date: 2011-01-21 08:31:10 +0100 (Fri, 21 Jan 2011)
New Revision: 5407
Modified:
vncterm/pve2/vncpatches/patch2.diff
Log:
Modified: vncterm/pve2/vncpatches/patch2.diff
===================================================================
--- vncterm/pve2/vncpatches/patch2.diff 2011-01-20 16:05:50 UTC (rev 5406)
+++ vncterm/pve2/vncpatches/patch2.diff 2011-01-21 07:31:10 UTC (rev 5407)
@@ -32,14 +32,75 @@
Index: vnc/newterm/vncterm.c
===================================================================
--- vnc.orig/newterm/vncterm.c 2011-01-20 13:41:18.000000000 +0100
-+++ vnc/newterm/vncterm.c 2011-01-20 17:05:31.000000000 +0100
-@@ -37,6 +37,94 @@
++++ vnc/newterm/vncterm.c 2011-01-21 08:29:20.000000000 +0100
+@@ -37,6 +37,170 @@
#include "vncterm.h"
#include "glyphs.h"
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
++char *auth_path = "/";
++
++/* launch expernal script to verify credential */
++int
++pve_auth_verify(const char *username, const char *passwd)
++{
++ sigset_t oldmask, mask;
++ int pid, status;
++ char *args[4];
++ char **parg;
++ char *env[2];
++ char **penv;
++
++ char pwenv[1024];
++
++ sprintf(pwenv, "PVE_PW_TICKET=%s", passwd);
++
++ const char *script ="/usr/bin/pve-authhelper";
++
++ sigemptyset(&mask);
++ sigaddset(&mask, SIGCHLD);
++ sigprocmask(SIG_BLOCK, &mask, &oldmask);
++
++ /* try to launch pve authentification helper */
++ pid = fork();
++ if (pid == 0) {
++ int open_max = sysconf(_SC_OPEN_MAX), i;
++
++ for (i = 0; i < open_max; i++) {
++ if (i != STDIN_FILENO &&
++ i != STDOUT_FILENO &&
++ i != STDERR_FILENO) {
++ close(i);
++ }
++ }
++ parg = args;
++ *parg++ = (char *)script;
++ *parg++ = (char *)auth_path;
++ *parg++ = (char *)username;
++ *parg = NULL;
++ penv = env;
++ *penv++ = (char *)pwenv;
++ *penv = NULL;
++ execve(script, args, env);
++ _exit(1);
++ } else if (pid > 0) {
++ while (waitpid(pid, &status, 0) != pid) {
++ /* loop */
++ }
++ sigprocmask(SIG_SETMASK, &oldmask, NULL);
++
++ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
++ return 0;
++ }
++ }
++
++ rfbLog("could not launch auth script %s\n", script);
++
++ return -1;
++}
++
+#ifdef DEBUG
+static void vnc_debug_gnutls_log(int level, const char* str) {
+ fprintf(stderr, "%d %s", level, str);
@@ -64,7 +125,6 @@
+
+retry:
+ n = send(cl->sock, data, len, 0);
-+ //fixme: is that safe?
+ if (n < 0) {
+ if (errno == EINTR)
+ goto retry;
@@ -92,7 +152,7 @@
+ return n;
+}
+
-+ssize_t my_tls_read(rfbClientPtr cl, void *buf, size_t count)
++ssize_t vnc_tls_read(rfbClientPtr cl, void *buf, size_t count)
+{
+ rfbLog("my_tls_read\n");
+ tls_client_t *sd = (tls_client_t *)cl->clientData;
@@ -108,7 +168,23 @@
+
+ return ret;
+}
++ssize_t vnc_tls_write(rfbClientPtr cl, void *buf, size_t count)
++{
++ rfbLog("my_tls_write\n");
++ tls_client_t *sd = (tls_client_t *)cl->clientData;
+
++ int ret = gnutls_write(sd->session, buf, count);
++ if (ret < 0) {
++ if (ret == GNUTLS_E_AGAIN)
++ errno = EAGAIN;
++ else
++ errno = EIO;
++ ret = -1;
++ }
++
++ return ret;
++}
++
+static gnutls_anon_server_credentials
+tls_initialize_anon_cred(void)
+{
@@ -128,7 +204,7 @@
/* define this for debugging */
//#define DEBUG
-@@ -45,10 +133,183 @@
+@@ -45,10 +209,275 @@
#define rfbSecTypeVencrypt 19
#define rfbVencryptTlsPlain 259
@@ -146,6 +222,77 @@
+ (data[offset + 2] << 8) | data[offset + 3]);
+}
+
++static void
++vencrypt_subauth_plain(rfbClientPtr cl)
++{
++ const char *err = NULL;
++ char buf[4096];
++ int n;
++
++ if ((n = rfbReadExact(cl, buf, 8)) <= 0) {
++ err = n ? "read failed" : "client gone";
++ goto err;
++ }
++
++ uint32_t ulen = rfbDecodeU32(buf, 0);
++ uint32_t pwlen = rfbDecodeU32(buf, 4);
++
++ if (!ulen) {
++ err = "No User name.";
++ goto err;
++ }
++ if (ulen >= 255) {
++ err = "User name too long.";
++ goto err;
++ }
++ if (!pwlen) {
++ err = "Password too short";
++ goto err;
++ }
++ if (pwlen >= 511) {
++ err = "Password too long.";
++ goto err;
++ }
++
++ if ((n = rfbReadExact(cl, buf, ulen)) <= 0) {
++ err = n ? "read failed" : "client gone";
++ goto err;
++ }
++ buf[ulen] = 0;
++ char *username = buf;
++ char *passwd = buf + ulen + 1;
++ if ((n = rfbReadExact(cl, passwd, pwlen)) <= 0) {
++ err = n ? "read failed" : "client gone";
++ goto err;
++ }
++ passwd[pwlen] = 0;
++
++ rfbLog("VencryptPlain: username: %s pw: %s\n", username, passwd);
++
++ if (pve_auth_verify(username, passwd) == 0) {
++ rfbEncodeU32(buf, 0); /* Accept auth completion */
++ rfbWriteExact(cl, buf, 4);
++ cl->state = RFB_INITIALISATION;
++ return;
++ }
++
++ err = "Authentication failed";
++err:
++ rfbLog("VencryptPlain: %s\n", err ? err : "no reason specified");
++ if (err) {
++ rfbEncodeU32(buf, 1); /* Reject auth */
++ rfbWriteExact(cl, buf, 4);
++ if (cl->protocolMinorVersion >= 8) {
++ int elen = strlen(err);
++ rfbEncodeU32(buf, elen);
++ rfbWriteExact(cl, buf, 4);
++ rfbWriteExact(cl, err, elen);
++ }
++ }
++ rfbCloseClient(cl);
++ return;
++}
++
static void
rfbVncAuthVencrypt(rfbClientPtr cl)
{
@@ -163,7 +310,7 @@
+ rfbCloseClient(cl);
+ return;
+ }
-
++
+ printf("TEST2\n");
+ int n = rfbReadExact(cl, buf, 2);
+ if (n <= 0) {
@@ -197,7 +344,7 @@
+ rfbCloseClient(cl);
+ return;
+ }
-+
+
+ printf("TEST5\n");
+ n = rfbReadExact(cl, buf, 4);
+ if (n <= 0) {
@@ -230,47 +377,76 @@
+
+
+ tls_client_t *sd = calloc(1, sizeof(tls_client_t));
-+ cl->clientData = sd;
+
+ if (sd->session == NULL) {
+ if (gnutls_init(&sd->session, GNUTLS_SERVER) < 0) {
-+ fprintf(stderr, "gnutls_init FAILED");
-+ exit(-1); //fixme
++ rfbLog("gnutls_init failed\n");
++ rfbCloseClient(cl);
++ return;
++
+ }
+
-+ if (gnutls_set_default_priority(sd->session) < 0) {
-+ fprintf(stderr, "gnutls_set_default_priority FAILED");
-+ exit(-1); //fixme
++ if ((ret = gnutls_set_default_priority(sd->session)) < 0) {
++ rfbLog("gnutls_set_default_priority failed: %s\n", gnutls_strerror(ret));
++ sd->session = NULL;
++ rfbCloseClient(cl);
++ return;
+ }
+
++ /* optimize for speed */
++ static const int cipher_priority_performance[] = {
++ GNUTLS_CIPHER_ARCFOUR_128,
++ GNUTLS_CIPHER_AES_128_CBC,
++ GNUTLS_CIPHER_3DES_CBC, 0
++ };
++
++ if ((ret = gnutls_cipher_set_priority(sd->session, cipher_priority_performance)) < 0) {
++ rfbLog("gnutls_cipher_set_priority failed: %s\n", gnutls_strerror(ret));
++ sd->session = NULL;
++ rfbCloseClient(cl);
++ return;
++ }
++
+ static const int kx_anon[] = {GNUTLS_KX_ANON_DH, 0};
-+ if (gnutls_kx_set_priority(sd->session, kx_anon) < 0) {
-+ fprintf(stderr, "gnutls_kx_set_priority FAILED");
-+ exit(-1); //fixme
++ if ((ret = gnutls_kx_set_priority(sd->session, kx_anon)) < 0) {
++ rfbLog("gnutls_kx_set_priority failed: %s\n", gnutls_strerror(ret));
++ sd->session = NULL;
++ rfbCloseClient(cl);
++ return;
+ }
+
+ static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
-+ if (gnutls_certificate_type_set_priority(sd->session, cert_type_priority) < 0) {
-+ fprintf(stderr, "gnutls_certificate_type_set_priority FAILED");
-+ exit(-1); //fixme
++ if ((ret = gnutls_certificate_type_set_priority(sd->session, cert_type_priority)) < 0) {
++ rfbLog("gnutls_certificate_type_set_priority failed: %s\n",
++ gnutls_strerror(ret));
++ sd->session = NULL;
++ rfbCloseClient(cl);
++ return;
+ }
+
+ static const int protocol_priority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
-+ if (gnutls_protocol_set_priority(sd->session, protocol_priority) < 0) {
-+ fprintf(stderr, "gnutls_protocol_set_priority FAILED");
-+ exit(-1); //fixme
++ if ((ret = gnutls_protocol_set_priority(sd->session, protocol_priority)) < 0) {
++ rfbLog("gnutls_protocol_set_priority failed: %s\n",
++ gnutls_strerror(ret));
++ sd->session = NULL;
++ rfbCloseClient(cl);
++ return;
+ }
+
+ gnutls_anon_server_credentials anon_cred;
+
+ if (!(anon_cred = tls_initialize_anon_cred())) {
-+ exit(-1); //fixme
++ sd->session = NULL;
++ rfbCloseClient(cl);
++ return;
+ }
+
-+ if (gnutls_credentials_set(sd->session, GNUTLS_CRD_ANON, anon_cred) < 0) {
-+ fprintf(stderr, "gnutls_credentials_set FAILED");
++ if ((ret = gnutls_credentials_set(sd->session, GNUTLS_CRD_ANON, anon_cred)) < 0) {
++ rfbLog("gnutls_credentials_set failed: %s\n", gnutls_strerror(ret));
+ gnutls_anon_free_server_credentials(anon_cred);
-+ exit(-1); //fixme
++ sd->session = NULL;
++ rfbCloseClient(cl);
++ return;
+ }
+
+ gnutls_transport_set_ptr(sd->session, (gnutls_transport_ptr_t)cl);
@@ -285,7 +461,7 @@
+
+ if ((ret = gnutls_handshake(sd->session)) < 0) {
+ if (!gnutls_error_is_fatal(ret)) {
-+ usleep(10000);
++ usleep(100000);
+ goto retry;
+ }
+ rfbLog("rfbVncAuthVencrypt: handshake failed\n");
@@ -293,26 +469,18 @@
+ return;
+ }
+
-+ cl->sock_read_fn = &my_tls_read;
-+
-+ /* start subauth - read plain password */
-+ n = rfbReadExact(cl, buf, 8);
-+ if (n <= 0) {
-+ if (n == 0)
-+ rfbLog("rfbVncAuthVencrypt: client gone\n");
-+ else
-+ rfbLogPerror("rfbVncAuthVencrypt: read");
-+ rfbCloseClient(cl);
-+ return;
-+ }
++ /* set up TLS read/write hooks */
++ cl->clientData = sd;
++ cl->sock_read_fn = &vnc_tls_read;
++ cl->sock_write_fn = &vnc_tls_write;
+
-+ //fixme: read len, lew, id, pw
++ vencrypt_subauth_plain(cl);
+
+ printf("TEST end\n");
}
static rfbSecurityHandler VncSecurityHandlerVencrypt = {
-@@ -1759,6 +2020,21 @@
+@@ -1759,6 +2188,21 @@
time_t elapsed, cur_time;
struct winsize dimensions;
@@ -334,7 +502,7 @@
for (i = 1; i < argc; i++) {
if (!strcmp (argv[i], "-c")) {
command = argv[i+1];
-@@ -1784,6 +2060,8 @@
+@@ -1784,6 +2228,8 @@
#ifdef DEBUG
rfbLogEnable (1);
@@ -346,7 +514,7 @@
Index: vnc/libvncserver/sockets.c
===================================================================
--- vnc.orig/libvncserver/sockets.c 2011-01-20 16:42:41.000000000 +0100
-+++ vnc/libvncserver/sockets.c 2011-01-20 16:47:59.000000000 +0100
++++ vnc/libvncserver/sockets.c 2011-01-21 06:32:42.000000000 +0100
@@ -454,8 +454,12 @@
fd_set fds;
struct timeval tv;
@@ -361,24 +529,40 @@
if (n > 0) {
+@@ -538,7 +542,10 @@
+
+ LOCK(cl->outputMutex);
+ while (len > 0) {
+- n = write(sock, buf, len);
++ if (cl->sock_write_fn)
++ n = cl->sock_write_fn(cl, buf, len);
++ else
++ n = write(sock, buf, len);
+
+ if (n > 0) {
+
Index: vnc/rfb/rfb.h
===================================================================
--- vnc.orig/rfb/rfb.h 2011-01-20 16:36:06.000000000 +0100
-+++ vnc/rfb/rfb.h 2011-01-20 16:51:22.000000000 +0100
-@@ -397,6 +397,8 @@
++++ vnc/rfb/rfb.h 2011-01-21 06:44:22.000000000 +0100
+@@ -397,6 +397,9 @@
struct _rfbStatList *Next;
} rfbStatList;
+typedef ssize_t (*sock_read_fn_t)(struct _rfbClientRec *cl, void *buf, size_t count);
++typedef ssize_t (*sock_write_fn_t)(struct _rfbClientRec *cl, const void *buf, size_t count);
+
typedef struct _rfbClientRec {
/* back pointer to the screen */
-@@ -417,6 +419,7 @@
+@@ -417,6 +420,10 @@
void* clientData;
ClientGoneHookPtr clientGoneHook;
++ /* use to hook up TLS read/write */
+ sock_read_fn_t sock_read_fn;
++ sock_read_fn_t sock_write_fn;
++
SOCKET sock;
char *host;
More information about the pve-devel
mailing list