freebsd 使用 Ntpdate 和 Ntpd 自动更新系统时间

由于某些原因,系统时间有时候不对了.
freebsd 如何同步时间.

  1. 手动同步:
ntpdate -b pool.ntp.org

几秒钟后, 时间就同步了.

  1. 启动系统 Ntpd 服务, 自动同步:
    编辑系统的文件: /etc/ntpd.conf
server pool.ntp.org
driftfile /etc/ntp.drift
logfile /var/log/ntpd.log

然后编辑: /etc/rc.conf
加入一行:

ntpd_enable="YES"
ntpdate_enable="YES"

启动ntpd 服务:

service ntpd start

参考:
1. http://www.surlyjake.com/blog/2008/11/17/freebsd-time-updates-with-ntpdate-and-ntpd/
1. https://www.cyberciti.biz/tips/freebsd-timeclock-synchronization-with-ntp-server.html

发表在 其他分类 | 留下评论

Linux 下如何保存并恢复 firefox 的设置

要自动化firefox的一些操作, 除了 firefox 的 一些命令行参数: http://kb.mozillazine.org/Command_line_arguments 外, 可以修改一份 firefox 的设置并保存, 然后在新的机器上,只需要先恢复设置, 再启动 firefox.

firefox 的设置在一个叫 profile 的 文件夹中. 文件夹位置在这里:
http://kb.mozillazine.org/Profile_folder

只需要保存这个目录, 然后复制到新机器的相同位置即可.

发表在 其他分类 | 留下评论

Delphi/c++builder 中出现 “float operation exception”

编译好的 dll 在 c++ builder 64 位中调用,出现 “float operation exception”.

尝试了 32位, 没有问题.

尝试了纯console 的 c++ builder 程序, 也没有问题. 只有包含 vcl 的 c++ builder 程序才有问题.

让我感觉到可能是 vcl 改变了 runtime 的某种行为.

跟踪了代码, 异常发生在这一行:
https://github.com/v8/v8/blob/3.20.17/src/conversions.h#L75

inline int FastD2I(double x) {
  return static_cast<int>(x);
}

当 x 大于 int 的 max 值时,问题出现.

虽然这种转换会导致溢出, 但是怎么会引发异常呢?

然后找到:
https://www.opengl.org/discussion_boards/showthread.php/156817-Disabling-Floating-Point-Exceptions

看起来, opengl 也遇到相同的问题.

然后找到:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/c310909a-fe07-4a4e-92d7-be2e1dc81137/finding-cause-of-floating-point-invalid-operation?forum=vsdebug

最终找到了这篇文章:

Random and unexpected EXCEPTION_FLT_DIVIDE_BY_ZERO and EXCEPTION_FLT_INVALID__OPERATION

原来 cpu 在操作浮点数时有专门的 fpu 寄存器.

而浮点数如果出现溢出等情况时, 是否导致异常是由一个专门的寄存器 fpcw 控制.

在 windows 平台上, fpcw 的值默认是忽略浮点溢出的异常的.
但是有的程序可能会改变 fpcw 的值, 来引发异常.

解决方案: 执行自己的代码时, 恢复 fpcw 的默认值, 用完再回滚.

头文件:

#include "float.h"

获得当前 fpcw 的值:

int old_fpcw = _controlfp(0,0)

设置 fpcw 为 windows 上的默认值:

_controlfp(MCW_EM, MCW_EM);

用完后, 回滚到原始值:

_controlfp(old_fpcw, _MCW_DN | _MCW_EM |_MCW_RC  )

另外, 这里还有一篇文章介绍fpu 的工作方式:
http://www.website.masmforum.com/tutorials/fptute/fpuchap1.htm

发表在 其他分类 | 留下评论

如何编译 google chrome v8 引擎

谷歌 chrome v8 引擎可以嵌入到自己的 c++ 程序中. 一般可以把 v8 编译成 dll, 然后调用.
还可以把 v8 编译成静态库, 静态链接到自己的程序中. 要编译v8的源代码可不是件容易的事.
这里记录下步骤:

  1. Pure Windows 7 x64
  2. Install python 2.7
  3. Install git https://git-scm.com/, v8 needs git bash to compile. Then edit the C:\Users\neil\.bashrc file:
export DEPOT_TOOLS_WIN_TOOLCHAIN=0
  1. Install VS2013, Express edition is ok. Edit Windows Registry:
    HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\12.0.
    Crate a String value: InstallDir, value is: C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\
    If you already have the value there, just ignore this step.
  2. If you don’t have this file: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat, copy one.
  3. Install VS2015, Express edition is ok.
  4. Install Windows 10 sdk: https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk
  5. Install google depot_tools https://www.chromium.org/developers/how-tos/install-depot-tools
  6. Open git-bash, get v8 source code:
fetch v8
  1. Generate vs 2015 project, static lib without snapshot, release edition:
cd v8
gn gen out-release/Default --args="v8_static_library=true is_component_build=false v8_use_external_startup_data=false v8_use_snapshot=false is_debug=false" --ide=vs2015

注意:
1. 第 4 步, 可能是因为 VS2013 express 版有点残, 如果你是pro 或者 ultimate版 可能不需要.
2. 第 8 步, 需要从 google 同步很多工具, 在中国, 你懂得.
3. 第 10 步, 个的参数是生成静态库. 不加,就是动态库. 要查看所有可用参数: “gn args –list” for available build arguments.

refs:
1. https://www.chromium.org/developers/how-tos/install-depot-tools
2. https://v8project.blogspot.com/2015/09/custom-startup-snapshots.html
3. https://chromium.googlesource.com/chromium/src/tools/gn/+/HEAD/docs/reference.md
4. https://stackoverflow.com/questions/38674676/building-and-linking-v8-in-visual-studio

发表在 其他分类 | 留下评论

mosh 使用(二)

在 ubuntu 上运行 mosh 的客户端, 出现以下错误:

The locale requested by LC_CTYPE=UTF-8 isn't available here.
Running `locale-gen UTF-8' may be necessary.

The locale requested by LC_CTYPE=UTF-8 isn't available here.
Running `locale-gen UTF-8' may be necessary.

mosh-server needs a UTF-8 native locale to run.

Unfortunately, the local environment (LC_CTYPE=UTF-8) specifies
the character set "US-ASCII",

The client-supplied environment (LC_CTYPE=UTF-8) specifies
the character set "US-ASCII".

locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=
LANGUAGE=
LC_CTYPE=UTF-8
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
Connection to 128.199.. closed.
/usr/local/bin/mosh: Did not find mosh server startup message.

在~/.bashrc添加一行:

export LC_ALL="en_US.UTF-8"

退出 bash, 再次进入, 出现以下警告:

-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory

我们可以通过运行 locale -a 查看系统当前支持的locale定义

我们通过运行

localedef -v -c -i en_US -f UTF-8 en_US.UTF-8

生成相应的locale配置文件。之后系统就不会报错了。

发表在 linux | 留下评论

solaris 上安装 git

今天要在solaris上安装git。
记录一下步骤:

pkgadd -d http://get.opencsw.org/now
/opt/csw/bin/pkgutil -U
/opt/csw/bin/pkgutil -y -i git 
/usr/sbin/pkgchk -L CSWgit # list files

https://www.opencsw.org/package/git/

发表在 系统编程 | 留下评论

gentoo linux 安装软件

gentoo linux 使用 emerge 安装 软件。

更新软件包信息:

emerge  --sync

搜索软件包:

emerge  --search   netcat

安装软件:

emerge   curl

如果安装软件遇到如下错误:

# emerge    net-analyzer/openbsd-netcat

 * IMPORTANT: 11 news items need reading for repository 'gentoo'.
 * Use eselect news read to view new items.

Calculating dependencies... done!
[ebuild   R   ~] net-analyzer/openbsd-netcat-1.105-r1 

The following keyword changes are necessary to proceed:
 (see "package.accept_keywords" in the portage(5) man page for more details)
# required by net-analyzer/openbsd-netcat (argument)
=net-analyzer/openbsd-netcat-1.105-r1 ~amd64

Use --autounmask-write to write changes to config files (honoring
CONFIG_PROTECT). Carefully examine the list of proposed changes,
paying special attention to mask or keyword changes that may expose
experimental or unstable packages.

尝试这样:

 ACCEPT_KEYWORDS="~amd64"   emerge  net-analyzer/openbsd-netcat
发表在 linux | 留下评论

使用java keytool 查看,添加,删除 jks 文件

jks 是 java 的 key store 文件格式. java 提供 keytool 工具操作jks.
keytool 是随 jre 发布的工具. 所以只要你安装了 jre 就有这个工具.
在windows上,是keytool.exe. 在Lunix上,是 keytool

