OpenSSL: patch

J

Jamis Buck

--------------000506080602020001080008
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Attached is a patch for the Ruby/OpenSSL module, done against the code
in the snapshot.tar.gz file as currently available from
http://www.ruby-lang.org.

This patch adds functionality necessary to support SSH operations. I
have also added a new method to Cipher::Cipher: called "crypt". I did
this because I couldn't get the update/final stuff to work. This may
have been because I do not have a complete understanding of how they are
*supposed* to work. Still, I have a very hacked-together SSH client in
Ruby now, using the routines provided by this patch.

Please let me know if you have any questions!

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a <<
r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'

--------------000506080602020001080008
Content-Type: text/x-patch;
name="openssl.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="openssl.patch"

Only in ruby.mod/ext/openssl: :q
diff -ur ruby/ext/openssl/ossl_cipher.c ruby.mod/ext/openssl/ossl_cipher.c
--- ruby/ext/openssl/ossl_cipher.c 2003-09-17 03:05:02.000000000 -0600
+++ ruby.mod/ext/openssl/ossl_cipher.c 2004-06-09 22:27:07.000000000 -0600
@@ -228,6 +228,28 @@
return self;
}

+static VALUE
+ossl_cipher_crypt(VALUE self, VALUE data)
+{
+ EVP_CIPHER_CTX *ctx;
+ VALUE result;
+
+ GetCipher(self, ctx);
+
+ StringValue(data);
+
+ if( RSTRING(data)->len % EVP_CIPHER_CTX_block_size(ctx) )
+ ossl_raise(eCipherError, "data length not multiple of block size" );
+
+ result = rb_str_buf_new( RSTRING(data)->len );
+ if( EVP_Cipher(ctx, RSTRING(result)->ptr, RSTRING(data)->ptr, RSTRING(data)->len ) == 0 )
+ ossl_raise(eCipherError, NULL);
+
+ RSTRING(result)->len = RSTRING(data)->len;
+
+ return result;
+}
+
static VALUE
ossl_cipher_update(VALUE self, VALUE data)
{
@@ -357,6 +379,7 @@

rb_define_method(cCipher, "reset", ossl_cipher_reset, 0);

+ rb_define_method(cCipher, "crypt", ossl_cipher_crypt, 1);
rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1);
rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1);
rb_define_method(cCipher, "update", ossl_cipher_update, 1);
diff -ur ruby/ext/openssl/ossl_pkey_dh.c ruby.mod/ext/openssl/ossl_pkey_dh.c
--- ruby/ext/openssl/ossl_pkey_dh.c 2004-01-08 05:24:22.000000000 -0700
+++ ruby.mod/ext/openssl/ossl_pkey_dh.c 2004-06-06 06:54:45.000000000 -0600
@@ -129,29 +129,33 @@
VALUE arg, gen;

GetPKey(self, pkey);
- rb_scan_args(argc, argv, "11", &arg, &gen);
- if (FIXNUM_P(arg)) {
- if (!NIL_P(gen)) {
- g = FIX2INT(gen);
- }
- if (!(dh = dh_generate(FIX2INT(arg), g))) {
- ossl_raise(eDHError, NULL);
- }
+ if( 0 == rb_scan_args(argc, argv, "02", &arg, &gen) ) {
+ dh = DH_new();
}
else {
- arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
- dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
- if (!dh){
- BIO_reset(in);
- dh = d2i_DHparams_bio(in, NULL);
- }
- BIO_free(in);
- if (!dh) ossl_raise(eDHError, NULL);
+ if (FIXNUM_P(arg)) {
+ if (!NIL_P(gen)) {
+ g = FIX2INT(gen);
+ }
+ if (!(dh = dh_generate(FIX2INT(arg), g))) {
+ ossl_raise(eDHError, NULL);
+ }
+ }
+ else {
+ arg = ossl_to_der_if_possible(arg);
+ in = ossl_obj2bio(arg);
+ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
+ if (!dh){
+ BIO_reset(in);
+ dh = d2i_DHparams_bio(in, NULL);
+ }
+ BIO_free(in);
+ if (!dh) ossl_raise(eDHError, NULL);
+ }
}
if (!EVP_PKEY_assign_DH(pkey, dh)) {
- DH_free(dh);
- ossl_raise(eRSAError, NULL);
+ DH_free(dh);
+ ossl_raise(eRSAError, NULL);
}
return self;
}
@@ -299,7 +303,7 @@
dh = pkey->pkey.dh;

