Jmeter throws error on Encryption - using Public Key - jmeter

I am currently working in a application where RSA Encryption is being used for Encrypting sensitive data. I have tried incorporating the standard encryption method but it is throwing errors. I have selected the language Groovy. Can someone throw light on whether i am doing it right?
import javax.crypto.Cipher
import java.security.KeyFactory
import java.security.spec.X509EncodedKeySpec
def publicKey = '5dy47yt7ty5ad283c0c4955f53csa24wse244wfrfafa34239rsgd89gfsg8342r93r98efae89fdf9983r9gjsdgnsgjkwt23r923r2r0943tf9sdg9d8gfsgf90sgsf89grw098tg09s90ig90g90s903r5244r517823rea8f8werf9842tf24tf42e0132saf9fg6f65afa43f12r103tf4040ryrw0e9rtqtwe0r9t04ty8842t03e9asfads0fgadg675'
def x509PublicKey = new X509EncodedKeySpec(publicKey.decodeBase64())
def keyFactory = KeyFactory.getInstance('RSA')
def key = keyFactory.generatePublic(x509Publickey)
def string2Encrypt = '("testinga#gmail.com|testingb#gmail.com").'
def encryptCipher = Cipher.getInstance('RSA')
encryptCipher.init(Cipher.ENCRYPT_MODE,key)
def secretMessage = string2Encrypt.getBytes('UTF-8')
def encryptedMessage = encryptCipher.doFinal(secretMessage)
def encodedMessage = encryptedMessage.encodedBase64().toString()
vars.put('encodedMessage',encodedMessage)
The Output Error i am getting
Response Code: 500
Response Message:javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: x509Publickey for class: Script4
SampleResult fields:
ContentType:
DataEncoding: null

You have:
def x509PublicKey
^ mind the capital K
and
def key = keyFactory.generatePublic(x509Publickey)
^ mind the lower-case k
in Groovy they're absolutely different beasts and case sensitivity matters a lot, choose one option and stick to it and "your" script will start working as expected (or at least this error will go away)
More information:
Apache Groovy - Syntax
Apache Groovy - Why and How You Should Use It

Related

Pyarrow basic auth: How to prevent `Stream is closed`?

I am new to Arrow Flight and pyarrow (v=6.0.1), and am trying to implement basic auth but I am always getting an error:
OSError: Stream is closed
I have created a minimal reproducing sample, by running the following two files sequentially (representing server and client respectively):
from typing import Dict, Union
from pyarrow.lib import tobytes
from pyarrow.flight import BasicAuth, FlightUnauthenticatedError, ServerAuthHandler, FlightServerBase
from pyarrow._flight import ServerAuthSender, ServerAuthReader
class ServerBasicAuthHandler(ServerAuthHandler):
def __init__(self, creds: Dict[str, str]):
self.creds = {user.encode(): pw.encode() for user, pw in creds.items()}
def authenticate(self, outgoing: ServerAuthSender, incoming: ServerAuthReader):
buf = incoming.read() # this line raises "OSError: Stream is closed"
auth = BasicAuth.deserialize(buf)
if auth.username not in self.creds:
raise FlightUnauthenticatedError("unknown user")
if self.creds[auth.username] != auth.password:
raise FlightUnauthenticatedError("wrong password")
outgoing.write(tobytes(auth.username))
def is_valid(self, token: bytes) -> Union[bytes, str]:
if not token:
raise FlightUnauthenticatedError("no basic auth provided")
if token not in self.creds:
raise FlightUnauthenticatedError("unknown user")
return token
service = FlightServerBase(
location=f"grpc://[::]:50051",
auth_handler=ServerBasicAuthHandler({"user": "pw"}),
)
service.serve()
from pyarrow.flight import FlightClient
client = FlightClient(location=f"grpc://localhost:50051")
client.authenticate_basic_token("user", "pw")
I basically copied the ServerAuthHandler implementation from their tests, so it is proven to work. However, I can't get it to work.
The error message Stream is closed hard to debug. I don't know where it comes from and I can't trace it to anywhere within the pyarrow implementation (neither Pythonside nor C++ side). I can't see where it comes from.
Any help or hints on how to prevent this error would be appreciated.
The example in the OP is mixing up two authentication implementations (which is indeed confusing). The "BasicAuth" object isn't actual HTTP basic authentication that the authenticate_basic_token method implements; this is because contributors have implemented a variety of authentication methods over the years. The actual test is as follows:
header_auth_server_middleware_factory = HeaderAuthServerMiddlewareFactory()
no_op_auth_handler = NoopAuthHandler()
def test_authenticate_basic_token():
"""Test authenticate_basic_token with bearer token and auth headers."""
with HeaderAuthFlightServer(auth_handler=no_op_auth_handler, middleware={
"auth": HeaderAuthServerMiddlewareFactory()
}) as server:
client = FlightClient(('localhost', server.port))
token_pair = client.authenticate_basic_token(b'test', b'password')
assert token_pair[0] == b'authorization'
assert token_pair[1] == b'Bearer token1234'
i.e. we're not using authenticate but rather a "middleware" to do the implementation. A full example looks as follows:
import base64
import pyarrow.flight as flight
class BasicAuthServerMiddlewareFactory(flight.ServerMiddlewareFactory):
def __init__(self, creds):
self.creds = creds
def start_call(self, info, headers):
token = None
for header in headers:
if header.lower() == "authorization":
token = headers[header]
break
if not token:
raise flight.FlightUnauthenticatedError("No credentials supplied")
values = token[0].split(' ', 1)
if values[0] == 'Basic':
decoded = base64.b64decode(values[1])
pair = decoded.decode("utf-8").split(':')
if pair[0] not in self.creds:
raise flight.FlightUnauthenticatedError("No credentials supplied")
if pair[1] != self.creds[pair[0]]:
raise flight.FlightUnauthenticatedError("No credentials supplied")
return BasicAuthServerMiddleware("BearerTokenValue")
raise flight.FlightUnauthenticatedError("No credentials supplied")
class BasicAuthServerMiddleware(flight.ServerMiddleware):
def __init__(self, token):
self.token = token
def sending_headers(self):
return {'authorization': f'Bearer {self.token}'}
class NoOpAuthHandler(flight.ServerAuthHandler):
def authenticate(self, outgoing, incoming):
pass
def is_valid(self, token):
return ""
with flight.FlightServerBase(auth_handler=NoOpAuthHandler(), middleware={
"basic": BasicAuthServerMiddlewareFactory({"test": "password"})
}) as server:
client = flight.connect(('localhost', server.port))
token_pair = client.authenticate_basic_token(b'test', b'password')
print(token_pair)
assert token_pair[0] == b'authorization'
assert token_pair[1] == b'Bearer BearerTokenValue'
I think it's simply due to this not being supported on Windows.
On closer inspection, the test that "proves it work" is being skipped in Windows. The comment refers to this issue. That issue has been fixed though (ostensibly); not anything as to why it wouldn't work with Stream is closed.

