資格情報マネージャ読み書きプログラムをNode.jsで作成する

VBA等のスクリプト系は、Windowsの資格情報マネージャに格納されてる情報を直接取得する事が出来ません。かといって、Web API等のアクセスに必要な情報を直書きしたり、そのままレジストリに書き込んで読み書きでは不安です。

そこで今回、Node.js + Keytar + nexeでexeを作成し、コマンドラインの標準出力でVBA側にパスワードを渡す手法を考えてみました。

※正直言って実用的じゃないので、素直に暗号化モジュール使って、暗号/複合を実装したほうがなんぼもマシだと思います

今回使用するモジュール

今回は、Node.jsにコマンドライン引数を渡して処理し、返り値をDOS窓の標準出力を取得する形で手に入れます。

ソースコード

Node.js側コード

"use strict"

//モジュールの読み込み
const fs = require('fs');
const keytar = require('keytar');
const commandLineArgs = require('command-line-args');

//コマンドラインオプションを構築
const optionDefinitions = [
  {
    name: 'userid',
    alias: 'u',
    type: String
  },
  {
    name: 'setpass',
    alias: 's',
    type: String
  },
  {
    name: 'getpass',
    alias: 'g',
    type: String
  }
];
const args = commandLineArgs(optionDefinitions);

//引数に応じて処理を分岐
var userid = args.userid;
if(userid == undefined){
  //User ID指定がないので処理を終了
  return 0;
}

//サービス名を構築する
var servicename = "kintone_" + userid;

//-gオプションの値を取得する
var tempargs = args.getpass;

if(tempargs == undefined){
  //getじゃないのでsetなのか判定
  tempargs = args.setpass;

  if(tempargs == undefined){
    //オプション指定がないので処理を終了
    return 0;
  }else{
    //パスワードセットの処理を実行
    setPassword(servicename,userid,tempargs,function(ret){
      console.log(ret);
      return ret;
    });
  }
}else{
  //パスワードゲットの処理を実行
  getPassword(servicename,userid,function (ret){
    console.log(ret);
    return ret;
  })
}

//パスワードを取得する処理
function getPassword(servicename,userid,callback){
  const secret = keytar.getPassword(servicename,userid);
  secret.then((result) => {
    return result;
  })
  .then(function(data) {
 
    callback(data);
    return data;
  })
}

//パスワードをセットする処理
function setPassword(servicename,userid,pass,callback){
  //パスワードを保存する
  keytar.setPassword(servicename,userid,pass);

  //処理完了
  callback(1);
  return 1;

}
  • optionDefinitionsにて、コマンドライン引数オプション-s-u-gの場合の処理を用意しています。
  • コマンドラインとして、node index.js -u ユーザID -s パスワードとすると、パスワードを資格情報マネージャにセットします。
  • コマンドラインとして、node index.js -u ユーザID -g ユーザIDとすると、パスワードを資格情報マネージャからゲットします。
  • -gの時の処理、-sの時の処理それぞれを条件分岐で作成します。
  • setPasswordでkeytarを使ってパスワードをセットします。
  • getPasswordでkeytarを使ってパスワードをゲットします。
  • keytar自体、非同期で実行されるので、callbackやthenなどを利用して値を取得後に標準出力で出すようにコードを記述する必要があります。
  • servicenameは、利用するウェブサービス等の名称と組み合わせる何か(例えばUser ID)で組み立てます。これを元に資格情報マネージャにセットしたり、取得したりします。

VBA側コード

Sub credmanexe()
    'WSHの用意
    Dim WSH, wExec, sCmd As String, Result As String
    Set WSH = CreateObject("WScript.Shell")

    //コマンドラインの組み立てと実行
    sCmd = ThisWorkbook.Path & "\creden.exe -u ユーザID -g ユーザID"
    Set wExec = WSH.Exec("%ComSpec% /c " & sCmd)
    
    //ステータスを見てループ
    Do While wExec.Status = 0
        DoEvents
    Loop
    
    //標準出力内容を取得してメッセージボックスで表示
    Result = wExec.StdOut.ReadAll
    MsgBox Result

    //終了処理
    Set wExec = Nothing
    Set WSH = Nothing

End Sub
  • WSHを利用してexecにてコマンドラインを実行しています(今回はとりあえずパスワードの取得の部分だけ)
  • StdOut.ReadAllにて標準出力(console.log())に出力された内容を取得しています。
  • コマンドプロンプトの画面はexecの場合、非表示に出来ません。しかし、Runの場合今度は標準出力を取得できません。
  • VBSを利用したコマンドプロンプト非表示のテクニックがあるので、こちらを利用すると尚良いでしょう。
  • パスワード取得とパスワードセットの2つのルーチンに対して、今回のコードを組み込んでおきます。

単一実行ファイルを作成する

Node.js 18よりSingle executable applicationsという機能が装備され、標準で単独実行ファイルが作成できるようになりました。結果pkgはプロジェクト終了となっています。よって、以下のエントリーの単一実行ファイルを作成するを参考に、Node18以降はexeファイルを作成することが可能です。

Puppeteerを使ってX(旧Twitter)へのポストを自動化する

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)