if (!DH_check(dh, &codes)) {
- return Qfalse;
+ return Qfalse;
}

return codes == 0 ? Qtrue : Qfalse;
@@ -315,7 +319,7 @@
dh = pkey->pkey.dh;

if (!DH_generate_key(dh))
- ossl_raise(eDHError, "Failed to generate key");
+ ossl_raise(eDHError, "Failed to generate key");
return self;
}

@@ -342,6 +346,30 @@
return str;
}

+#define dh_bignum_accessors( varname ) \
+ static VALUE \
+ ossl_dh_get_##varname( VALUE self ) \
+ { \
+ EVP_PKEY *pkey; \
+ GetPKeyDH( self, pkey ); \
+ if( pkey->pkey.dh->varname == NULL ) return Qnil; \
+ return ossl_bn_new( pkey->pkey.dh->varname ); \
+ } \
+ static VALUE \
+ ossl_dh_set_##varname( VALUE self, VALUE varname ) \
+ { \
+ EVP_PKEY *pkey; \
+ GetPKeyDH(self, pkey); \
+ if( pkey->pkey.dh->varname != NULL ) BN_clear_free( pkey->pkey.dh->varname ); \
+ pkey->pkey.dh->varname = BN_dup( GetBNPtr( varname ) ); \
+ return varname; \
+ }
+
+dh_bignum_accessors( p )
+dh_bignum_accessors( g )
+dh_bignum_accessors( pub_key )
+dh_bignum_accessors( priv_key )
+
/*
* INIT
*/
@@ -368,6 +396,15 @@
rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0);
rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1);

+ rb_define_method(cDH, "p", ossl_dh_get_p, 0 );
+ rb_define_method(cDH, "p=", ossl_dh_set_p, 1 );
+ rb_define_method(cDH, "g", ossl_dh_get_g, 0 );
+ rb_define_method(cDH, "g=", ossl_dh_set_g, 1 );
+ rb_define_method(cDH, "pub_key", ossl_dh_get_pub_key, 0 );
+ rb_define_method(cDH, "pub_key=", ossl_dh_set_pub_key, 1 );
+ rb_define_method(cDH, "priv_key", ossl_dh_get_priv_key, 0 );
+ rb_define_method(cDH, "priv_key=", ossl_dh_set_priv_key, 1 );
+
rb_define_method(cDH, "params", ossl_dh_get_params, 0);
}

diff -ur ruby/ext/openssl/ossl_pkey_dsa.c ruby.mod/ext/openssl/ossl_pkey_dsa.c
--- ruby/ext/openssl/ossl_pkey_dsa.c 2004-01-08 05:24:22.000000000 -0700
+++ ruby.mod/ext/openssl/ossl_pkey_dsa.c 2004-06-06 21:31:26.000000000 -0600
@@ -129,39 +129,43 @@
VALUE arg, pass;

GetPKey(self, pkey);
- rb_scan_args(argc, argv, "11", &arg, &pass);
- if (FIXNUM_P(arg)) {
- if (!(dsa = dsa_generate(FIX2INT(arg)))) {
- ossl_raise(eDSAError, NULL);
- }
+ if( rb_scan_args(argc, argv, "02", &arg, &pass) == 0 ) {
+ dsa = DH_new();
}
else {
- if (!NIL_P(pass)) passwd = StringValuePtr(pass);
- arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
- dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
- if (!dsa) {
- BIO_reset(in);
- dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
- }
- if (!dsa) {
- BIO_reset(in);
- dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
- }
- if (!dsa) {
- BIO_reset(in);
- dsa = d2i_DSAPrivateKey_bio(in, NULL);
- }
- if (!dsa) {
- BIO_reset(in);
- dsa = d2i_DSA_PUBKEY_bio(in, NULL);
- }
- BIO_free(in);
- if (!dsa) ossl_raise(eDSAError, "Neither PUB key nor PRIV key:");
+ if (FIXNUM_P(arg)) {
+ if (!(dsa = dsa_generate(FIX2INT(arg)))) {
+ ossl_raise(eDSAError, NULL);
+ }
+ }
+ else {
+ if (!NIL_P(pass)) passwd = StringValuePtr(pass);
+ arg = ossl_to_der_if_possible(arg);
+ in = ossl_obj2bio(arg);
+ dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
+ if (!dsa) {
+ BIO_reset(in);
+ dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL);
+ }
+ if (!dsa) {
+ BIO_reset(in);
+ dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
+ }
+ if (!dsa) {
+ BIO_reset(in);
+ dsa = d2i_DSAPrivateKey_bio(in, NULL);
+ }
+ if (!dsa) {
+ BIO_reset(in);
+ dsa = d2i_DSA_PUBKEY_bio(in, NULL);
+ }
+ BIO_free(in);
+ if (!dsa) ossl_raise(eDSAError, "Neither PUB key nor PRIV key:");
+ }
}
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
- DSA_free(dsa);
- ossl_raise(eDSAError, NULL);
+ DSA_free(dsa);
+ ossl_raise(eDSAError, NULL);
}

return self;
@@ -370,6 +374,12 @@
return Qfalse;
}

+OSSL_PKEY_BN(dsa, p);
+OSSL_PKEY_BN(dsa, q);
+OSSL_PKEY_BN(dsa, g);
+OSSL_PKEY_BN(dsa, pub_key);
+OSSL_PKEY_BN(dsa, priv_key);
+
/*
* INIT
*/
@@ -394,6 +404,12 @@
rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1);
rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2);

+ DEF_OSSL_PKEY_BN(cDSA, dsa, p);
+ DEF_OSSL_PKEY_BN(cDSA, dsa, q);
+ DEF_OSSL_PKEY_BN(cDSA, dsa, g);
+ DEF_OSSL_PKEY_BN(cDSA, dsa, pub_key);
+ DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key);
+
rb_define_method(cDSA, "params", ossl_dsa_get_params, 0);
}

diff -ur ruby/ext/openssl/ossl_pkey_rsa.c ruby.mod/ext/openssl/ossl_pkey_rsa.c
--- ruby/ext/openssl/ossl_pkey_rsa.c 2004-01-08 05:24:22.000000000 -0700
+++ ruby.mod/ext/openssl/ossl_pkey_rsa.c 2004-06-05 21:17:06.000000000 -0600
@@ -119,42 +119,46 @@
VALUE arg, pass;

GetPKey(self, pkey);
- rb_scan_args(argc, argv, "11", &arg, &pass);
- if (FIXNUM_P(arg)) {
- rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass));
- if (!rsa) ossl_raise(eRSAError, NULL);
+ if( rb_scan_args(argc, argv, "02", &arg, &pass) == 0 ) {
+ rsa = RSA_new();
}
else {
- if (!NIL_P(pass)) passwd = StringValuePtr(pass);
- arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
- rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
- if (!rsa) {
- BIO_reset(in);
- rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
- }
- if (!rsa) {
- BIO_reset(in);
- rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
- }
- if (!rsa) {
- BIO_reset(in);
- rsa = d2i_RSAPrivateKey_bio(in, NULL);
- }
- if (!rsa) {
- BIO_reset(in);
- rsa = d2i_RSAPublicKey_bio(in, NULL);
- }
- if (!rsa) {
- BIO_reset(in);
- rsa = d2i_RSA_PUBKEY_bio(in, NULL);
- }
- BIO_free(in);
- if (!rsa) ossl_raise(eRSAError, "Neither PUB key nor PRIV key:");
+ if (FIXNUM_P(arg)) {
+ rsa = rsa_generate(FIX2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2INT(pass));
+ if (!rsa) ossl_raise(eRSAError, NULL);
+ }
+ else {
+ if (!NIL_P(pass)) passwd = StringValuePtr(pass);
+ arg = ossl_to_der_if_possible(arg);
+ in = ossl_obj2bio(arg);
+ rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
+ if (!rsa) {
+ BIO_reset(in);
+ rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
+ }
+ if (!rsa) {
+ BIO_reset(in);
+ rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);
+ }
+ if (!rsa) {
+ BIO_reset(in);
+ rsa = d2i_RSAPrivateKey_bio(in, NULL);
+ }
+ if (!rsa) {
+ BIO_reset(in);
+ rsa = d2i_RSAPublicKey_bio(in, NULL);
+ }
+ if (!rsa) {
+ BIO_reset(in);
+ rsa = d2i_RSA_PUBKEY_bio(in, NULL);
+ }
+ BIO_free(in);
+ if (!rsa) ossl_raise(eRSAError, "Neither PUB key nor PRIV key:");
+ }
}
if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
- RSA_free(rsa);
- ossl_raise(eRSAError, NULL);
+ RSA_free(rsa);
+ ossl_raise(eRSAError, NULL);
}

return self;

--------------000506080602020001080008--
 
G

GOTOU Yuuzou

Hi,

In message said:
Attached is a patch for the Ruby/OpenSSL module, done against the code
in the snapshot.tar.gz file as currently available from
http://www.ruby-lang.org.

Thanks a lot. Your patch seems a good solution. It will be
applied when the CVS service's back.

But a question. In ossl_pkey_dh.c, you made
dh_bignum_accessors without using OSSL_PKEY_BN and
DEF_OSSL_PKEY_BN. Does these macro have any problem?
This patch adds functionality necessary to support SSH operations. I
have also added a new method to Cipher::Cipher: called "crypt". I did
this because I couldn't get the update/final stuff to work. This may
have been because I do not have a complete understanding of how they are
*supposed* to work.

Cipher#update and Cipher#final return a String; it is a set
of streamable interface. I feel that Cipher#crypt may be
added if you need a block specific interface.

require "openssl"
bf = OpenSSL::Cipher::Cipher.new("bf")
bf.encrypt
bf.key = "0123456789abcdef"
bf.iv = "01234567"
ciphertext = ""
ciphertext << bf.update("line 1\n")
ciphertext << bf.update("line 2\n")
ciphertext << bf.final
p ciphertext
Still, I have a very hacked-together SSH client in
Ruby now, using the routines provided by this patch.

I look forward to reading it:)

regards,
 
J

Jamis Buck

GOTOU said:
Thanks a lot. Your patch seems a good solution. It will be
applied when the CVS service's back.

But a question. In ossl_pkey_dh.c, you made
dh_bignum_accessors without using OSSL_PKEY_BN and
DEF_OSSL_PKEY_BN. Does these macro have any problem?

Hah! Forget I did that. I wrote those before I discovered the
OSSL_PKEY_BN macros. I discovered them later and then used them (in the
rsa and dsa modules). If you'd like, I'll fix the ossl_pkey_dh.c file
and resubmit the patch. Let me know.
Cipher#update and Cipher#final return a String; it is a set
of streamable interface. I feel that Cipher#crypt may be
added if you need a block specific interface.

[snip]

Hmm. I tried all that, and it wouldn't give me the answer that the ssh
server expected. Using Cipher#crypt, however, did (and it should, since
it is modeled from the OpenSSH code).
I look forward to reading it:)

I'm refactoring all of the (Net::SSH) code now, to make it more robust.
I'm hoping to have something worthwhile to report in a few weeks.

Thanks!

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a <<
r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'
 
M

Mark Hubbart

I'm refactoring all of the (Net::SSH) code now, to make it more
robust. I'm hoping to have something worthwhile to report in a few
weeks.

can't wait to see that :) I can think of several uses right off the top
of my head.

cheers,
Mark
 
J

Jamis Buck

Mark said:
can't wait to see that :) I can think of several uses right off the top
of my head.

I'm glad I'm not the only one that wants this. It's been a pretty
challenging project! I've wanted this for some time, and I finally
decided that it wasn't going to happen if I just kept waiting for
someone else to do it. :) I'm a little nervous about releasing it to the
general public, since (as I've stressed before) cryptography is not by
strong point, by any stretch of the imagination, and reading through the
SSH specs has really emphasized that for me. I've sure learned a ton
about it in the last 3 weeks, though! :)

I finished refactoring my existing code just a few minutes ago. Now I've
got the transport layer about 80% done and a proof-of-concept
user-authentication service written (meaning it's really only about 10%
done). To be written: the connection service, which (when finished) will
be the real "meat and potatoes" of Net::SSH, since that will be the
service that allows you to execute programs (for instance) on the remote
host. Once that's done I'll probably bundle it up and release it, with
the caveat that it's still experimental. At that point, I would REALLY
appreciate feedback (and patches, preferably).

Also, I'm kind of lost as to how to write test cases for something like
this. It's hard to (for instance) force the server to send something
unexpected without writing your own server... :( Any tips?

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a <<
r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'
 
G

GOTOU Yuuzou

In message said:
Hah! Forget I did that. I wrote those before I discovered the
OSSL_PKEY_BN macros. I discovered them later and then used them (in the
rsa and dsa modules). If you'd like, I'll fix the ossl_pkey_dh.c file
and resubmit the patch. Let me know.

I did it. No need to re-post.
Hmm. I tried all that, and it wouldn't give me the answer that the ssh
server expected. Using Cipher#crypt, however, did (and it should, since
it is modeled from the OpenSSH code).

Hmm, Can I leave the decision to you?

regards,
 
G

gabriele renzi

Also, I'm kind of lost as to how to write test cases for something like
this. It's hard to (for instance) force the server to send something
unexpected without writing your own server... :( Any tips?

weite your own server too? :))
 
J

Jamis Buck

GOTOU said:
In message <[email protected]>,



I did it. No need to re-post.

One other thing: I was advised off-list that the "crypt" method I added
is unecessary, and I have verified that this is true. My problem was
that I was not setting the padding. By setting the padding on the cipher
to 0, I can use update/final without any problems. I.e.:

c = OpenSSL::Cipher::Cipher.new(...)
c.encrypt
c.key = ...
c.iv = ...
c.padding = 0 # <-- this is what I was missing

v = c.update( .... ) << c.final
p v

So... if you haven't already applied the patch, I can send you another
one. Or you can just remove the definition of that "crypt" method I added.

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a <<
r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'
 
J

Jamis Buck

gabriele said:
il Mon, 14 Jun 2004 12:37:43 +0900, Jamis Buck <[email protected]> ha
scritto::




weite your own server too? :))

Ha ha. :) Yah, just let me whip out an SSH server while I'm at it. ;)

Although, I have been tinkering with that idea. You could probably do
some fun stuff if you had a Net::SSH::Server module for Ruby, to go with
the Net::SSH client. I think, for now, that I'll work on solidifying the
client, though.

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a <<
r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'
 
G

GOTOU Yuuzou

In message said:
One other thing: I was advised off-list that the "crypt" method I added
is unecessary, and I have verified that this is true. My problem was
that I was not setting the padding. By setting the padding on the cipher
to 0, I can use update/final without any problems. I.e.:

c = OpenSSL::Cipher::Cipher.new(...)
c.encrypt
c.key = ...
c.iv = ...
c.padding = 0 # <-- this is what I was missing

v = c.update( .... ) << c.final
p v

So... if you haven't already applied the patch, I can send you another
one. Or you can just remove the definition of that "crypt" method I added.

No problem. ossl_cipher.c was rolled back.

BTW, I'd like to change the type of the argument of Cipher#padding=.
It should take a boolean but an integer. (patch is attaced.)

# I'll add a workaround to treat backward compatibility if
# it is applied to Ruby 1.8.

regards,

--
gotoyuzo


--- ext/openssl/ossl_cipher.c 17 Sep 2003 09:05:02 -0000 1.4
+++ ext/openssl/ossl_cipher.c 14 Jun 2004 13:34:32 -0000
@@ -315,13 +282,16 @@ ossl_cipher_set_iv(VALUE self, VALUE iv)
static VALUE
ossl_cipher_set_padding(VALUE self, VALUE padding)
{
-#if defined(HAVE_ST_FLAGS)
+#if defined(HAVE_ST_FLAGS) || OPENSSL_VERSION_NUMBER >= 0x0090702fL
+ /*
+ * EVP_CIPHER_CTX_set_padding existed in an earlier versions of openssl.
+ * I don't know the exact version number, but it does exist in 0x0090702fL.
+ */
EVP_CIPHER_CTX *ctx;

GetCipher(self, ctx);
-
- if (EVP_CIPHER_CTX_set_padding(ctx, NUM2INT(padding)) != 1)
- ossl_raise(eCipherError, NULL);
+ if (EVP_CIPHER_CTX_set_padding(ctx, RTEST(padding)) != 1)
+ ossl_raise(eCipherError, NULL);
#else
rb_notimplement();
#endif
 
J

John W. Long

ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/)
{|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'

This signature is amazing! How long did it take you to come up with
that? and what motivated you?
 
J

Jamis Buck

John said:
ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/)
{|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'

This signature is amazing! How long did it take you to come up with
that? and what motivated you?

Hynek has it right -- it was inspired by the myriad "japh" sigs ("Just
Another Perl Hacker"). And it took me far too long to come up with than
I needed to spend on it. ;)

Hynek is also right on another point: whereas Perl is more prone to
obfuscation, one of the goals of Ruby is clarity. Thus, obfuscated sigs
in Ruby are harder to generate than in Perl (IMO), and don't exactly
encourage newbies to leap into Ruby. However, that doesn't keep some of
us from writing them anyway... ;)

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/) {|r| a <<
r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'
 
M

Michael Neumann

John said:
ruby -h | ruby -e
'a=[];readlines.join.scan(/-(.)\[e|Kk(\S*)|le.l(..)e|#!(\S*)/)
{|r| a << r.compact.first };puts "\n>#{a.join(%q/ /)}<\n\n"'

This signature is amazing! How long did it take you to come up with
that? and what motivated you?

Hynek has it right -- it was inspired by the myriad "japh" sigs ("Just
Another Perl Hacker"). And it took me far too long to come up with than
I needed to spend on it. ;)

Hynek is also right on another point: whereas Perl is more prone to
obfuscation, one of the goals of Ruby is clarity. Thus, obfuscated sigs
in Ruby are harder to generate than in Perl (IMO), and don't exactly
encourage newbies to leap into Ruby. However, that doesn't keep some of
us from writing them anyway... ;)

Hehe, mine can even do cool graphics ;-)
(you need ImageMagick's display to see it)
 
N

nobu.nokada

Hi,

At Tue, 15 Jun 2004 22:13:07 +0900,
Jamis Buck wrote in [ruby-talk:103666]:
Hynek is also right on another point: whereas Perl is more prone to
obfuscation, one of the goals of Ruby is clarity. Thus, obfuscated sigs
in Ruby are harder to generate than in Perl (IMO), and don't exactly
encourage newbies to leap into Ruby. However, that doesn't keep some of
us from writing them anyway... ;)

http://jarp.jin.gr.jp/ruby/jarh.rb
 
G

Gennady

Hal said:

Very entertaining! Are all these yours? If you are collecting
them from other people, you may add mine if you wish:

str = "aa tut Rnrehoec Jykusbrh"; srand 0; 0.upto(999) {|i|
x = rand(23); str[x,2] = str[x,2].reverse! }; puts str



Hal
Hmm, I wonder why it does not work in Ruby 1.6.8, it prints

R etJrbrhnotc uhaaku esy

Is it because rand() differs so much in 1.8?

Gennady.
 
H

Hal Fulton

Gennady said:
str = "aa tut Rnrehoec Jykusbrh"; srand 0; 0.upto(999) {|i|
x = rand(23); str[x,2] = str[x,2].reverse! }; puts str

Hal
Hmm, I wonder why it does not work in Ruby 1.6.8, it prints

R etJrbrhnotc uhaaku esy

Is it because rand() differs so much in 1.8?

Yes, there was a change in the PRNG.

We discovered that when I first posted this -- you can search the
archives for "Rnrehoec". :)


Hal
 
S

Simon Strandgaard


Very entertaining! Are all these yours? If you are collecting
them from other people, you may add mine if you wish:

str = "aa tut Rnrehoec Jykusbrh"; srand 0; 0.upto(999) {|i|
x = rand(23); str[x,2] = str[x,2].reverse! }; puts str

I have just made my first signature

"J t ycuahR ksneuhetorbar".scan(/#{'(.)'*6}/).transpose.join
#=> "Just another Ruby hacker"

You are also welcome to add that sig too.. ;-)
 
G

Gennady

Hal said:
Gennady said:
str = "aa tut Rnrehoec Jykusbrh"; srand 0; 0.upto(999) {|i|
x = rand(23); str[x,2] = str[x,2].reverse! }; puts str

Hal
Hmm, I wonder why it does not work in Ruby 1.6.8, it prints

R etJrbrhnotc uhaaku esy

Is it because rand() differs so much in 1.8?


Yes, there was a change in the PRNG.

We discovered that when I first posted this -- you can search the
archives for "Rnrehoec". :)


Hal

Thank you, I found it.
Gennady.
 
S

Simon Strandgaard

I have just made my first signature

"J t ycuahR ksneuhetorbar".scan(/#{'(.)'*6}/).transpose.join
#=> "Just another Ruby hacker"

You are also welcome to add that sig too.. ;-)

I managed to make it even more opfuscated

('J t '<<'rabrotehuensk Rhaucy'.reverse).scan(/#{'(.)'*6}/).transpose.join
#=> "Just another Ruby hacker"

BTW: what does 'rabrotehuensk Rhaucy' mean ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top