jks 类似于 pfx(p12) 文件, 有密码加密, 可以保存多可key 或者证书等等. key 或者 证书被称为一个 entry, 每个entry有个别名(alias). 操作时需要制定别名.

list

查看 jks 的内容:

keytool -list  -keystore  publickeys.jks     -storepass mypassword

keytool -list  -keystore  privatekeys.jks   -storepass mypassword

keytool 还可以操作pfx 文件.
比如:

keytool -list  -keystore  PartyB.pfx  -storetype pkcs12  -storepass ExampleB  -v 

import

添加证书到 jks 中:

keytool  -importcert  -keystore publickeys.jks  -storepass  mypassword  -alias partyb  -file PartyB.cer

添加pfx 包含key和证书到 jks 中:

keytool  -importkeystore  -srcstoretype PKCS12 -srckeystore PartyB.pfx  -srcalias  1   -srcstorepass ExampleB   -destkeystore  privatekeys.jks  -deststorepass secrets  -destalias  partyb -destkeypass ExampleB

注意上面的 -srcalias 1, 指的是 pfx 文件中需要导入到 jks 中的证书的 别名. 如何查看到这个别名呢:

用上面的 list 命令可以查看到 pfx 里面的 alias:

keytool -list  -keystore  PartyB.pfx  -storetype pkcs12  -storepass ExampleB  -v   | grep "Alias"

delete

删除 jks 中的 证书或key


keytool -delete -keystore publickeys.jks -storepass mypassword -alias partyb keytool -delete -keystore privatekeys.jks -storepass mypassword -alias partyb
发表在 其他分类 | 留下评论

mosh 的安装和使用

ssh 的服务器如果延迟比较大的话, 还是比较痛苦的.
今天发现了这个东西: mosh

http://scm.zoomquiet.io/data/20131104091538/index.html
http://www.zfanw.com/blog/mosh.html

它是为了解决两个问题:

  1. 线路不稳定, 丢包率高.
  2. 线路延迟大, 操作延迟大.

简单的讲, 它使用普通的ssh协议认证, 然后传输使用udp协议.

使用udp协议的好处是不用总是保持连接, 用来解决第一个问题, 就是高丢包率. 就算丢包,也不会断,因为本来就是 udp , 没有连接.

为了处理延迟大的问题, 它在客户端做了优化, 包括输入回显预测机制,让你感觉到输入流畅了. 以及打包及拆包发送等等. 实测效果比较流畅.大有改观.

目前的缺陷, 就是只支持交互式shell环境, 不支持X转发,和端口转发等.

简单说一下安装方法.

  1. 安装服务端.

服务端已经支持了几乎所有的平台. 安装也很简单:

https://mosh.mit.edu/#getting

apt-get install mosh

服务端默认使用 udp 60001 端口传输, 所以可能需要你打开防火墙端口:

iptables -I INPUT -p udp --dport 60001 -j ACCEPT
  1. 安装客户端.
    如果是linux, 也使用同样的命令安装:
apt-get install mosh

我是windows, 官方客户端只支持cygwin. 所以要先安装cygwin.

mosh已经进入cygwin的仓库, 但是默认没有安装.

在cygwin安装时, 需要搜索添加mosh.

如果已经安装过cygwin了, 再次运行安装程序, 然后在安装时搜索找到mosh 安装即可.

mosh 只能在 纯的 utf-8 环境下工作. 所以在运行 mosh之前, 要改cygwin的语言.

找到 cygwin的 C:\cygwin64\home\neil.bashrc 文件.

在文件末尾加入如下两行.

export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
  1. 使用方法.

启动cygwin的shell.

直接输入命令:

mosh  root@myserver.com

如果ssh的端口改了.

mosh -ssh="ssh -p 1234"  root@myserver.com

更新:

今天发现有官方的 chrome 插件 客户端. 可以在浏览器里直接连接vps了.
https://chrome.google.com/webstore/detail/mosh/ooiklbnjmhbcgemelgfhaeaocllobloj

发表在 linux | 留下评论

Mac和 iOS 下的对称和非对称加密算法的使用

分享在Mac 和 iOS 上使用到的对称和非对称加密算法. 包括RSA,DSA, AES, DES, 3DES 和 blowfish 等等.
因为要实现ssh协议, 所以用到了这些算法, 这些算法在mac和ios上的接口比较难用, 我在这折腾了好长时间, 这里分享出来, 希望对大家有帮助.
(这里不提 openssl 在 apple 上的接口了)

主要参考了apple的文档:

Cryptographic Services Guide

Apple Encrypting and Hashing Data

先大致概括一下整体情况:
基本上这两个平台上的加密解密都和 keychain service 密不可分. keychain是mac和ios上用来保存证书,密码,key 等等敏感信息的存储区. 有专门的api访问这些接口. 有时候我们为了获得一个 key 的实例,必须想办法把数据导入到keychain中,然后才能通过keychain获得一个key的实例. 后面再说.

在mac 上, 有三个方式实现加密解密签名服务:

  1. Security Transforms API —a Core-Foundation-level API that provides support for signing and verifying, symmetric cryptography, and Base64 encoding and decoding.
    是 CoreFoundation 级别的api, 提供了, 最全的功能和算法支持. 包括对称,非对称算法. 实现加密,签名功能. 但遗憾的是这个接口只在mac上有效. iOS上没有. 但有些功能必须要用到, 所以要实现跨平台的代码,需要一些补丁.

  2. Common Crypto—a C-level API that can perform most symmetric encryption and decryption tasks
    这是一个 C 风格的接口. 好消息是它在mac和ios上都有, 可以跨平台. 但坏消息是, 它只包含了, 对称加密算法, 却没有非对称算法. 因此只能加密解密,而不能签名和验证. 其实之前 Apple上还有一个 ComonCryptoRSA 模块, 但后来不知为何消失了.

  3. CDSA/CSSM —a legacy API that should be used only to perform tasks not supported by the other two APIs, such as asymmetric encryption
    这个名字比较吓人, Common Data Security Architecture (CDSA) 通用数据安全架构. 很奇怪,它被apple接受后不久, 就被废弃了. 现在已经不建议使用了. 所以就不提它了.

在 iOS 上, 基本上有两种方式:

  1. Common Crypto. 这个在上面已经说过了. 对称算法接口.

  2. 使用系统提供的特有api实现加密,解密, 签名和验证:

系统提供了下面4个函数:

SecKeyEncrypt—encrypts a block of data using the specified key.

SecKeyDecrypt—decrypts a block of data using the specified key.

SecKeyRawSign—signs a block of data using the specified key.

SecKeyRawVerify—verifies a signature against a block of data and a specified key.

基于上面的分析, 我们秉着尽可能减少代码重复, 跨平台开发的原则: 对称算法就使用 “Common Crypto” 模块了. 因为两个平台都有. 而非对称则需要分别实现了.

下面详细分享一些细节:

一, 非对称加密算法, 签名和验证.(RSA/DSA signature and verity)

这需要在两个平台独立开发.

  1. Mac 平台.

在 mac 平台上, 我们使用它的 Security Transforms API.

参考这里: Security Transforms Programming Guide-Signing and Verifying

上面有很好的 代码 片段. 需要注意的是如何把 RSA 的参数 变成 api 需要的 SecKeyRef 对象.

这是它的导入片段.

    params.keyUsage = NULL;
    params.keyAttributes = NULL;

    SecExternalItemType itemType = kSecItemTypeCertificate;
    SecExternalFormat externalFormat = kSecFormatPEMSequence;
    int flags = 0;

 oserr = SecItemImport(cfdataprivatekey,
        NULL, // filename or extension
        &externalFormat, // See SecExternalFormat for details
        &itemType, // item type
        flags, // See SecItemImportExportFlags for details
        &params,
        NULL, // Don't import into a keychain
        &temparray);
    if (oserr) {
        fprintf(stderr, "SecItemImport failed (oserr=%d)\n", oserr);
        CFShow(temparray);
        exit(-1);
    }

    privatekey = (SecKeyRef)CFArrayGetValueAtIndex(temparray, 0);

这里是为了创建 SecKeyRef 实例. 通过 SecItemImport 把数据导入.变成SecKeyRef实例. 数据放在 cfdataprivatekey 中. 这个数据必须是 Pem格式的证书. 因为这个case下需要私钥, 所以这个证书需要包含私钥, 都是pem格式.

这里特别介绍一下, 如何从ssh 的公钥格式导入. 以RSA为例, RSA的公钥其实是一个底数e, 和一个大整数 m ,

e = [int32(len), bytes(value)]
m = [int32(len), bytes(value)]