How to concatenate string and integer values in jmeter

I'm trying to concatenate string and integer values in JMeter as below
for(int i in 1..100){
def cloudItemId="cloudItemId"+i;
def deviceItemId="deviceItemId"+i;
}
but I'm getting this below error
Response message:Exception: groovy.lang.MissingMethodException: No signature of method:
java.lang.String.positive() is applicable for argument types: () values: []
Possible solutions: notify(), size(), tokenize()
How can Iconcatenate with cloudItemId/deviceItemId
I cannot reproduce your issue using latest JMeter 5.4.1 (you're supposed to be using the latest JMeter version just in case):
so pay attention to your syntax and suspicious entries in jmeter.log file.
You can also slightly refactor your code to use GStrings and make it more Groovy:
1.upto(100, { i ->
def cloudItemId = "cloudItemId$i"
def deviceItemId = "deviceItemId$i"
log.info('cloudItemId: ' + cloudItemId)
})
The issue is + sign is used for mathematic plus in integers and concatenation in Strings
You can concatenate using <<:
for(int i in 1..100){
def cloudItemId="cloudItemId" <<i;
log.info(cloudItemId.toString());
def deviceItemId="deviceItemId"<<i;
log.info(cloudItemId.toString());
}
Or call String.valueOf to concat Strings:
for(int i in 1..100){
def cloudItemId="cloudItemId" + String.valueOf(i);
log.info(cloudItemId);
def deviceItemId="deviceItemId"+ String.valueOf(i)
log.info(cloudItemId);
}

How do I use asyncio.sslproto.SSLProtocol?

I am trying to talk to an ElectrumX server using JSON-RPC over TLS, but through Tor (SOCKS proxy on localhost).
When running the following code, drain() in asyncio.streams is calling _drain_helper in SSLProtocol, which I don't know how to implement.
If I just make it a no-op, it seems to not work.
I know that the JSON-RPC server is working because I have tested with
echo -ne '{"id":0,"args":["3.0.2","1.1"],"method":"server.version"}\n' | socat stdio openssl-connect:songbird.bauerj.eu:50002,verify=0
My attempt at using TLS through SOCKS in Python with asyncio:
from asyncio.sslproto import SSLProtocol
import aiosocks
import asyncio
loop = None
class MySSLProtocol(SSLProtocol):
def __init__(otherself):
super().__init__(loop, None, False , None)
# app_proto context waiter
async def l(fut):
try:
socks4addr = aiosocks.Socks4Addr("127.0.0.1", 9050)
transport, protocol = await aiosocks.create_connection(MySSLProtocol, proxy=socks4addr, proxy_auth=None, dst=("songbird.bauerj.eu", 50002))
reader = asyncio.StreamReader()
reader.set_transport(transport)
writer = asyncio.StreamWriter(transport, protocol, reader, loop)
writer.write(b'{"id":0,"method":"server.version","args":["3.0.2", "1.1"]}\n')
await writer.drain()
print(await reader.readuntil(b"\n"))
fut.set_result("finished")
except BaseException as e:
fut.set_exception(e)
def f():
global loop
loop = asyncio.get_event_loop()
fut = asyncio.Future()
asyncio.ensure_future(l(fut))
loop.run_until_complete(fut)
print(fut.result())
loop.close()
f()
I am using aiosocks from master. Commit 932374c
asyncio.sslproto and SSLProtocol are part of asyncio private API.
You should never use the class directly or derive from it.
For working with SSL please pass normal protocol (derived from asyncio.Protocol) and ssl.SSLContext as ssl param into loop.create_connection() / loop.create_server().
I'm using it like so:
class HTTP(asyncio.Protocol):
def __init__(self, config: Config):
self.config = config
def data_received(self, data) -> None:
print(data)
class HTTPS:
def __new__(cls, config: Config):
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ssl_context.load_cert_chain(config.rsa_cert, config.rsa_key)
return asyncio.sslproto.SSLProtocol(
loop=asyncio.get_running_loop(),
app_protocol=HTTP(config),
sslcontext=ssl_context,
waiter=None,
server_side=True,
)
See mitm for working example. Not the way I would've chosen to use it, but the only way I could figure out. From my knowledge there is no way to upgrade an asyncio.Protocol to use SSL - you must create a new one.

Gatling Feeder Issue : No attribute name 'CSVFieldName' is defined issue

I am newbie for Gatling and trying to read some fields from CSV and use them in my gatling scenario but facing
No attribute name 'CSVFieldName' is defined
issue ;
some details:
Gatling Version : bundle-2.2.3
CSV Name : memId.csv
CSV contents :
memid
CKABC123
Scala File contents :
//Class Declaration
{
//some http configuration
val memId_feeder = csv("memId.csv").circular
val scn = scenario("Scn name").during( 10 seconds ) {
feed(memId_feeder)
exec(http("Req_01_Auth")
.post("/auth")
.check(status.is(200))
.headers(header_1)
.formParam("memberId","${memid}"))
}
setup(scn.inject(atOnceUsers(1)).protocols(httpConf))
}
Any help or clue to resolve this issue is really appreciable .
P.S. : There is no whitespaces in the input csv file .
Oh, I can feel your pain…
It's a while since I played with Gatling. As far I remember you have to provide a "chain" of actions in the scenario definition employing currying.
This all means: placing a dot before exec should make it.
val scn = scenario("Scn name").during( 10 seconds ) {
feed(memId_feeder)
.exec(http("Req_01_Auth")
.post("/auth")
.check(status.is(200))
.headers(header_1)
.formParam("memberId","${memid}"))
}
In my case applying dot implies error.
import com.shutterfly.loadtest.commerce.webcartorch.simulations.AbstractScenarioSimulation
import com.shutterfly.loadtest.siteServices.services.MyProjectsService
import com.shutterfly.loadtest.siteServices.util.{Configuration, HttpConfigs}
import io.gatling.core.Predef._
import com.shutterfly.loadtest.siteServices.services.MyProjectsService._
import io.gatling.http.config.HttpProtocolBuilder
class MetaDataApiSimulation extends Simulation {
def scenarioName = "MetaData Flow. Get All Projects"
def userCount = Configuration.getNumUsers(20)
def rampUpTime = Configuration.getRampUpTime(60)
def httpConf: HttpProtocolBuilder = HttpConfigs.newConfig(Configuration.siteServicesServer.hostname)
def getMetadata = exec(MyProjectsService.getAllProjectsForUser("${userId}"))
def dataFileName = "MetadataSimulationData.csv"
def Photobook_AddToCartDataFile="Photobook_AddToCartData.csv"
def Calendar_AddToCartDataFile="Calendar_AddToCartData.csv"
def dataFileName4="AddToCartData.csv"
def assertions = List(
details("First Assertion").responseTime.percentile3.lessThan(1000)
)
val scn = scenario(scenarioName).during(5) {
.exec().feed(csv(dataFileName).circular).exec(getMetadata)
}
setUp(scn.inject(rampUsers(userCount) over rampUpTime))
.protocols(httpConf)
.assertions(assertions)
}

Requests/urllib3 error: unorderable types: Retry() < int()

I understand the error, yet do no understand it in the context of my code. This is in Python 3.4. The relevant bits of code (simplified somewhat for clarity):
from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager
class SessionAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1,
cert_reqs = 'CERT_REQUIRED',
ca_certs = certifi.where(),
)
try:
app_session = requests.Session()
app_session.mount('https://', SessionAdapter())
app_response = app_session.post(
url = 'https://<FQD URL>'
, auth = (user, password)
, verify = True
)
# Code errors on the previous line and never executes the logger line
logger.debug('Status code: {}'.format(app_response.status_code))
if app_response.status_code == 401:
return 401
else:
return app_session
except:
logger.debug('Exception')
From sys.exc_info() I see:
", verify = True"): unorderable types: Retry() < int()
If the error were something like SessionAdapter() < int() it might make more sense. But I don't know where the Retry() check is being made.
Does the import of PoolManager need to be done differently for Python 3? I'm using version 1.7.1 of python-urllib3 on Ubuntu.

Resources