Commit 521b9d98 authored by runge's avatar runge

classes/ssl: Java SSL applet viewer now works with certificate chains.

x11vnc: Printout option -sslScripts.  Suggest -auth guess in error message.  Set fake_screen width and height.  Test for +kb in Xvfb.
parent 909683fd
......@@ -218,8 +218,13 @@ Both TightVNC and UltraVNC Java viewers:
yes/no, default: no
Automatically trust any cert that the web browsers has accepted.
E.g. the user said "Yes" or "Continue" to a web browser dialog
regarding a certificate. If we get the same cert from the VNC
server we trust it without prompting the user.
regarding a certificate. If we get the same cert (chain) from
the VNC server we trust it without prompting the user.
debugCerts
yes/no, default: no
Print out every cert in the Server, TrustUrl, TrustAll chains.
TightVNC Java viewer only:
......
......@@ -73,8 +73,8 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/RfbProto.java vnc_javasrc/RfbProto
serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSLSocketToMe.java
--- vnc_javasrc.orig/SSLSocketToMe.java 1969-12-31 19:00:00.000000000 -0500
+++ vnc_javasrc/SSLSocketToMe.java 2009-08-13 09:16:42.000000000 -0400
@@ -0,0 +1,1727 @@
+++ vnc_javasrc/SSLSocketToMe.java 2010-02-22 20:03:11.000000000 -0500
@@ -0,0 +1,1712 @@
+/*
+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
+ *
......@@ -151,6 +151,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+
+ boolean use_url_cert_for_auth = true;
+ boolean user_wants_to_see_cert = true;
+ boolean debug_certs = false;
+
+ /* cert(s) we retrieve from VNC server */
+ java.security.cert.Certificate[] trustallCerts = null;
......@@ -180,6 +181,8 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ port = p;
+ viewer = v;
+
+ debug_certs = v.debugCerts;
+
+ /* we will first try default factory for certification: */
+
+ factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
......@@ -237,21 +240,6 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ throw new CertificateException(
+ "No Trust url Certs.");
+ }
+ if (trusturlCerts.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < trusturlCerts.length - 1; i++) {
+ if (! trusturlCerts[i].equals(trusturlCerts[i+1])) {
+ ok = false;
+ }
+ }
+ if (! ok) {
+ throw new CertificateException(
+ "Too many Trust url Certs: "
+ + trusturlCerts.length
+ );
+ }
+ }
+ if (certs == null) {
+ throw new CertificateException(
+ "No this-certs array.");
......@@ -260,26 +248,32 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ throw new CertificateException(
+ "No this-certs Certs.");
+ }
+ if (certs.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < certs.length - 1; i++) {
+ if (! certs[i].equals(certs[i+1])) {
+ ok = false;
+ }
+ if (certs.length != trusturlCerts.length) {
+ throw new CertificateException(
+ "certs.length != trusturlCerts.length " + certs.length + " " + trusturlCerts.length);
+ }
+ boolean ok = true;
+ for (int i = 0; i < certs.length; i++) {
+ if (! trusturlCerts[i].equals(certs[i])) {
+ ok = false;
+ dbg("URL: cert mismatch at i=" + i);
+ dbg("URL: cert mismatch cert" + certs[i]);
+ dbg("URL: cert mismatch url" + trusturlCerts[i]);
+ }
+ if (! ok) {
+ throw new CertificateException(
+ "Too many this-certs: "
+ + certs.length
+ );
+ if (debug_certs) {
+ dbg("\n***********************************************");
+ dbg("URL: cert info at i=" + i);
+ dbg("URL: cert info cert" + certs[i]);
+ dbg("===============================================");
+ dbg("URL: cert info url" + trusturlCerts[i]);
+ dbg("***********************************************");
+ }
+ }
+ if (! trusturlCerts[0].equals(certs[0])) {
+ if (!ok) {
+ throw new CertificateException(
+ "Server Cert Changed != URL.");
+ "Server Cert Chain != URL Cert Chain.");
+ }
+ dbg("URL: trusturlCerts[0] matches certs[0]");
+ dbg("URL: trusturlCerts[i] matches certs[i] i=0:" + (certs.length-1));
+ }
+ }
+ };
......@@ -309,21 +303,6 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ throw new CertificateException(
+ "No Trust All Server Certs.");
+ }
+ if (trustallCerts.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < trustallCerts.length - 1; i++) {
+ if (! trustallCerts[i].equals(trustallCerts[i+1])) {
+ ok = false;
+ }
+ }
+ if (! ok) {
+ throw new CertificateException(
+ "Too many Trust All Server Certs: "
+ + trustallCerts.length
+ );
+ }
+ }
+ if (certs == null) {
+ throw new CertificateException(
+ "No this-certs array.");
......@@ -332,26 +311,32 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+ throw new CertificateException(
+ "No this-certs Certs.");
+ }
+ if (certs.length > 1) {
+ int i;
+ boolean ok = true;
+ for (i = 0; i < certs.length - 1; i++) {
+ if (! certs[i].equals(certs[i+1])) {
+ ok = false;
+ }
+ if (certs.length != trustallCerts.length) {
+ throw new CertificateException(
+ "certs.length != trustallCerts.length " + certs.length + " " + trustallCerts.length);
+ }
+ boolean ok = true;
+ for (int i = 0; i < certs.length; i++) {
+ if (! trustallCerts[i].equals(certs[i])) {
+ ok = false;
+ dbg("ONE: cert mismatch at i=" + i);
+ dbg("ONE: cert mismatch cert" + certs[i]);
+ dbg("ONE: cert mismatch all" + trustallCerts[i]);
+ }
+ if (! ok) {
+ throw new CertificateException(
+ "Too many this-certs: "
+ + certs.length
+ );
+ if (debug_certs) {
+ dbg("\n***********************************************");
+ dbg("ONE: cert info at i=" + i);
+ dbg("ONE: cert info cert" + certs[i]);
+ dbg("===============================================");
+ dbg("ONE: cert info all" + trustallCerts[i]);
+ dbg("***********************************************");
+ }
+ }
+ if (! trustallCerts[0].equals(certs[0])) {
+ if (!ok) {
+ throw new CertificateException(
+ "Server Cert Changed != TRUSTALL.");
+ "Server Cert Chain != TRUSTALL Cert Chain.");
+ }
+ dbg("ONE: trustallCerts[0] matches certs[0]");
+ dbg("ONE: trustallCerts[i] matches certs[i] i=0:" + (certs.length-1));
+ }
+ }
+ };
......@@ -1804,7 +1789,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/SSLSocketToMe.java vnc_javasrc/SSL
+}
diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncViewer.java
--- vnc_javasrc.orig/VncViewer.java 2004-03-04 08:34:25.000000000 -0500
+++ vnc_javasrc/VncViewer.java 2009-06-19 10:32:03.000000000 -0400
+++ vnc_javasrc/VncViewer.java 2010-02-22 19:25:19.000000000 -0500
@@ -80,7 +80,7 @@
// Variables read from parameter values.
String socketFactory;
......@@ -1814,7 +1799,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncView
boolean showControls;
boolean offerRelogin;
boolean showOfflineDesktop;
@@ -88,6 +88,19 @@
@@ -88,6 +88,20 @@
int deferCursorUpdates;
int deferUpdateRequests;
......@@ -1830,11 +1815,12 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncView
+ boolean ignoreProxy;
+ boolean trustAllVncCerts;
+ boolean trustUrlVncCert;
+ boolean debugCerts;
+
// Reference to this applet for inter-applet communication.
public static java.applet.Applet refApplet;
@@ -591,8 +604,25 @@
@@ -591,8 +605,25 @@
}
}
......@@ -1862,7 +1848,7 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncView
if (inAnApplet) {
str = readParameter("Open New Window", false);
@@ -626,6 +656,96 @@
@@ -626,6 +657,101 @@
// SocketFactory.
socketFactory = readParameter("SocketFactory", false);
......@@ -1955,6 +1941,11 @@ diff -x VncCanvas.java -Naur vnc_javasrc.orig/VncViewer.java vnc_javasrc/VncView
+ str = readParameter("trustUrlVncCert", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ trustUrlVncCert = true;
+ }
+ debugCerts = false;
+ str = readParameter("debugCerts", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ debugCerts = true;
+ }
}
......
2010-02-22 Karl Runge <runge@karlrunge.com>
* classes/ssl: Java SSL applet viewer now works with certificate
chains.
* x11vnc: Printout option -sslScripts. Suggest -auth guess
in error message. Set fake_screen width and height. Test
for +kb in Xvfb.
2010-01-02 Karl Runge <runge@karlrunge.com>
* x11vnc: small tweaks to Xdummy, rx11vnc*. Apply
SMALL_FOOTPRINT to -appshare text. Copyright year change.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1753,14 +1753,14 @@ void print_help(int mode) {
" ssh) and you do not want x11vnc waiting around for more\n"
" connections, tying up ports, etc.\n"
"\n"
"-ssldir [dir] Use [dir] as an alternate ssl certificate and key\n"
"-ssldir dir Use \"dir\" as an alternate ssl certificate and key\n"
" management toplevel directory. The default is\n"
" ~/.vnc/certs\n"
"\n"
" This directory is used to store server and other\n"
" certificates and keys and also other materials. E.g. in\n"
" the simplest case, \"-ssl SAVE\" will store the x11vnc\n"
" server cert in [dir]/server.pem\n"
" server cert in dir/server.pem\n"
"\n"
" Use of alternate directories via -ssldir allows you to\n"
" manage multiple VNC Certificate Authority (CA) keys.\n"
......@@ -1772,14 +1772,14 @@ void print_help(int mode) {
" -ssldir affects nearly all of the other -ssl* options,\n"
" e.g. -ssl SAVE, -sslGenCert, etc..\n"
"\n"
"-sslverify [path] For either of the -ssl or -stunnel modes, use [path]\n"
"-sslverify path For either of the -ssl or -stunnel modes, use \"path\"\n"
" to provide certificates to authenticate incoming VNC\n"
" *Client* connections (normally only the server is\n"
" authenticated in SSL.) This can be used as a method\n"
" to replace standard password authentication of clients.\n"
"\n"
" If [path] is a directory it contains the client (or CA)\n"
" certificates in separate files. If [path] is a file,\n"
" If \"path\" is a directory it contains the client (or CA)\n"
" certificates in separate files. If path is a file,\n"
" it contains one or more certificates. See special tokens\n"
" below. These correspond to the \"CApath = dir\" and\n"
" \"CAfile = file\" stunnel options. See the stunnel(8)\n"
......@@ -1789,7 +1789,7 @@ void print_help(int mode) {
" x11vnc -ssl -sslverify ~/my.crt\n"
" x11vnc -ssl -sslverify ~/my_pem_dir/\n"
"\n"
" Note that if [path] is a directory, it must contain\n"
" Note that if path is a directory, it must contain\n"
" the certs in separate files named like <HASH>.0, where\n"
" the value of <HASH> is found by running the command\n"
" \"openssl x509 -hash -noout -in file.crt\". Evidently\n"
......@@ -1801,7 +1801,7 @@ void print_help(int mode) {
" subdirs it manages. Then you can point -sslverify to\n"
" the HASH subdir.\n"
"\n"
" Special tokens: in -ssl mode, if [path] is not a file or\n"
" Special tokens: in -ssl mode, if \"path\" is not a file or\n"
" a directory, it is taken as a comma separated list of\n"
" tokens that are interpreted as follows:\n"
"\n"
......@@ -2090,7 +2090,7 @@ void print_help(int mode) {
" REQ_ARGS='-days 1095' to bump up the expiration date\n"
" (3 years in this case).\n"
"\n"
"-sslEncKey [pem] Utility to encrypt an existing PEM file with a\n"
"-sslEncKey pem Utility to encrypt an existing PEM file with a\n"
" passphrase you supply when prompted. For that key to be\n"
" used (e.g. by x11vnc) the passphrase must be supplied\n"
" each time.\n"
......@@ -2108,7 +2108,7 @@ void print_help(int mode) {
" x11vnc -sslEncKey SAVE\n"
" x11vnc -sslEncKey SAVE-charlie\n"
"\n"
"-sslCertInfo [pem] Prints out information about an existing PEM file.\n"
"-sslCertInfo pem Prints out information about an existing PEM file.\n"
" In addition the public certificate is also printed.\n"
" The openssl(1) program must be in PATH. Basically the\n"
" command \"openssl x509 -text\" is run on the pem.\n"
......@@ -2137,10 +2137,15 @@ void print_help(int mode) {
" The LIST, LISTL, LL, ALL, HASHON, HASHOFF words can\n"
" also be lowercase, e.g. \"list\".\n"
"\n"
"-sslDelCert [pem] Prompts you to delete all .crt .pem .key .req files\n"
"-sslDelCert pem Prompts you to delete all .crt .pem .key .req files\n"
" associated with [pem]. \"SAVE\" and lookups as in\n"
" -sslCertInfo apply as well.\n"
"\n"
"-sslScripts Prints out both the 'genCA' and 'genCert' x11vnc\n"
" openssl wrapper scripts for you to examine, modify, etc.\n"
" The scripts are printed to stdout and then the program\n"
" exits.\n"
"\n"
"\n"
"-stunnel [pem] Use the stunnel(8) (www.stunnel.org) to provide an\n"
" encrypted SSL tunnel between viewers and x11vnc.\n"
......@@ -5530,7 +5535,7 @@ void xopen_display_fail_message(char *disp) {
" x11vnc.\n");
fprintf(stderr, " - Being root is usually not enough because the"
" incorrect MIT-MAGIC-COOKIE\n");
fprintf(stderr, " file will be accessed. The cookie file contains"
fprintf(stderr, " file may be accessed. The cookie file contains"
" the secret key that\n");
fprintf(stderr, " allows x11vnc to connect to the desired"
" X DISPLAY.\n");
......@@ -5542,6 +5547,7 @@ void xopen_display_fail_message(char *disp) {
fprintf(stderr, " x11vnc -auth /tmp/.gdmzndVlR"
" -display :0\n");
fprintf(stderr, " you must have read permission for the auth file.\n");
fprintf(stderr, " See also '-auth guess' and '-findauth' discussed below.\n");
fprintf(stderr, "\n");
fprintf(stderr, "** If NO ONE is logged into an X session yet, but"
" there is a greeter login\n");
......@@ -5561,6 +5567,12 @@ void xopen_display_fail_message(char *disp) {
fprintf(stderr, " Sometimes the command \"ps wwwwaux | grep auth\""
" can reveal the file location.\n");
fprintf(stderr, "\n");
fprintf(stderr, " Starting with x11vnc 0.9.9 you can have it try to guess by using:\n");
fprintf(stderr, "\n");
fprintf(stderr, " -auth guess\n");
fprintf(stderr, "\n");
fprintf(stderr, " (see also the x11vnc -findauth option.)\n");
fprintf(stderr, "\n");
fprintf(stderr, " Only root will have read permission for the"
" file, and so x11vnc must be run\n");
fprintf(stderr, " as root (or copy it). The random characters in the filenames"
......
......@@ -2608,6 +2608,8 @@ static void snap_vcsa_rawfb(void) {
fake_screen->frameBuffer = snap->data;
fake_screen->paddedWidthInBytes = snap->bytes_per_line;
fake_screen->serverFormat.bitsPerPixel = raw_fb_native_bpp;
fake_screen->width = snap->width;
fake_screen->height = snap->height;
for (i=0; i < rows * cols; i++) {
int ix, iy, x, y, w, h;
......
......@@ -53,6 +53,7 @@ int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vnc_hport
void stop_stunnel(void);
void setup_stunnel(int rport, int *argc, char **argv);
char *get_Cert_dir(char *cdir_in, char **tmp_in);
void sslScripts(void);
void sslGenCA(char *cdir);
void sslGenCert(char *ty, char *nm);
void sslEncKey(char *path, int info_only);
......@@ -558,6 +559,15 @@ static char *getsslscript(char *cdir, char *name, char *script) {
return scr;
}
void sslScripts(void) {
fprintf(stdout, "======================================================\n");
fprintf(stdout, "genCA script for '-sslGenCA':\n\n");
fprintf(stdout, "%s\n", genCA);
fprintf(stdout, "======================================================\n");
fprintf(stdout, "genCert script for '-sslGenCert', etc.:\n\n");
fprintf(stdout, "%s\n", genCert);
}
void sslGenCA(char *cdir) {
char *cmd, *scr = getsslscript(cdir, "genca", genCA);
......
......@@ -40,6 +40,7 @@ extern int start_stunnel(int stunnel_port, int x11vnc_port, int hport, int x11vn
extern void stop_stunnel(void);
extern void setup_stunnel(int rport, int *argc, char **argv);
extern char *get_Cert_dir(char *cdir_in, char **tmp_in);
extern void sslScripts(void);
extern void sslGenCA(char *cdir);
extern void sslGenCert(char *ty, char *nm);
extern void sslEncKey(char *path, int info_only);
......
......@@ -2078,7 +2078,10 @@ char create_display[] =
" sarg=\"screen\"\n"
" fi\n"
" fi\n"
" margs=\"+kb\"\n"
" margs=\"\"\n"
" if $have_Xvfb -help 2>&1 | grep '^\\+kb[ ].*Keyboard Extension' >/dev/null; then\n"
" margs=\"+kb\"\n"
" fi\n"
"\n"
" # currently not enabled in Xvfb's we see.\n"
"# if $have_Xvfb -extension MOOMOO 2>&1 | grep -w RANDR >/dev/null; then\n"
......
.\" This file was automatically generated from x11vnc -help output.
.TH X11VNC "1" "January 2010" "x11vnc " "User Commands"
.TH X11VNC "1" "February 2010" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.9.10, lastmod: 2010-01-07
version: 0.9.10, lastmod: 2010-02-21
.SH SYNOPSIS
.B x11vnc
[OPTION]...
......@@ -1945,16 +1945,16 @@ scripting SSL connections (e.g. x11vnc is started via
ssh) and you do not want x11vnc waiting around for more
connections, tying up ports, etc.
.PP
\fB-ssldir\fR \fI[dir]\fR
\fB-ssldir\fR \fIdir\fR
.IP
Use [dir] as an alternate ssl certificate and key
Use \fIdir\fR as an alternate ssl certificate and key
management toplevel directory. The default is
~/.vnc/certs
.IP
This directory is used to store server and other
certificates and keys and also other materials. E.g. in
the simplest case, "\fB-ssl\fR \fISAVE\fR" will store the x11vnc
server cert in [dir]/server.pem
server cert in dir/server.pem
.IP
Use of alternate directories via \fB-ssldir\fR allows you to
manage multiple VNC Certificate Authority (CA) keys.
......@@ -1966,16 +1966,16 @@ filesystem to prevent network snooping (for example
\fB-ssldir\fR affects nearly all of the other \fB-ssl*\fR options,
e.g. \fB-ssl\fR SAVE, \fB-sslGenCert,\fR etc..
.PP
\fB-sslverify\fR \fI[path]\fR
\fB-sslverify\fR \fIpath\fR
.IP
For either of the \fB-ssl\fR or \fB-stunnel\fR modes, use [path]
For either of the \fB-ssl\fR or \fB-stunnel\fR modes, use \fIpath\fR
to provide certificates to authenticate incoming VNC
*Client* connections (normally only the server is
authenticated in SSL.) This can be used as a method
to replace standard password authentication of clients.
.IP
If [path] is a directory it contains the client (or CA)
certificates in separate files. If [path] is a file,
If \fIpath\fR is a directory it contains the client (or CA)
certificates in separate files. If path is a file,
it contains one or more certificates. See special tokens
below. These correspond to the "CApath = dir" and
"CAfile = file" stunnel options. See the
......@@ -1986,7 +1986,7 @@ Examples:
x11vnc \fB-ssl\fR \fB-sslverify\fR ~/my.crt
x11vnc \fB-ssl\fR \fB-sslverify\fR ~/my_pem_dir/
.IP
Note that if [path] is a directory, it must contain
Note that if path is a directory, it must contain
the certs in separate files named like <HASH>.0, where
the value of <HASH> is found by running the command
"openssl x509 \fB-hash\fR \fB-noout\fR \fB-in\fR file.crt". Evidently
......@@ -1998,7 +1998,7 @@ hashes for you automatically (via symlink) in the HASH
subdirs it manages. Then you can point \fB-sslverify\fR to
the HASH subdir.
.IP
Special tokens: in \fB-ssl\fR mode, if [path] is not a file or
Special tokens: in \fB-ssl\fR mode, if \fIpath\fR is not a file or
a directory, it is taken as a comma separated list of
tokens that are interpreted as follows:
.IP
......@@ -2298,7 +2298,7 @@ A common use would be
REQ_ARGS='-days 1095' to bump up the expiration date
(3 years in this case).
.PP
\fB-sslEncKey\fR \fI[pem]\fR
\fB-sslEncKey\fR \fIpem\fR
.IP
Utility to encrypt an existing PEM file with a
passphrase you supply when prompted. For that key to be
......@@ -2320,7 +2320,7 @@ x11vnc \fB-sslEncKey\fR /path/to/foo.pem
x11vnc \fB-sslEncKey\fR SAVE
x11vnc \fB-sslEncKey\fR SAVE-charlie
.PP
\fB-sslCertInfo\fR \fI[pem]\fR
\fB-sslCertInfo\fR \fIpem\fR
.IP
Prints out information about an existing PEM file.
In addition the public certificate is also printed.
......@@ -2353,12 +2353,19 @@ removes these HASH subdirs.
The LIST, LISTL, LL, ALL, HASHON, HASHOFF words can
also be lowercase, e.g. "list".
.PP
\fB-sslDelCert\fR \fI[pem]\fR
\fB-sslDelCert\fR \fIpem\fR
.IP
Prompts you to delete all .crt .pem .key .req files
associated with [pem]. "SAVE" and lookups as in
\fB-sslCertInfo\fR apply as well.
.PP
\fB-sslScripts\fR
.IP
Prints out both the 'genCA' and 'genCert' x11vnc
openssl wrapper scripts for you to examine, modify, etc.
The scripts are printed to stdout and then the program
exits.
.PP
\fB-stunnel\fR \fI[pem]\fR
.IP
Use the
......
......@@ -2844,6 +2844,11 @@ int main(int argc, char* argv[]) {
exit(0);
continue;
}
if (!strcmp(arg, "-sslScripts")) {
sslScripts();
exit(0);
continue;
}
if (!strcmp(arg, "-stunnel")) {
use_stunnel = 1;
got_tls = -1000;
......
......@@ -47,7 +47,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.10 lastmod: 2010-01-07";
char lastmod[] = "0.9.10 lastmod: 2010-02-21";
/* X display info */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment