免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 13080 | 回复: 12
打印 上一主题 下一主题

Perl实现花生壳DDNS客户端[2013/01/03更新] [复制链接]

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-01-03 17:32 |只看该作者 |倒序浏览
参考@coolend兄的帖子:http://bbs.chinaunix.net/thread-1825007-1-1.html
修正了64位系统下Perl的兼容性问题
修正了最后没有confirm的问题(花生壳协议更新)
修正了一定几率提交失败的问题(花生壳的文档里加密串ror没有提到的一个暗雷)
打算用它结合树莓派搭建一个git服务器

有花生壳的朋友可以试试。
  1. #!/usr/bin/perl

  2. use strict;
  3. use IO::Socket::INET;
  4. use MIME::Base64 qw(encode_base64 decode_base64);
  5. use Digest::HMAC_MD5 qw(hmac_md5);
  6. my $serverip = "ph051.oray.net";
  7. my $port = '6060';

  8. ###  登录用户名和密码
  9. my $user = '花生壳账户';
  10. my $pass =  '密码';
  11. my $domain ='花生壳域名.xicp.net';



  12. my $sock = IO::Socket::INET->new(
  13.     PeerAddr => $serverip,
  14.     PeerPort => $port,
  15.     Proto    => 'tcp',
  16. ) or die "ERR: unable to connect to server $! \n";

  17. my $msg;
  18. $sock->recv($msg,128);
  19. die "ERR: server not response ! \n" if (! $msg);
  20. print $msg;

  21. ## 发送验证请求
  22. print $sock "auth router6\n";
  23. $sock->recv($msg,128);
  24. print $msg;

  25. ## BASE64 解码
  26. $msg =~ s/^\d+\s+//;
  27. my $reply = decode_base64($msg);

  28. print "Reply message content is: ",unpack("H*",$reply),"\n";

  29. ## 服务器时间是挑战串的第六字节后的4个字节
  30. my $stime = substr($reply,6,4);
  31. my $tm_stime = unpack("H*",$stime);
  32. $tm_stime =~ s/^(\w{2})(\w{2})(\w{2})(\w{2})$/$4$3$2$1/;
  33. $tm_stime = hex($tm_stime);

  34. ## 打印下服务器的时间,便于调试
  35. print "Server time is $tm_stime, ",&timenow($tm_stime),"\n";

  36. ### 以下信息从 “笑行天下” 的 DDNS代码中借用的
  37. my $client_ID = "0x26A0";   # 客户端ID
  38. my $client_VER = "0x9899"; # 客户端版本
  39. my $auth_KEY = "0x1E0808B7"; # 嵌入认证密码

  40. ### 客户端信息为客户端ID+版本号,共4字节
  41. my $client_info = ((hex($client_ID) & 0xFFFF) << 16) | (hex($client_VER) & 0xFFFF);

  42. ## 转换为16进制
  43. $client_info = sprintf ("%x",$client_info);
  44. $client_info =~ s/^(\w{2})(\w{2})(\w{2})(\w{2})$/$4$3$2$1/;

  45. print "Client INFO: $client_info\n";
  46. my $auth_key = hex($auth_KEY);
  47. ## 嵌入认证码与时间的取反进行或运算后循环右移
  48. $tm_stime = $tm_stime | (~$auth_key)&0xFFFFFFFF;
  49. printf ("%032b \n",$tm_stime);
  50. print "Positive: $tm_stime\n";
  51. ### 右移位数是用服务器时间整除30后的余数
  52. my $mv = $tm_stime % 30;
  53. print "Original Movebit: $mv\n";
  54. $mv+=2 if $mv>16;  ####暗雷
  55. print "Adjusted Movebit: $mv\n";
  56. my $auth_enc=ror($tm_stime,($mv),32);
  57. $auth_enc &= 0xFFFFFFFF;
  58. printf ("%032b\n",$auth_enc);
  59. $auth_enc &= 0xFFFFFFFF;
  60. $auth_enc = sprintf ("%x",$auth_enc);
  61. $auth_enc =~ s/^(\w{2})(\w{2})(\w{2})(\w{2})$/$2$1$4$3/;
  62. print "AUTH_ENC: $auth_enc\n";

  63. ## 加密串
  64. my $enc_str = unpack("H*",hmac_md5($pass, $reply));
  65. print "ENC STR: $enc_str\n";

  66. my $header = pack("H*","$auth_enc$client_info$enc_str");
  67. print "HEADER: " . unpack("H*",$header) , " LEN: " , length($header),"\n";

  68. ## 生成回应串用BASE64编码
  69. my $lines = join('',$user,' ',$header);
  70. my $base64 = encode_base64 $lines;
  71. print "Send BASE64: $base64\n";

  72. ### 发送给服务端
  73. print $sock "$base64\n";
  74. $sock->recv($msg,128);
  75. print $msg;

  76. ### 注册域名
  77. print $sock "regi a $domain\n";
  78. $sock->recv($msg,128);
  79. print $msg;
  80. ### 确认
  81. print $sock "cnfm\n";
  82. $sock->recv($msg,128);
  83. print $msg;


  84. ## 退出
  85. print $sock "quit\n";

  86. $sock->shutdown(1);
  87. $sock->close();

  88. sub rol { return ($_[0]<<$_[1] | $_[0]>>($_[2]-$_[1])) & (2**$_[2]-1); }
  89. sub ror { return ($_[0]>>$_[1] | $_[0]<<($_[2]-$_[1])) & (2**$_[2]-1); }
  90. sub timenow {
  91.     my $tm = time();
  92.     my ($sec,$min,$hur,$day,$mon,$year) = (localtime($tm))[0,1,2,3,4,5];
  93.     $year += 1900; ++ $mon ;
  94.     return sprintf ("%02u-%02u-%02u %02u:%02u:%02u",$year,$mon,$day,$hur,$min,$sec);
  95. }
复制代码

评分

参与人数 1可用积分 +6 收起 理由
send_linux + 6 感谢原创分享:)

查看全部评分

论坛徽章:
1
未羊
日期:2014-09-08 22:47:27
2 [报告]
发表于 2013-01-04 09:29 |只看该作者
不错,学习了。

论坛徽章:
0
3 [报告]
发表于 2013-01-04 12:29 |只看该作者
谢谢 有空试试 鼓励原创

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2013-01-04 21:34 |只看该作者
能稍微模块化一下就更好了。

论坛徽章:
3
CU大牛徽章
日期:2013-03-13 15:29:07CU大牛徽章
日期:2013-03-13 15:29:49CU大牛徽章
日期:2013-03-13 15:30:19
5 [报告]
发表于 2013-01-08 15:53 |只看该作者
本帖最后由 fengyun530 于 2013-01-08 15:53 编辑

树莓派的机器性能对于一个20几人的团队操作的情况下,其内存性能能承受得住吗?

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
6 [报告]
发表于 2013-01-08 16:11 |只看该作者
回复 5# fengyun530

512 内存的机器,我不清楚,应该不行吧.我只是把它当个人使用的玩具而已.
你有20个人的团队还是正正经经的投资一个靠谱的设备,多考虑备份容灾
   

论坛徽章:
0
7 [报告]
发表于 2013-01-09 17:07 |只看该作者
本帖最后由 dingonet 于 2013-01-09 17:12 编辑

花生壳才那么麻烦的吧?看看3322.org的就简单很多了..
lynx -mime_header -auth=UserNameassword 'http://members.3322.net/dyndns/update?system=dyndns&hostname=domainname'

论坛徽章:
0
8 [报告]
发表于 2013-01-24 14:39 |只看该作者
ttcn_cu 发表于 2013-01-03 17:32
参考@coolend兄的帖子:http://bbs.chinaunix.net/thread-1825007-1-1.html
修正了64位系统下Perl的兼容性 ...


呵呵~~~ 想不到2年前的帖子还有人关注

花生壳的协议的确搞的太复杂了,BS一个... 之前用perl来实现主要是因为它提供的二进制的客户端太难用了,不过目前官网已经提供C的源代码了

另外有个地方需要注意:

客户端发送 auth router6 命令后,服务器端可能返回  536 Should Redirection To <phddns60std.oray.net> 这样的重定向信息(针对花生壳的付费用户),
需重新和新的服务器建立连接,否则后面的命令将无效。

LZ打算用RPI建GIT服务器? 推荐使用 gitolite(perl写的),偶们公司开始用的gitosis(基于python),后来换成了gitolite,很好用!

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
9 [报告]
发表于 2013-01-24 22:42 |只看该作者
回复 8# coolend


    感谢你提供代码!我也是编一个binary没编过去才想到搜perl代码的,没想到一搜就搜到CU了。我现在临时用GitStack(在Windows笔记本上装的)和GitLab。等有了想法再试试Git on Perl,应该可以写出一些提高效率的插件 吼吼。

论坛徽章:
0
10 [报告]
发表于 2013-01-26 23:39 |只看该作者
不错哦,DDNS在系统运维中用处很多的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP