pub fn verify_authentication_header(
settings: &Settings,
request: &HttpRequest,
- body: String,
+ body: &web::Bytes,
+ parsed_body: String,
) -> Result<(), HttpResponse> {
// Check whether need both methods for authorization to work
let check_both = settings.basic_auth_and_secret;
if has_secret || check_both {
let signature = get_signature_header(&request.headers())?;
if !signature.is_empty() {
- verify_signature_header(signature, secret, &body)?;
+ verify_signature_header(signature, secret, body, parsed_body)?;
} else if check_both {
// The signature header is required and couldn't be found
return Err(HttpResponse::Unauthorized().body("No signature header found"));
/// Verify the signature header. Checks our own signature generated by hmac sha1 with secret and payload
/// against the signature provided in the header.
-fn verify_signature_header(signature: String, secret: String, body: &String) -> Result<(), HttpResponse> {
+fn verify_signature_header(signature: String, secret: String, body: &web::Bytes, parsed_body: String) -> Result<(), HttpResponse> {
// Try to decode the sha1 into bytes. Should be a valid hex string
let signature_bytes = match hex::decode(&signature) {
Ok(result) => result,
Err(_) => {
warn!(
"Got wrong sha1: {} \nwith payload: {}",
- signature, body
+ signature, parsed_body
);
Err(HttpResponse::Unauthorized().body("Invalid sha1 signature"))
}
}
/// Create a hmac SHA1 instance from a secret and body
-fn generate_signature_sha1(secret_bytes: &Vec<u8>, body: &String) -> HmacSha1 {
+fn generate_signature_sha1(secret_bytes: &Vec<u8>, body: &web::Bytes) -> HmacSha1 {
let mut hmac =
HmacSha1::new_varkey(secret_bytes).expect("Couldn't create hmac with current secret");
- hmac.input(&body.clone().into_bytes());
+ hmac.input(&body);
hmac
}
data: web::Data<AppState>,
path_info: web::Path<String>,
request: web::HttpRequest,
- body: String,
+ body: web::Bytes,
) -> Result<HttpResponse, HttpResponse> {
+
let payload = get_payload(&body)?;
+ let parsed_payload = match str::from_utf8(&body) {
+ Ok(parsed) => parsed,
+ Err(_) => {
+ return Err(HttpResponse::Unauthorized().body("Couldn't parse body"));
+ }
+ };
+
let webhook_name = path_info.into_inner();
info!("");
info!("Incoming webhook for \"{}\":", webhook_name);
- info!("Got payload: {}", body);
+ info!("Got payload: {}", parsed_payload);
// Check the credentials and signature headers of the request
- verify_authentication_header(&data.settings, &request, body)?;
+ verify_authentication_header(&data.settings, &request, &body, parsed_payload.to_string())?;
// Create a new task with the checked parameters and webhook name
let new_task = get_task_from_request(&data.settings, webhook_name, payload.parameters)?;
/// We do our own json handling, since Actix doesn't allow multiple extractors at once
-fn get_payload(string: &String) -> Result<Payload, HttpResponse> {
- match serde_json::from_str(&string) {
+fn get_payload(body: &web::Bytes) -> Result<Payload, HttpResponse> {
+ match serde_json::from_slice(body) {
Ok(payload) => Ok(payload),
Err(error) => {
let message = format!("Json error: {}", error);
webhooks:
-
name: 'ls'
- command: '/bin/ls {{param1}} {{param2}}'
+ command: '/bin/ls /tmp'
cwd: '/home/nuke'
mode: ''
parallel_processes: 2