PKCS12_parse: unsupported - when running a ruby application as a service on the server - ruby

In my ruby application, I am creating Apple wallet passes.
The application actually works well, but when I try to start it as a service (/etc/systemd/system), it is failing.
I can see that almost everything is working, but it fails when I want to parse the p12 certificate.
My function to sign the manifest file
def sign_manifest(serial_number)
temporary_path = "./passes/#{CUSTOMER}_#{serial_number}"
certificate_path = "./certs/Zertifikate.p12"
wwdr_path = "./certs/WWDR.pem"
manifest_path = "./passes/#{CUSTOMER}_#{serial_number}/manifest.json"
puts "Signing the manifest"
# Import the certificates
p12_certificate = OpenSSL::PKCS12::new(File.read(certificate_path), "")
wwdr_certificate = OpenSSL::X509::Certificate.new(File.read(wwdr_path))
# Sign the data
flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED
signed = OpenSSL::PKCS7::sign(p12_certificate.certificate, p12_certificate.key, File.read(manifest_path), [wwdr_certificate], flag)
# Create an output path for the signed data
signature_url = temporary_path + "/signature"
# Write out the data
File.open(signature_url, "w") do |f|
f.syswrite signed.to_der
end
end
Manually start with the command line
When I start the application manually with the command
ruby passGenerator.rb -p 20001 -o 0.0.0.0
on my server, it is working well, no issues.
Start as a service
The service itself looks like:
# wallet.service
[Unit]
Description = Apple Wallet Pass Generator
After = network.target
[Service]
WorkingDirectory = /var/www/html/passGenerator
ExecStart = ruby /var/www/html/passGenerator/passGenerator.rb -p 20001 -o 0.0.0.0
[Install]
WantedBy = multi-user.target
and start it with:
systemctl start wallet
I can start the service, and the server is running, but as soon as I want to create a new pass and come to this function, it crashes with the error:
PKCS12_parse: unsupported in the line of
p12_certificate = OpenSSL::PKCS12::new(File.read(certificate_path), "“)
(In the code snippet line 9)
I first thought about the relative paths, but everything else works with the relative paths.
Can anybody explain why that is happening?

Related

Async::WebSocket unable to connect on Windows 10

I'm attempting to write a Ruby SDK for the Stream Deck, a product that is basically a fancy hardware AutoHotkey allowing the user to program buttons with customized icons that do whatever they please, including making directories to achieve an unlimited amount of buttons organized to their liking. It has a language-agnostic API wherein it runs your script or compiled app with the arguments -port, -pluginUUID, -registerEvent, and -info. It runs a websocket on localhost at the port specified in the args, and on opening a connection you are to send a JSON string with your event and UUID as specified in the args.
I've gotten Ruby 3.0.5 running within a plugin with console output, but I'm having trouble getting it to talk to the websocket. I'm using SDPL to load my script (intended only for testing):
#!/esr/bin/env ruby
require "json"
require "async/websocket/client"
require "async/http/endpoint"
include Async
include Async::HTTP
# Parse arguments
_, port, _, UUID, _, REGISTER_EVENT, _, *info = ARGV
PORT = port.to_i
INFO = JSON.parse info.join(" ")
# Debug output prints properly
p PORT
p UUID
p REGISTER_EVENT
p INFO
Async do |task|
WebSocket::Client.connect(Endpoint.parse "http://localhost:#{PORT}") do |ws|
ws.write({ event: REGISTER_EVENT, uuid: UUID }.to_json)
ws.flush
puts "Opened!"
while msg = ws.read
puts "Message:"
puts msg
end
end
end
The arguments output as expected, then it hangs. If this code is run in WSL (with modifications to hardcode the port and an open plugin UUID), it talks to the Stream Deck as expected. Possible issue with the module on Windows 10? On RubyInstaller 3.1.2, the situation is even worse- it crashes with the following error:
0.0s warn: Async::Task [oid=0x280] [ec=0x294] [pid=32436] [2022-12-13 00:36:46 -0500]
| Task may have ended with unhandled exception.
| Errno::EBADF: Bad file descriptor
| → <internal:io> 63
| C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/io-event-1.1.4/lib/io/event/selector/select.rb 206

boto3 - base64 encoded lifecycle configuration produces instance failure

I am trying to set up lifecycle configurations for Sagemaker notebooks over the aws api via boto3. From the docs it reads that a base64 encoded string of the configuration has to be provided.
I am using the following code:
with open(lifecycleconfig.sh, 'rb') as fp:
file_content = fp.read()
config_string = base64.b64encode(file_content).decode('utf-8')
boto3.client('sagemaker').create_notebook_instance_lifecycle_config(
NotebookInstanceLifecycleConfigName='mylifecycleconfig1',
OnCreate=[
{
'Content': config_string
},
],
)
With some lifecycleconfig.sh:
#!/bin/bash
set -e
This creates a lifecycle configuration which shows up in the web interface and whose content is seemingly identical to creating a config by hand:
image.
However Notebooks using the lifecycle config created via boto3 will not start and the log file will show error:
/home/ec2-user/SageMaker/create_script.sh: line 2: $'\r': command not found
/home/ec2-user/SageMaker/create_script.sh: line 3: set: -
set: usage: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
Moreover, if I copy paste the content of the corrupted config and create a new config by hand, the new one will now also not start.
How do I have to encode a bash script for a working aws lifecycle configuration?
Found out that it is actually a Windows specific problem concerning the difference between open(..., 'rb').read() and open(..., 'r').read().encode('utf-8').
On my linux machine these two give the same result. On Windows however open(..., 'rb') gives stuff like \r\n for new lines, which appearantly can be comprehended by Amazon's web interface, but not the linux machine where the script gets deployed.
This is a os independent solution:
with open(lifecycleconfig.sh, 'r') as fp:
file_content = fp.read()
config_string = base64.b64encode(file_content.encode('utf-8')).decode('utf-8')

How to properly make an api request in python3 with base64 encoding

I'm trying to run a bash script at server creation on vultr.com through the API using Python3
I'm not sure what I'm doing wrong. The server starts up but the script never runs.
The documentation states it has to be a base64 encoded string. I'm thinking I'm doing something wrong with the encoding.
Have any ideas?
import base64
import requests
key = 'redacted'
squid = '''#!/bin/bash
touch test'''
squid_encoded = base64.b64encode(squid.encode())
payload = {'DCID': 1, 'VPSPLANID': 29, 'OSID': 215, 'userdata': squid_encoded}
headers = {'API-Key': key}
def vult_api_call():
p = requests.post('https://api.vultr.com/v1/server/create', data=payload, headers=headers)
print(p.status_code)
print(p.text)
vult_api_call()
The cloud-init userdata scripts can be tricky to troubleshoot. Looking at your squid script, it is missing the #cloud-config header. Vultr has a similar example in their docs:
Run a script after the system boots.
#cloud-config
bootcmd:
- "/bin/echo sample > /root/my_file.txt"
</pre>
Support for this can vary by operating system though. I would recommend using Vultr's startup script feature instead of cloud-init, as it works for every operating system. These are referenced in the Vultr API spec with SCRIPTID.
Also note that "bootcmd:" will run every time the instance boots. There is also "runcmd:", but I have seen compatibility issues with it on some Ubuntu distros on Vultr.

How to resolve external domain names using MaraDNS in windows 7

I have installed maradns in windows 7 machine, I have configured it, It can able to handle internal requests, But not external ones
marac file
ipv4_bind_addresses = "127.0.0.1"
timestamp_type = 2
random_seed_file = "secret.txt"
csv2 = {}
csv2["myapp.com."] = "db.lan.txt"
upstream_servers = {} # Initialize dictionary variable
upstream_servers["."] = "8.8.8.8, 8.8.4.4"
db.lan.txt
private.% 192.168.1.21 ~
blog.% 192.168.1.16 ~
For external requests, its giving me the below error
C:\Program Files\maradns-2-0-06-win32>askmara.exe Agoogle.com.
# Querying the server with the IP 127.0.0.1
# Remote server said: REFUSED
# NS replies:
# AR replies:
For internal requests, Its working fine as below
C:\Program Files\maradns-2-0-06-win32>askmara.exe Aprivate.myapp.com.
# Querying the server with the IP 127.0.0.1
# Question: Aprivate.myapp.com.
private.myapp.com. +86400 a 192.168.1.21
# NS replies:
#myapp.com. +86400 ns synth-ip-7f000001.myapp.com.
# AR replies:
#synth-ip-7f000001.myapp.com. +86400 a 127.0.0.1
And when i start the server, I am getting a prompt with a warning as well
How to resolve this issue.
i had the same problem.. fixed it by replacing the latest version with the version 1.4..
after that the only i did was run the mkSecretTxt.exe to create the secret.txt file and configured the mararc file like this:
this is my current mararc file:
# Win32-specific MaraRC file; this makes a basic recursive DNS
# server.
hide_disclaimer = "YES"
ipv4_bind_addresses = "127.0.0.1"
recursive_acl = "127.0.0.1/8"
timestamp_type = 2
csv2 = {}
csv2["local.com."] = "db.lan.txt"
# This is insecure until the secret.txt file is edited
random_seed_file = "secret.txt"
upstream_servers = {}
upstream_servers["."] = "208.67.222.222,208.67.220.220"
db.lan.txt
% 192.168.1.33 ~
As you can see i've used the openDNS servers, if your still get the error try them as well.
http://www.opendns.com/support/article/105
cheers
For anyone following along with this, it seems the current solution as of MaraDNS > 2.0 is to use MaraDNS in conjunction with the included Deadwood recursive server to be able to handle both local and external resolution. I was able to get this working on my Windows 10 machine with the following configs...
Assume that the Windows machine's IP address is 192.168.1.2
In the MaraDNS mararc file:
ipv4_bind_addresses = "127.0.0.1"
timestamp_type = 2
random_seed_file = "secret.txt"
csv2 = {}
csv2["mylocalnet.com."] = "db.lan.txt"
In the db.lan.txt file:
% 192.168.1.XXX ~
And in the Deadwood dwood3rc.txt config file:
upstream_servers = {}
upstream_servers["."]="8.8.8.8, 8.8.4.4"
upstream_servers["mylocalnet.com."]="127.0.0.1"
bind_address="192.168.1.2"
recursive_acl = "127.0.0.1/16, 192.168.1.1/24"
# By default, for security reasons, Deadwood does not allow IPs in the
# 192.168.x.x, 172.[16-31].x.x, 10.x.x.x, 127.x.x.x, 169.254.x.x,
# 224.x.x.x, or 0.0.x.x range. If using Deadwood to resolve names
# on an internal network, uncomment the following line:
filter_rfc1918 = 0
You could potentially set up multiple machines to act as independent servers, but my config above was particular in that in enabled me to run both servers on the same machine. You can see that in the Deadwood config, I'm using Google's DNS servers to handle all upstream requests with the exception of mylocalnet.com. which gets forwarded to localhost and handled by MaraDNS.
From here, you just need to launch both programs and point DNS to 192.168.1.2. Should be good to go!

Sending an email from R using the sendmailR package

I am trying to send an email from R, using the sendmailR package. The code below works fine when I run it on my PC, and I recieve the email. However, when I run it with my macbook pro, it fails with the following error:
library(sendmailR)
from <- sprintf("<sendmailR#%s>", Sys.info()[4])
to <- "<myemail#gmail.com>"
subject <- "TEST"
sendmail(from, to, subject, body,
control=list(smtpServer="ASPMX.L.GOOGLE.COM"))
Error in socketConnection(host = server, port = port, blocking = TRUE) :
cannot open the connection
In addition: Warning message:
In socketConnection(host = server, port = port, blocking = TRUE) :
ASPMX.L.GOOGLE.COM:25 cannot be opened
Any ideas as to why this would work on a PC, but not a mac? I turned the firewall off on both machines.
Are you able to send email via the command-line?
So, first of all, fire up a Terminal and then
$ echo “Test 123” | mail -s “Test” user#domain.com
Look into /var/log/mail.log, or better use
$ tail -f /var/log/mail.log
in a different window while you send your email. If you see something like
... setting up TLS connection to smtp.gmail.com[xxx.xx.xxx.xxx]:587
... Trusted TLS connection established to smtp.gmail.com[xxx.xx.xxx.xxx]:587:\
TLSv1 with cipher RC4-MD5 (128/128 bits)
then you succeeded. Otherwise, it means you have to configure you mailing system. I use postfix with Gmail for two years now, and I never had have problem with it. Basically, you need to grab the Equifax certificates, Equifax_Secure_CA.pem from here: http://www.geotrust.com/resources/root-certificates/. (They were using Thawtee certificates before but they changed last year.) Then, assuming you used Gmail,
Create relay_password in /etc/postfix and put a single line like this (with your correct login and password):
smtp.gmail.com login#gmail.com:password
then in a Terminal,
$ sudo postmap /etc/postfix/relay_password
to update Postfix lookup table.
Add the certificates in /etc/postfix/certs, or any folder you like, then
$ sudo c_rehash /etc/postfix/certs/
(i.e., rehash the certificates with Openssl).
Edit /etc/postfix/main.cf so that it includes the following lines (adjust the paths if needed):
relayhost = smtp.gmail.com:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/relay_password
smtp_sasl_security_options = noanonymous
smtp_tls_security_level = may
smtp_tls_CApath = /etc/postfix/certs
smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache
smtp_tls_session_cache_timeout = 3600s
smtp_tls_loglevel = 1
tls_random_source = dev:/dev/urandom
Finally, just reload the Postfix process, with e.g.
$ sudo postfix reload
(a combination of start/stop works too).
You can choose a different port for the SMTP, e.g. 465.
It’s still possible to use SASL without TLS (the above steps are basically the same), but in both case the main problem is that your login informations are available in a plan text file... Also, should you want to use your MobileMe account, just replace the Gmail SMTP server with smtp.me.com.

Resources