// NewSessionState takes the plugin args and returns a SessionState // returns State or error and returnCode: // 0 - ok // 2 - error when unmarshaling pluginArgs // 3 - cannot open error files func NewSessionState(pluginArgsMsg string, plugin Plugin, meta *PluginMeta) (*SessionState, error, int) { pluginArg := &Arg{} err := json.Unmarshal([]byte(pluginArgsMsg), pluginArg) if err != nil { return nil, err, 2 } // If no port was provided we let the OS select a port for us. // This is safe as address is returned in the Response and keep // alive prevents unattended plugins. if pluginArg.listenPort == "" { pluginArg.listenPort = "0" } // If no PingTimeoutDuration was provided we need to set it if pluginArg.PingTimeoutDuration == 0 { pluginArg.PingTimeoutDuration = PingTimeoutDurationDefault } // Generate random token for this session rb := make([]byte, 32) rand.Read(rb) rs := base64.URLEncoding.EncodeToString(rb) logger := &log.Logger{ Out: os.Stderr, Formatter: &simpleFormatter{}, Hooks: make(log.LevelHooks), Level: pluginArg.LogLevel, } var enc encoding.Encoder switch meta.RPCType { case JSONRPC: enc = encoding.NewJsonEncoder() case NativeRPC: enc = encoding.NewGobEncoder() case GRPC: enc = encoding.NewGobEncoder() //TODO(CDR): re-think once content-types is settled } ss := &SessionState{ Arg: pluginArg, Encoder: enc, plugin: plugin, token: rs, killChan: make(chan int), logger: logger, } if !meta.Unsecure { key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err, 2 } encrypt := encrypter.New(nil, key) enc.SetEncrypter(encrypt) ss.Encrypter = encrypt ss.privateKey = key } return ss, nil, 0 }
// NewSessionState takes the plugin args and returns a SessionState // returns State or error and returnCode: // 0 - ok // 2 - error when unmarshaling pluginArgs // 3 - cannot open error files func NewSessionState(pluginArgsMsg string, plugin Plugin, meta *PluginMeta) (*SessionState, error, int) { pluginArg := &Arg{} err := json.Unmarshal([]byte(pluginArgsMsg), pluginArg) if err != nil { return nil, err, 2 } // If no port was provided we let the OS select a port for us. // This is safe as address is returned in the Response and keep // alive prevents unattended plugins. if pluginArg.listenPort == "" { pluginArg.listenPort = "0" } // If no PingTimeoutDuration was provided we need to set it if pluginArg.PingTimeoutDuration == 0 { pluginArg.PingTimeoutDuration = PingTimeoutDurationDefault } // Generate random token for this session rb := make([]byte, 32) rand.Read(rb) rs := base64.URLEncoding.EncodeToString(rb) // Initialize a logger based on PluginLogPath truncOrAppend := os.O_TRUNC // truncate log file explicitly given by user // Empty or /tmp means use default tmp log (needs to be removed post-aAtruncOrAppendpha) if pluginArg.PluginLogPath == "" || pluginArg.PluginLogPath == "/tmp" { if runtime.GOOS == "windows" { pluginArg.PluginLogPath = `c:\TEMP\snap_plugin.log` } else { pluginArg.PluginLogPath = "/tmp/snap_plugin.log" } truncOrAppend = os.O_APPEND } lf, err := os.OpenFile(pluginArg.PluginLogPath, os.O_WRONLY|os.O_CREATE|truncOrAppend, 0666) if err != nil { return nil, errors.New(fmt.Sprintf("error opening log file: %v", err)), 3 } logger := log.New(lf, ">>>", log.Ldate|log.Ltime) var enc encoding.Encoder switch meta.RPCType { case JSONRPC: enc = encoding.NewJsonEncoder() case NativeRPC: enc = encoding.NewGobEncoder() } ss := &SessionState{ Arg: pluginArg, Encoder: enc, plugin: plugin, token: rs, killChan: make(chan int), logger: logger, } if !meta.Unsecure { key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err, 2 } encrypt := encrypter.New(nil, key) enc.SetEncrypter(encrypt) ss.Encrypter = encrypt ss.privateKey = key } return ss, nil, 0 }