e 和 m 的结构一样. 先是4个字节的长度, 然后紧跟上字节序列. len是 大端在前的, 跟通常的小端是有区别的.
完整的机构大概是这个样子的:

Binary = [0x00, 0x00, 0x00, 0x07, 'ssh-rsa', e, m]

keydata = 'ssh-rsa' + Base64Encode(Binary)

这个keydata 就可以用来构建上面用到的参数cfdataprivatekey了.

对于DSA, 结构跟上面类似:

p = [int32(len), bytes(value)]
q = [int32(len), bytes(value)]
g = [int32(len), bytes(value)]
y = [int32(len), bytes(value)]


Binary = [0x00, 0x00, 0x00, 0x07, 'ssh-dss', p, q, g, y]

keydata = 'ssh-dss' + Base64Encode(Binary)

  1. 对于 iOS, 平台, 我们使用上面说的两个函数来签名和验证:
SecKeyRawSign—signs a block of data using the specified key.

SecKeyRawVerify—verifies a signature against a block of data and a specified key.

这两个函数要命的是都需要一个 SecKeyRef 参数, iOS 上还真没有直接的方式可以通过大整数直接创建 SecKeyRef的实例.

要么通过 keychain 读取. 或者通过 SecPKCS12Import() 函数导入 pkcs12 格式的包含私钥的证书, 然后获得 SecIdentityRef 实例. 然后再通过 SecIdentityCopyPrivateKey() 函数把其中的 私钥导出成 SecKeyRef实例.

OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data,
                                 SecIdentityRef *outIdentity,
                                 SecTrustRef *outTrust,
                                 CFStringRef keyPassword)
{
    OSStatus securityError = errSecSuccess;


    const void *keys[] =   { kSecImportExportPassphrase };
    const void *values[] = { keyPassword };
    CFDictionaryRef optionsDictionary = NULL;

    /* Create a dictionary containing the passphrase if one
       was specified.  Otherwise, create an empty dictionary. */
    optionsDictionary = CFDictionaryCreate(
                                                  NULL, keys,
                                                  values, (keyPassword ? 1 : 0),
                                                  NULL, NULL);  // 1

    CFArrayRef items = NULL;
    securityError = SecPKCS12Import(inPKCS12Data,
                                    optionsDictionary,
                                    &items);                    // 2


    //
    if (securityError == 0) {                                   // 3
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust,
                                                       kSecImportItemIdentity);
        CFRetain(tempIdentity);
        *outIdentity = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);

        CFRetain(tempTrust);
        *outTrust = (SecTrustRef)tempTrust;
    }

    if (optionsDictionary)                                      // 4
        CFRelease(optionsDictionary);

    if (items)
        CFRelease(items);

    return securityError;
}

另外一个方法是, 苹果官方给的示例代码, 强制拼凑 SecKeyRef示例.
这里有 SecKeyWrapper 的实例代码: SecKeyWrapper 的实例代码

并且可以在这里直接下载到 源码: SecKeyWrapper 源码

这个源码里面有很多 苹果写的例子. 非常好. 对剑使用这里面的代码实现.

二, 对于对称加密算法.
这个比较简单了, 我们直接使用 Common Crypto 模块. 在mac 和ios上可以跨平台.

请参考这里: Apple Common Crypto library

  1. 使用 CCCryptorCreate 或者 CCCryptorCreateWithMode 创建 CCCryptorRef 对象.
    然后不断的调用 CCCryptorUpdate. 进行加密/解密.
    最后调用:CCCryptorFinal. 获取最后一块加密方法.

建议使用 CCCryptorCreateWithMode 方法.因为它能指定更多的参数. 比如 加密算法的padding 和ciphermode.

最后再顺便分享一下Mac 和iOS上生成 密码学安全的随机数的方法: Generating Random Numbers

简单的来说. 在mac上, 可以通过 fopen 读取 /dev/random 设备获得密码学安全的随机数.

FILE *fp = fopen("/dev/random", "r");

if (!fp) {
    perror("randgetter");
    exit(-1);
}

uint64_t value = 0;
int i;
for (i=0; i<sizeof(value); i++) {
    value <<= 8;
    value |= fgetc(fp);
}

fclose(fp);

而在 iOS 上, 由于不能读取设备, 它提供了 专门的 方法: SecRandomCopyBytes , 用起来非常简单.

欢迎访问我的独立博客 https://blog.byneil.com

发表在 系统编程 | 留下评论